From b7ccc9fda6b2915b71b6dc004c94534154ef2d25 Mon Sep 17 00:00:00 2001 From: wangfenjin Date: Tue, 8 Feb 2022 10:53:37 +0800 Subject: [PATCH] upgrade to 0.3.2 Change-Id: I39f0cb4db7982e0c1e0d7c5812c0f955a7929f46 --- .github/workflows/rust.yaml | 2 +- CONTRIBUTING.md | 12 + Cargo.toml | 6 +- libduckdb-sys/Cargo.toml | 4 +- .../duckdb/bindgen_bundled_version.rs | 11012 +- libduckdb-sys/duckdb/duckdb.cpp | 89055 +++++++++------- libduckdb-sys/duckdb/duckdb.h | 44 +- libduckdb-sys/duckdb/duckdb.hpp | 12005 ++- libduckdb-sys/src/lib.rs | 27 +- libduckdb-sys/src/raw_statement.rs | 1 + libduckdb-sys/upgrade.sh | 2 +- src/raw_statement.rs | 20 +- upgrade.sh | 17 + 13 files changed, 70446 insertions(+), 41761 deletions(-) create mode 100644 libduckdb-sys/src/raw_statement.rs create mode 100755 upgrade.sh diff --git a/.github/workflows/rust.yaml b/.github/workflows/rust.yaml index 6bdf2f72..c1304551 100644 --- a/.github/workflows/rust.yaml +++ b/.github/workflows/rust.yaml @@ -38,7 +38,7 @@ jobs: - run: cargo fmt --all -- --check - name: Download DuckDB run: | - wget https://github.com/duckdb/duckdb/releases/download/v0.3.1/libduckdb-linux-amd64.zip -O libduckdb.zip + wget https://github.com/duckdb/duckdb/releases/download/v0.3.2/libduckdb-linux-amd64.zip -O libduckdb.zip unzip libduckdb.zip -d libduckdb # - run: cargo clippy --all-targets --workspace --features bundled --features modern-full -- -D warnings -A clippy::redundant-closure - run: cargo clippy --all-targets --workspace --features buildtime_bindgen --features modern-full -- -D warnings -A clippy::redundant-closure diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ae45d688..bac02655 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -84,3 +84,15 @@ Detect memory leaks: cd ~/github/duckdb-rs ASAN_OPTIONS=detect_leaks=1 ASAN_SYMBOLIZER_PATH=/usr/local/opt/llvm/bin/llvm-symbolizer cargo test --features bundled -- --nocapture ``` + +### Update to new version + +Everytime duckdb release to a new version, we also need to release a new version. + +We can use the scripts to do the upgrades: +```shell +./upgrade.sh +``` +Which use sed to update the version number and then call `./libduckdb-sys/upgrade.sh` to generated new bindings. + +We may need to fix any error as duckdb's c-api may have breaking changes occasionally. diff --git a/Cargo.toml b/Cargo.toml index a1e7e0b6..8c5110e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "duckdb" -version = "0.3.1" +version = "0.3.2" authors = ["wangfenjin "] -edition = "2018" +edition = "2021" description = "Ergonomic wrapper for DuckDB" repository = "https://github.com/wangfenjin/duckdb-rs" homepage = "https://github.com/wangfenjin/duckdb-rs" @@ -68,7 +68,7 @@ tempdir = "0.3.7" [dependencies.libduckdb-sys] path = "libduckdb-sys" -version = "0.3.1" +version = "0.3.2" [package.metadata.docs.rs] features = [] diff --git a/libduckdb-sys/Cargo.toml b/libduckdb-sys/Cargo.toml index 2173423d..64e2bb7f 100644 --- a/libduckdb-sys/Cargo.toml +++ b/libduckdb-sys/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "libduckdb-sys" -version = "0.3.1" +version = "0.3.2" authors = ["wangfenjin "] -edition = "2018" +edition = "2021" build = "build.rs" license = "MIT" repository = "https://github.com/wangfenjin/duckdb-rs" diff --git a/libduckdb-sys/duckdb/bindgen_bundled_version.rs b/libduckdb-sys/duckdb/bindgen_bundled_version.rs index 9bff3628..12eecb6c 100644 --- a/libduckdb-sys/duckdb/bindgen_bundled_version.rs +++ b/libduckdb-sys/duckdb/bindgen_bundled_version.rs @@ -1,2053 +1,10374 @@ /* automatically generated by rust-bindgen 0.59.2 */ +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit { + storage: Storage, +} +impl __BindgenBitfieldUnit { + #[inline] + pub const fn new(storage: Storage) -> Self { + Self { storage } + } +} +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + byte & mask == mask + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + let mut val = 0; + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self.set_bit(index + bit_offset, val_bit_is_set); + } + } +} +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 true_: u32 = 1; pub const false_: u32 = 0; pub const __bool_true_false_are_defined: u32 = 1; -pub const _STDINT_H: u32 = 1; -pub const _FEATURES_H: u32 = 1; -pub const _DEFAULT_SOURCE: u32 = 1; -pub const __GLIBC_USE_ISOC2X: u32 = 0; -pub const __USE_ISOC11: u32 = 1; -pub const __USE_ISOC99: u32 = 1; -pub const __USE_ISOC95: u32 = 1; -pub const __USE_POSIX_IMPLICITLY: u32 = 1; -pub const _POSIX_SOURCE: u32 = 1; -pub const _POSIX_C_SOURCE: u32 = 200809; -pub const __USE_POSIX: u32 = 1; -pub const __USE_POSIX2: u32 = 1; -pub const __USE_POSIX199309: u32 = 1; -pub const __USE_POSIX199506: u32 = 1; -pub const __USE_XOPEN2K: u32 = 1; -pub const __USE_XOPEN2K8: u32 = 1; -pub const _ATFILE_SOURCE: u32 = 1; -pub const __USE_MISC: u32 = 1; -pub const __USE_ATFILE: u32 = 1; -pub const __USE_FORTIFY_LEVEL: u32 = 0; -pub const __GLIBC_USE_DEPRECATED_GETS: u32 = 0; -pub const __GLIBC_USE_DEPRECATED_SCANF: u32 = 0; -pub const _STDC_PREDEF_H: u32 = 1; -pub const __STDC_IEC_559__: u32 = 1; -pub const __STDC_IEC_559_COMPLEX__: u32 = 1; -pub const __STDC_ISO_10646__: u32 = 201706; -pub const __GNU_LIBRARY__: u32 = 6; -pub const __GLIBC__: u32 = 2; -pub const __GLIBC_MINOR__: u32 = 33; -pub const _SYS_CDEFS_H: u32 = 1; -pub const __glibc_c99_flexarr_available: u32 = 1; pub const __WORDSIZE: u32 = 64; -pub const __WORDSIZE_TIME64_COMPAT32: u32 = 1; -pub const __SYSCALL_WORDSIZE: u32 = 64; -pub const __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI: u32 = 0; -pub const __HAVE_GENERIC_SELECTION: u32 = 1; -pub const __GLIBC_USE_LIB_EXT2: u32 = 0; -pub const __GLIBC_USE_IEC_60559_BFP_EXT: u32 = 0; -pub const __GLIBC_USE_IEC_60559_BFP_EXT_C2X: u32 = 0; -pub const __GLIBC_USE_IEC_60559_FUNCS_EXT: u32 = 0; -pub const __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X: u32 = 0; -pub const __GLIBC_USE_IEC_60559_TYPES_EXT: u32 = 0; -pub const _BITS_TYPES_H: u32 = 1; -pub const __TIMESIZE: u32 = 64; -pub const _BITS_TYPESIZES_H: u32 = 1; -pub const __OFF_T_MATCHES_OFF64_T: u32 = 1; -pub const __INO_T_MATCHES_INO64_T: u32 = 1; -pub const __RLIM_T_MATCHES_RLIM64_T: u32 = 1; -pub const __STATFS_MATCHES_STATFS64: u32 = 1; -pub const __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64: u32 = 1; -pub const __FD_SETSIZE: u32 = 1024; -pub const _BITS_TIME64_H: u32 = 1; -pub const _BITS_WCHAR_H: u32 = 1; -pub const _BITS_STDINT_INTN_H: u32 = 1; -pub const _BITS_STDINT_UINTN_H: u32 = 1; -pub const INT8_MIN: i32 = -128; -pub const INT16_MIN: i32 = -32768; -pub const INT32_MIN: i32 = -2147483648; +pub const __DARWIN_ONLY_64_BIT_INO_T: u32 = 0; +pub const __DARWIN_ONLY_UNIX_CONFORMANCE: u32 = 1; +pub const __DARWIN_ONLY_VERS_1050: u32 = 0; +pub const __DARWIN_UNIX03: u32 = 1; +pub const __DARWIN_64_BIT_INO_T: u32 = 1; +pub const __DARWIN_VERS_1050: u32 = 1; +pub const __DARWIN_NON_CANCELABLE: u32 = 0; +pub const __DARWIN_SUF_64_BIT_INO_T: &[u8; 9usize] = b"$INODE64\0"; +pub const __DARWIN_SUF_1050: &[u8; 6usize] = b"$1050\0"; +pub const __DARWIN_SUF_EXTSN: &[u8; 14usize] = b"$DARWIN_EXTSN\0"; +pub const __DARWIN_C_ANSI: u32 = 4096; +pub const __DARWIN_C_FULL: u32 = 900000; +pub const __DARWIN_C_LEVEL: u32 = 900000; +pub const __STDC_WANT_LIB_EXT1__: u32 = 1; +pub const __DARWIN_NO_LONG_LONG: u32 = 0; +pub const _DARWIN_FEATURE_64_BIT_INODE: u32 = 1; +pub const _DARWIN_FEATURE_ONLY_UNIX_CONFORMANCE: u32 = 1; +pub const _DARWIN_FEATURE_UNIX_CONFORMANCE: u32 = 3; +pub const __PTHREAD_SIZE__: u32 = 8176; +pub const __PTHREAD_ATTR_SIZE__: u32 = 56; +pub const __PTHREAD_MUTEXATTR_SIZE__: u32 = 8; +pub const __PTHREAD_MUTEX_SIZE__: u32 = 56; +pub const __PTHREAD_CONDATTR_SIZE__: u32 = 8; +pub const __PTHREAD_COND_SIZE__: u32 = 40; +pub const __PTHREAD_ONCE_SIZE__: u32 = 8; +pub const __PTHREAD_RWLOCK_SIZE__: u32 = 192; +pub const __PTHREAD_RWLOCKATTR_SIZE__: u32 = 16; pub const INT8_MAX: u32 = 127; pub const INT16_MAX: u32 = 32767; pub const INT32_MAX: u32 = 2147483647; +pub const INT64_MAX: u64 = 9223372036854775807; +pub const INT8_MIN: i32 = -128; +pub const INT16_MIN: i32 = -32768; +pub const INT32_MIN: i32 = -2147483648; +pub const INT64_MIN: i64 = -9223372036854775808; pub const UINT8_MAX: u32 = 255; pub const UINT16_MAX: u32 = 65535; pub const UINT32_MAX: u32 = 4294967295; +pub const UINT64_MAX: i32 = -1; pub const INT_LEAST8_MIN: i32 = -128; pub const INT_LEAST16_MIN: i32 = -32768; pub const INT_LEAST32_MIN: i32 = -2147483648; +pub const INT_LEAST64_MIN: i64 = -9223372036854775808; pub const INT_LEAST8_MAX: u32 = 127; pub const INT_LEAST16_MAX: u32 = 32767; pub const INT_LEAST32_MAX: u32 = 2147483647; +pub const INT_LEAST64_MAX: u64 = 9223372036854775807; pub const UINT_LEAST8_MAX: u32 = 255; pub const UINT_LEAST16_MAX: u32 = 65535; pub const UINT_LEAST32_MAX: u32 = 4294967295; +pub const UINT_LEAST64_MAX: i32 = -1; pub const INT_FAST8_MIN: i32 = -128; -pub const INT_FAST16_MIN: i64 = -9223372036854775808; -pub const INT_FAST32_MIN: i64 = -9223372036854775808; +pub const INT_FAST16_MIN: i32 = -32768; +pub const INT_FAST32_MIN: i32 = -2147483648; +pub const INT_FAST64_MIN: i64 = -9223372036854775808; pub const INT_FAST8_MAX: u32 = 127; -pub const INT_FAST16_MAX: u64 = 9223372036854775807; -pub const INT_FAST32_MAX: u64 = 9223372036854775807; +pub const INT_FAST16_MAX: u32 = 32767; +pub const INT_FAST32_MAX: u32 = 2147483647; +pub const INT_FAST64_MAX: u64 = 9223372036854775807; pub const UINT_FAST8_MAX: u32 = 255; -pub const UINT_FAST16_MAX: i32 = -1; -pub const UINT_FAST32_MAX: i32 = -1; -pub const INTPTR_MIN: i64 = -9223372036854775808; +pub const UINT_FAST16_MAX: u32 = 65535; +pub const UINT_FAST32_MAX: u32 = 4294967295; +pub const UINT_FAST64_MAX: i32 = -1; pub const INTPTR_MAX: u64 = 9223372036854775807; +pub const INTPTR_MIN: i64 = -9223372036854775808; pub const UINTPTR_MAX: i32 = -1; -pub const PTRDIFF_MIN: i64 = -9223372036854775808; -pub const PTRDIFF_MAX: u64 = 9223372036854775807; +pub const SIZE_MAX: i32 = -1; +pub const RSIZE_MAX: i32 = -1; +pub const WINT_MIN: i32 = -2147483648; +pub const WINT_MAX: u32 = 2147483647; pub const SIG_ATOMIC_MIN: i32 = -2147483648; pub const SIG_ATOMIC_MAX: u32 = 2147483647; -pub const SIZE_MAX: i32 = -1; -pub const WINT_MIN: u32 = 0; -pub const WINT_MAX: u32 = 4294967295; -pub const _STDLIB_H: u32 = 1; +pub const __API_TO_BE_DEPRECATED: u32 = 100000; +pub const __MAC_10_0: u32 = 1000; +pub const __MAC_10_1: u32 = 1010; +pub const __MAC_10_2: u32 = 1020; +pub const __MAC_10_3: u32 = 1030; +pub const __MAC_10_4: u32 = 1040; +pub const __MAC_10_5: u32 = 1050; +pub const __MAC_10_6: u32 = 1060; +pub const __MAC_10_7: u32 = 1070; +pub const __MAC_10_8: u32 = 1080; +pub const __MAC_10_9: u32 = 1090; +pub const __MAC_10_10: u32 = 101000; +pub const __MAC_10_10_2: u32 = 101002; +pub const __MAC_10_10_3: u32 = 101003; +pub const __MAC_10_11: u32 = 101100; +pub const __MAC_10_11_2: u32 = 101102; +pub const __MAC_10_11_3: u32 = 101103; +pub const __MAC_10_11_4: u32 = 101104; +pub const __MAC_10_12: u32 = 101200; +pub const __MAC_10_12_1: u32 = 101201; +pub const __MAC_10_12_2: u32 = 101202; +pub const __MAC_10_12_4: u32 = 101204; +pub const __MAC_10_13: u32 = 101300; +pub const __MAC_10_13_1: u32 = 101301; +pub const __MAC_10_13_2: u32 = 101302; +pub const __MAC_10_13_4: u32 = 101304; +pub const __MAC_10_14: u32 = 101400; +pub const __MAC_10_14_1: u32 = 101401; +pub const __MAC_10_14_4: u32 = 101404; +pub const __MAC_10_14_6: u32 = 101406; +pub const __MAC_10_15: u32 = 101500; +pub const __MAC_10_15_1: u32 = 101501; +pub const __MAC_10_15_4: u32 = 101504; +pub const __MAC_10_16: u32 = 101600; +pub const __MAC_11_0: u32 = 110000; +pub const __MAC_11_1: u32 = 110100; +pub const __MAC_11_3: u32 = 110300; +pub const __MAC_11_4: u32 = 110400; +pub const __MAC_11_5: u32 = 110500; +pub const __MAC_11_6: u32 = 110600; +pub const __MAC_12_0: u32 = 120000; +pub const __MAC_12_1: u32 = 120100; +pub const __IPHONE_2_0: u32 = 20000; +pub const __IPHONE_2_1: u32 = 20100; +pub const __IPHONE_2_2: u32 = 20200; +pub const __IPHONE_3_0: u32 = 30000; +pub const __IPHONE_3_1: u32 = 30100; +pub const __IPHONE_3_2: u32 = 30200; +pub const __IPHONE_4_0: u32 = 40000; +pub const __IPHONE_4_1: u32 = 40100; +pub const __IPHONE_4_2: u32 = 40200; +pub const __IPHONE_4_3: u32 = 40300; +pub const __IPHONE_5_0: u32 = 50000; +pub const __IPHONE_5_1: u32 = 50100; +pub const __IPHONE_6_0: u32 = 60000; +pub const __IPHONE_6_1: u32 = 60100; +pub const __IPHONE_7_0: u32 = 70000; +pub const __IPHONE_7_1: u32 = 70100; +pub const __IPHONE_8_0: u32 = 80000; +pub const __IPHONE_8_1: u32 = 80100; +pub const __IPHONE_8_2: u32 = 80200; +pub const __IPHONE_8_3: u32 = 80300; +pub const __IPHONE_8_4: u32 = 80400; +pub const __IPHONE_9_0: u32 = 90000; +pub const __IPHONE_9_1: u32 = 90100; +pub const __IPHONE_9_2: u32 = 90200; +pub const __IPHONE_9_3: u32 = 90300; +pub const __IPHONE_10_0: u32 = 100000; +pub const __IPHONE_10_1: u32 = 100100; +pub const __IPHONE_10_2: u32 = 100200; +pub const __IPHONE_10_3: u32 = 100300; +pub const __IPHONE_11_0: u32 = 110000; +pub const __IPHONE_11_1: u32 = 110100; +pub const __IPHONE_11_2: u32 = 110200; +pub const __IPHONE_11_3: u32 = 110300; +pub const __IPHONE_11_4: u32 = 110400; +pub const __IPHONE_12_0: u32 = 120000; +pub const __IPHONE_12_1: u32 = 120100; +pub const __IPHONE_12_2: u32 = 120200; +pub const __IPHONE_12_3: u32 = 120300; +pub const __IPHONE_12_4: u32 = 120400; +pub const __IPHONE_13_0: u32 = 130000; +pub const __IPHONE_13_1: u32 = 130100; +pub const __IPHONE_13_2: u32 = 130200; +pub const __IPHONE_13_3: u32 = 130300; +pub const __IPHONE_13_4: u32 = 130400; +pub const __IPHONE_13_5: u32 = 130500; +pub const __IPHONE_13_6: u32 = 130600; +pub const __IPHONE_13_7: u32 = 130700; +pub const __IPHONE_14_0: u32 = 140000; +pub const __IPHONE_14_1: u32 = 140100; +pub const __IPHONE_14_2: u32 = 140200; +pub const __IPHONE_14_3: u32 = 140300; +pub const __IPHONE_14_5: u32 = 140500; +pub const __IPHONE_14_6: u32 = 140600; +pub const __IPHONE_14_7: u32 = 140700; +pub const __IPHONE_14_8: u32 = 140800; +pub const __IPHONE_15_0: u32 = 150000; +pub const __IPHONE_15_1: u32 = 150100; +pub const __IPHONE_15_2: u32 = 150200; +pub const __TVOS_9_0: u32 = 90000; +pub const __TVOS_9_1: u32 = 90100; +pub const __TVOS_9_2: u32 = 90200; +pub const __TVOS_10_0: u32 = 100000; +pub const __TVOS_10_0_1: u32 = 100001; +pub const __TVOS_10_1: u32 = 100100; +pub const __TVOS_10_2: u32 = 100200; +pub const __TVOS_11_0: u32 = 110000; +pub const __TVOS_11_1: u32 = 110100; +pub const __TVOS_11_2: u32 = 110200; +pub const __TVOS_11_3: u32 = 110300; +pub const __TVOS_11_4: u32 = 110400; +pub const __TVOS_12_0: u32 = 120000; +pub const __TVOS_12_1: u32 = 120100; +pub const __TVOS_12_2: u32 = 120200; +pub const __TVOS_12_3: u32 = 120300; +pub const __TVOS_12_4: u32 = 120400; +pub const __TVOS_13_0: u32 = 130000; +pub const __TVOS_13_2: u32 = 130200; +pub const __TVOS_13_3: u32 = 130300; +pub const __TVOS_13_4: u32 = 130400; +pub const __TVOS_14_0: u32 = 140000; +pub const __TVOS_14_1: u32 = 140100; +pub const __TVOS_14_2: u32 = 140200; +pub const __TVOS_14_3: u32 = 140300; +pub const __TVOS_14_5: u32 = 140500; +pub const __TVOS_14_6: u32 = 140600; +pub const __TVOS_14_7: u32 = 140700; +pub const __TVOS_15_0: u32 = 150000; +pub const __TVOS_15_1: u32 = 150100; +pub const __TVOS_15_2: u32 = 150200; +pub const __WATCHOS_1_0: u32 = 10000; +pub const __WATCHOS_2_0: u32 = 20000; +pub const __WATCHOS_2_1: u32 = 20100; +pub const __WATCHOS_2_2: u32 = 20200; +pub const __WATCHOS_3_0: u32 = 30000; +pub const __WATCHOS_3_1: u32 = 30100; +pub const __WATCHOS_3_1_1: u32 = 30101; +pub const __WATCHOS_3_2: u32 = 30200; +pub const __WATCHOS_4_0: u32 = 40000; +pub const __WATCHOS_4_1: u32 = 40100; +pub const __WATCHOS_4_2: u32 = 40200; +pub const __WATCHOS_4_3: u32 = 40300; +pub const __WATCHOS_5_0: u32 = 50000; +pub const __WATCHOS_5_1: u32 = 50100; +pub const __WATCHOS_5_2: u32 = 50200; +pub const __WATCHOS_5_3: u32 = 50300; +pub const __WATCHOS_6_0: u32 = 60000; +pub const __WATCHOS_6_1: u32 = 60100; +pub const __WATCHOS_6_2: u32 = 60200; +pub const __WATCHOS_7_0: u32 = 70000; +pub const __WATCHOS_7_1: u32 = 70100; +pub const __WATCHOS_7_2: u32 = 70200; +pub const __WATCHOS_7_3: u32 = 70300; +pub const __WATCHOS_7_4: u32 = 70400; +pub const __WATCHOS_7_5: u32 = 70500; +pub const __WATCHOS_7_6: u32 = 70600; +pub const __WATCHOS_8_0: u32 = 80000; +pub const __WATCHOS_8_1: u32 = 80100; +pub const __WATCHOS_8_3: u32 = 80300; +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; +pub const MAC_OS_X_VERSION_10_3: u32 = 1030; +pub const MAC_OS_X_VERSION_10_4: u32 = 1040; +pub const MAC_OS_X_VERSION_10_5: u32 = 1050; +pub const MAC_OS_X_VERSION_10_6: u32 = 1060; +pub const MAC_OS_X_VERSION_10_7: u32 = 1070; +pub const MAC_OS_X_VERSION_10_8: u32 = 1080; +pub const MAC_OS_X_VERSION_10_9: u32 = 1090; +pub const MAC_OS_X_VERSION_10_10: u32 = 101000; +pub const MAC_OS_X_VERSION_10_10_2: u32 = 101002; +pub const MAC_OS_X_VERSION_10_10_3: u32 = 101003; +pub const MAC_OS_X_VERSION_10_11: u32 = 101100; +pub const MAC_OS_X_VERSION_10_11_2: u32 = 101102; +pub const MAC_OS_X_VERSION_10_11_3: u32 = 101103; +pub const MAC_OS_X_VERSION_10_11_4: u32 = 101104; +pub const MAC_OS_X_VERSION_10_12: u32 = 101200; +pub const MAC_OS_X_VERSION_10_12_1: u32 = 101201; +pub const MAC_OS_X_VERSION_10_12_2: u32 = 101202; +pub const MAC_OS_X_VERSION_10_12_4: u32 = 101204; +pub const MAC_OS_X_VERSION_10_13: u32 = 101300; +pub const MAC_OS_X_VERSION_10_13_1: u32 = 101301; +pub const MAC_OS_X_VERSION_10_13_2: u32 = 101302; +pub const MAC_OS_X_VERSION_10_13_4: u32 = 101304; +pub const MAC_OS_X_VERSION_10_14: u32 = 101400; +pub const MAC_OS_X_VERSION_10_14_1: u32 = 101401; +pub const MAC_OS_X_VERSION_10_14_4: u32 = 101404; +pub const MAC_OS_X_VERSION_10_14_6: u32 = 101406; +pub const MAC_OS_X_VERSION_10_15: u32 = 101500; +pub const MAC_OS_X_VERSION_10_15_1: u32 = 101501; +pub const MAC_OS_X_VERSION_10_16: u32 = 101600; +pub const MAC_OS_VERSION_11_0: u32 = 110000; +pub const MAC_OS_VERSION_12_0: u32 = 120000; +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 = 120100; +pub const __ENABLE_LEGACY_MAC_AVAILABILITY: u32 = 1; +pub const __DARWIN_WCHAR_MIN: i32 = -2147483648; +pub const _FORTIFY_SOURCE: u32 = 2; +pub const __DARWIN_NSIG: u32 = 32; +pub const NSIG: u32 = 32; +pub const _I386_SIGNAL_H_: u32 = 1; +pub const SIGHUP: u32 = 1; +pub const SIGINT: u32 = 2; +pub const SIGQUIT: u32 = 3; +pub const SIGILL: u32 = 4; +pub const SIGTRAP: u32 = 5; +pub const SIGABRT: u32 = 6; +pub const SIGIOT: u32 = 6; +pub const SIGEMT: u32 = 7; +pub const SIGFPE: u32 = 8; +pub const SIGKILL: u32 = 9; +pub const SIGBUS: u32 = 10; +pub const SIGSEGV: u32 = 11; +pub const SIGSYS: u32 = 12; +pub const SIGPIPE: u32 = 13; +pub const SIGALRM: u32 = 14; +pub const SIGTERM: u32 = 15; +pub const SIGURG: u32 = 16; +pub const SIGSTOP: u32 = 17; +pub const SIGTSTP: u32 = 18; +pub const SIGCONT: u32 = 19; +pub const SIGCHLD: u32 = 20; +pub const SIGTTIN: u32 = 21; +pub const SIGTTOU: u32 = 22; +pub const SIGIO: u32 = 23; +pub const SIGXCPU: u32 = 24; +pub const SIGXFSZ: u32 = 25; +pub const SIGVTALRM: u32 = 26; +pub const SIGPROF: u32 = 27; +pub const SIGWINCH: u32 = 28; +pub const SIGINFO: u32 = 29; +pub const SIGUSR1: u32 = 30; +pub const SIGUSR2: u32 = 31; +pub const FP_PREC_24B: u32 = 0; +pub const FP_PREC_53B: u32 = 2; +pub const FP_PREC_64B: u32 = 3; +pub const FP_RND_NEAR: u32 = 0; +pub const FP_RND_DOWN: u32 = 1; +pub const FP_RND_UP: u32 = 2; +pub const FP_CHOP: u32 = 3; +pub const FP_STATE_BYTES: u32 = 512; +pub const _X86_INSTRUCTION_STATE_MAX_INSN_BYTES: u32 = 2380; +pub const _X86_INSTRUCTION_STATE_CACHELINE_SIZE: u32 = 64; +pub const __LASTBRANCH_MAX: u32 = 32; +pub const SIGEV_NONE: u32 = 0; +pub const SIGEV_SIGNAL: u32 = 1; +pub const SIGEV_THREAD: u32 = 3; +pub const ILL_NOOP: u32 = 0; +pub const ILL_ILLOPC: u32 = 1; +pub const ILL_ILLTRP: u32 = 2; +pub const ILL_PRVOPC: u32 = 3; +pub const ILL_ILLOPN: u32 = 4; +pub const ILL_ILLADR: u32 = 5; +pub const ILL_PRVREG: u32 = 6; +pub const ILL_COPROC: u32 = 7; +pub const ILL_BADSTK: u32 = 8; +pub const FPE_NOOP: u32 = 0; +pub const FPE_FLTDIV: u32 = 1; +pub const FPE_FLTOVF: u32 = 2; +pub const FPE_FLTUND: u32 = 3; +pub const FPE_FLTRES: u32 = 4; +pub const FPE_FLTINV: u32 = 5; +pub const FPE_FLTSUB: u32 = 6; +pub const FPE_INTDIV: u32 = 7; +pub const FPE_INTOVF: u32 = 8; +pub const SEGV_NOOP: u32 = 0; +pub const SEGV_MAPERR: u32 = 1; +pub const SEGV_ACCERR: u32 = 2; +pub const BUS_NOOP: u32 = 0; +pub const BUS_ADRALN: u32 = 1; +pub const BUS_ADRERR: u32 = 2; +pub const BUS_OBJERR: u32 = 3; +pub const TRAP_BRKPT: u32 = 1; +pub const TRAP_TRACE: u32 = 2; +pub const CLD_NOOP: u32 = 0; +pub const CLD_EXITED: u32 = 1; +pub const CLD_KILLED: u32 = 2; +pub const CLD_DUMPED: u32 = 3; +pub const CLD_TRAPPED: u32 = 4; +pub const CLD_STOPPED: u32 = 5; +pub const CLD_CONTINUED: u32 = 6; +pub const POLL_IN: u32 = 1; +pub const POLL_OUT: u32 = 2; +pub const POLL_MSG: u32 = 3; +pub const POLL_ERR: u32 = 4; +pub const POLL_PRI: u32 = 5; +pub const POLL_HUP: u32 = 6; +pub const SA_ONSTACK: u32 = 1; +pub const SA_RESTART: u32 = 2; +pub const SA_RESETHAND: u32 = 4; +pub const SA_NOCLDSTOP: u32 = 8; +pub const SA_NODEFER: u32 = 16; +pub const SA_NOCLDWAIT: u32 = 32; +pub const SA_SIGINFO: u32 = 64; +pub const SA_USERTRAMP: u32 = 256; +pub const SA_64REGSET: u32 = 512; +pub const SA_USERSPACE_MASK: u32 = 127; +pub const SIG_BLOCK: u32 = 1; +pub const SIG_UNBLOCK: u32 = 2; +pub const SIG_SETMASK: u32 = 3; +pub const SI_USER: u32 = 65537; +pub const SI_QUEUE: u32 = 65538; +pub const SI_TIMER: u32 = 65539; +pub const SI_ASYNCIO: u32 = 65540; +pub const SI_MESGQ: u32 = 65541; +pub const SS_ONSTACK: u32 = 1; +pub const SS_DISABLE: u32 = 4; +pub const MINSIGSTKSZ: u32 = 32768; +pub const SIGSTKSZ: u32 = 131072; +pub const SV_ONSTACK: u32 = 1; +pub const SV_INTERRUPT: u32 = 2; +pub const SV_RESETHAND: u32 = 4; +pub const SV_NODEFER: u32 = 16; +pub const SV_NOCLDSTOP: u32 = 8; +pub const SV_SIGINFO: u32 = 64; +pub const PRIO_PROCESS: u32 = 0; +pub const PRIO_PGRP: u32 = 1; +pub const PRIO_USER: u32 = 2; +pub const PRIO_DARWIN_THREAD: u32 = 3; +pub const PRIO_DARWIN_PROCESS: u32 = 4; +pub const PRIO_MIN: i32 = -20; +pub const PRIO_MAX: u32 = 20; +pub const PRIO_DARWIN_BG: u32 = 4096; +pub const PRIO_DARWIN_NONUI: u32 = 4097; +pub const RUSAGE_SELF: u32 = 0; +pub const RUSAGE_CHILDREN: i32 = -1; +pub const RUSAGE_INFO_V0: u32 = 0; +pub const RUSAGE_INFO_V1: u32 = 1; +pub const RUSAGE_INFO_V2: u32 = 2; +pub const RUSAGE_INFO_V3: u32 = 3; +pub const RUSAGE_INFO_V4: u32 = 4; +pub const RUSAGE_INFO_V5: u32 = 5; +pub const RUSAGE_INFO_CURRENT: u32 = 5; +pub const RU_PROC_RUNS_RESLIDE: u32 = 1; +pub const RLIMIT_CPU: u32 = 0; +pub const RLIMIT_FSIZE: u32 = 1; +pub const RLIMIT_DATA: u32 = 2; +pub const RLIMIT_STACK: u32 = 3; +pub const RLIMIT_CORE: u32 = 4; +pub const RLIMIT_AS: u32 = 5; +pub const RLIMIT_RSS: u32 = 5; +pub const RLIMIT_MEMLOCK: u32 = 6; +pub const RLIMIT_NPROC: u32 = 7; +pub const RLIMIT_NOFILE: u32 = 8; +pub const RLIM_NLIMITS: u32 = 9; +pub const _RLIMIT_POSIX_FLAG: u32 = 4096; +pub const RLIMIT_WAKEUPS_MONITOR: u32 = 1; +pub const RLIMIT_CPU_USAGE_MONITOR: u32 = 2; +pub const RLIMIT_THREAD_CPULIMITS: u32 = 3; +pub const RLIMIT_FOOTPRINT_INTERVAL: u32 = 4; +pub const WAKEMON_ENABLE: u32 = 1; +pub const WAKEMON_DISABLE: u32 = 2; +pub const WAKEMON_GET_PARAMS: u32 = 4; +pub const WAKEMON_SET_DEFAULTS: u32 = 8; +pub const WAKEMON_MAKE_FATAL: u32 = 16; +pub const CPUMON_MAKE_FATAL: u32 = 4096; +pub const FOOTPRINT_INTERVAL_RESET: u32 = 1; +pub const IOPOL_TYPE_DISK: u32 = 0; +pub const IOPOL_TYPE_VFS_ATIME_UPDATES: u32 = 2; +pub const IOPOL_TYPE_VFS_MATERIALIZE_DATALESS_FILES: u32 = 3; +pub const IOPOL_TYPE_VFS_STATFS_NO_DATA_VOLUME: u32 = 4; +pub const IOPOL_TYPE_VFS_TRIGGER_RESOLVE: u32 = 5; +pub const IOPOL_TYPE_VFS_IGNORE_CONTENT_PROTECTION: u32 = 6; +pub const IOPOL_TYPE_VFS_IGNORE_PERMISSIONS: u32 = 7; +pub const IOPOL_TYPE_VFS_SKIP_MTIME_UPDATE: u32 = 8; +pub const IOPOL_TYPE_VFS_ALLOW_LOW_SPACE_WRITES: u32 = 9; +pub const IOPOL_SCOPE_PROCESS: u32 = 0; +pub const IOPOL_SCOPE_THREAD: u32 = 1; +pub const IOPOL_SCOPE_DARWIN_BG: u32 = 2; +pub const IOPOL_DEFAULT: u32 = 0; +pub const IOPOL_IMPORTANT: u32 = 1; +pub const IOPOL_PASSIVE: u32 = 2; +pub const IOPOL_THROTTLE: u32 = 3; +pub const IOPOL_UTILITY: u32 = 4; +pub const IOPOL_STANDARD: u32 = 5; +pub const IOPOL_APPLICATION: u32 = 5; +pub const IOPOL_NORMAL: u32 = 1; +pub const IOPOL_ATIME_UPDATES_DEFAULT: u32 = 0; +pub const IOPOL_ATIME_UPDATES_OFF: u32 = 1; +pub const IOPOL_MATERIALIZE_DATALESS_FILES_DEFAULT: u32 = 0; +pub const IOPOL_MATERIALIZE_DATALESS_FILES_OFF: u32 = 1; +pub const IOPOL_MATERIALIZE_DATALESS_FILES_ON: u32 = 2; +pub const IOPOL_VFS_STATFS_NO_DATA_VOLUME_DEFAULT: u32 = 0; +pub const IOPOL_VFS_STATFS_FORCE_NO_DATA_VOLUME: u32 = 1; +pub const IOPOL_VFS_TRIGGER_RESOLVE_DEFAULT: u32 = 0; +pub const IOPOL_VFS_TRIGGER_RESOLVE_OFF: u32 = 1; +pub const IOPOL_VFS_CONTENT_PROTECTION_DEFAULT: u32 = 0; +pub const IOPOL_VFS_CONTENT_PROTECTION_IGNORE: u32 = 1; +pub const IOPOL_VFS_IGNORE_PERMISSIONS_OFF: u32 = 0; +pub const IOPOL_VFS_IGNORE_PERMISSIONS_ON: u32 = 1; +pub const IOPOL_VFS_SKIP_MTIME_UPDATE_OFF: u32 = 0; +pub const IOPOL_VFS_SKIP_MTIME_UPDATE_ON: u32 = 1; +pub const IOPOL_VFS_ALLOW_LOW_SPACE_WRITES_OFF: u32 = 0; +pub const IOPOL_VFS_ALLOW_LOW_SPACE_WRITES_ON: u32 = 1; pub const WNOHANG: u32 = 1; pub const WUNTRACED: u32 = 2; -pub const WSTOPPED: u32 = 2; +pub const WCOREFLAG: u32 = 128; +pub const _WSTOPPED: u32 = 127; pub const WEXITED: u32 = 4; -pub const WCONTINUED: u32 = 8; -pub const WNOWAIT: u32 = 16777216; -pub const __WNOTHREAD: u32 = 536870912; -pub const __WALL: u32 = 1073741824; -pub const __WCLONE: u32 = 2147483648; -pub const __W_CONTINUED: u32 = 65535; -pub const __WCOREFLAG: u32 = 128; -pub const __HAVE_FLOAT128: u32 = 0; -pub const __HAVE_DISTINCT_FLOAT128: u32 = 0; -pub const __HAVE_FLOAT64X: u32 = 1; -pub const __HAVE_FLOAT64X_LONG_DOUBLE: u32 = 1; -pub const __HAVE_FLOAT16: u32 = 0; -pub const __HAVE_FLOAT32: u32 = 1; -pub const __HAVE_FLOAT64: u32 = 1; -pub const __HAVE_FLOAT32X: u32 = 1; -pub const __HAVE_FLOAT128X: u32 = 0; -pub const __HAVE_DISTINCT_FLOAT16: u32 = 0; -pub const __HAVE_DISTINCT_FLOAT32: u32 = 0; -pub const __HAVE_DISTINCT_FLOAT64: u32 = 0; -pub const __HAVE_DISTINCT_FLOAT32X: u32 = 0; -pub const __HAVE_DISTINCT_FLOAT64X: u32 = 0; -pub const __HAVE_DISTINCT_FLOAT128X: u32 = 0; -pub const __HAVE_FLOATN_NOT_TYPEDEF: u32 = 0; -pub const __ldiv_t_defined: u32 = 1; -pub const __lldiv_t_defined: u32 = 1; -pub const RAND_MAX: u32 = 2147483647; -pub const EXIT_FAILURE: u32 = 1; -pub const EXIT_SUCCESS: u32 = 0; -pub const _SYS_TYPES_H: u32 = 1; -pub const __clock_t_defined: u32 = 1; -pub const __clockid_t_defined: u32 = 1; -pub const __time_t_defined: u32 = 1; -pub const __timer_t_defined: u32 = 1; -pub const __BIT_TYPES_DEFINED__: u32 = 1; -pub const _ENDIAN_H: u32 = 1; -pub const _BITS_ENDIAN_H: u32 = 1; -pub const __LITTLE_ENDIAN: u32 = 1234; -pub const __BIG_ENDIAN: u32 = 4321; -pub const __PDP_ENDIAN: u32 = 3412; -pub const _BITS_ENDIANNESS_H: u32 = 1; -pub const __BYTE_ORDER: u32 = 1234; -pub const __FLOAT_WORD_ORDER: u32 = 1234; +pub const WSTOPPED: u32 = 8; +pub const WCONTINUED: u32 = 16; +pub const WNOWAIT: u32 = 32; +pub const WAIT_ANY: i32 = -1; +pub const WAIT_MYPGRP: u32 = 0; +pub const _QUAD_HIGHWORD: u32 = 1; +pub const _QUAD_LOWWORD: u32 = 0; +pub const __DARWIN_LITTLE_ENDIAN: u32 = 1234; +pub const __DARWIN_BIG_ENDIAN: u32 = 4321; +pub const __DARWIN_PDP_ENDIAN: u32 = 3412; +pub const __DARWIN_BYTE_ORDER: u32 = 1234; pub const LITTLE_ENDIAN: u32 = 1234; pub const BIG_ENDIAN: u32 = 4321; pub const PDP_ENDIAN: u32 = 3412; pub const BYTE_ORDER: u32 = 1234; -pub const _BITS_BYTESWAP_H: u32 = 1; -pub const _BITS_UINTN_IDENTITY_H: u32 = 1; -pub const _SYS_SELECT_H: u32 = 1; -pub const __sigset_t_defined: u32 = 1; -pub const __timeval_defined: u32 = 1; -pub const _STRUCT_TIMESPEC: u32 = 1; -pub const FD_SETSIZE: u32 = 1024; -pub const _BITS_PTHREADTYPES_COMMON_H: u32 = 1; -pub const _THREAD_SHARED_TYPES_H: u32 = 1; -pub const _BITS_PTHREADTYPES_ARCH_H: u32 = 1; -pub const __SIZEOF_PTHREAD_MUTEX_T: u32 = 40; -pub const __SIZEOF_PTHREAD_ATTR_T: u32 = 56; -pub const __SIZEOF_PTHREAD_RWLOCK_T: u32 = 56; -pub const __SIZEOF_PTHREAD_BARRIER_T: u32 = 32; -pub const __SIZEOF_PTHREAD_MUTEXATTR_T: u32 = 4; -pub const __SIZEOF_PTHREAD_COND_T: u32 = 48; -pub const __SIZEOF_PTHREAD_CONDATTR_T: u32 = 4; -pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: u32 = 8; -pub const __SIZEOF_PTHREAD_BARRIERATTR_T: u32 = 4; -pub const _THREAD_MUTEX_INTERNAL_H: u32 = 1; -pub const __PTHREAD_MUTEX_HAVE_PREV: u32 = 1; -pub const __have_pthread_attr_t: u32 = 1; -pub const _ALLOCA_H: u32 = 1; -pub type __u_char = ::std::os::raw::c_uchar; -pub type __u_short = ::std::os::raw::c_ushort; -pub type __u_int = ::std::os::raw::c_uint; -pub type __u_long = ::std::os::raw::c_ulong; +pub const EXIT_FAILURE: u32 = 1; +pub const EXIT_SUCCESS: u32 = 0; +pub const RAND_MAX: u32 = 2147483647; +pub type int_least8_t = i8; +pub type int_least16_t = i16; +pub type int_least32_t = i32; +pub type int_least64_t = i64; +pub type uint_least8_t = u8; +pub type uint_least16_t = u16; +pub type uint_least32_t = u32; +pub type uint_least64_t = u64; +pub type int_fast8_t = i8; +pub type int_fast16_t = i16; +pub type int_fast32_t = i32; +pub type int_fast64_t = i64; +pub type uint_fast8_t = u8; +pub type uint_fast16_t = u16; +pub type uint_fast32_t = u32; +pub type uint_fast64_t = u64; pub type __int8_t = ::std::os::raw::c_schar; pub type __uint8_t = ::std::os::raw::c_uchar; pub type __int16_t = ::std::os::raw::c_short; pub type __uint16_t = ::std::os::raw::c_ushort; pub type __int32_t = ::std::os::raw::c_int; pub type __uint32_t = ::std::os::raw::c_uint; -pub type __int64_t = ::std::os::raw::c_long; -pub type __uint64_t = ::std::os::raw::c_ulong; -pub type __int_least8_t = __int8_t; -pub type __uint_least8_t = __uint8_t; -pub type __int_least16_t = __int16_t; -pub type __uint_least16_t = __uint16_t; -pub type __int_least32_t = __int32_t; -pub type __uint_least32_t = __uint32_t; -pub type __int_least64_t = __int64_t; -pub type __uint_least64_t = __uint64_t; -pub type __quad_t = ::std::os::raw::c_long; -pub type __u_quad_t = ::std::os::raw::c_ulong; -pub type __intmax_t = ::std::os::raw::c_long; -pub type __uintmax_t = ::std::os::raw::c_ulong; -pub type __dev_t = ::std::os::raw::c_ulong; -pub type __uid_t = ::std::os::raw::c_uint; -pub type __gid_t = ::std::os::raw::c_uint; -pub type __ino_t = ::std::os::raw::c_ulong; -pub type __ino64_t = ::std::os::raw::c_ulong; -pub type __mode_t = ::std::os::raw::c_uint; -pub type __nlink_t = ::std::os::raw::c_ulong; -pub type __off_t = ::std::os::raw::c_long; -pub type __off64_t = ::std::os::raw::c_long; -pub type __pid_t = ::std::os::raw::c_int; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct __fsid_t { - pub __val: [::std::os::raw::c_int; 2usize], -} -#[test] -fn bindgen_test_layout___fsid_t() { - assert_eq!( - ::std::mem::size_of::<__fsid_t>(), - 8usize, - concat!("Size of: ", stringify!(__fsid_t)) - ); - assert_eq!( - ::std::mem::align_of::<__fsid_t>(), - 4usize, - concat!("Alignment of ", stringify!(__fsid_t)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<__fsid_t>())).__val as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(__fsid_t), "::", stringify!(__val)) - ); -} -pub type __clock_t = ::std::os::raw::c_long; -pub type __rlim_t = ::std::os::raw::c_ulong; -pub type __rlim64_t = ::std::os::raw::c_ulong; -pub type __id_t = ::std::os::raw::c_uint; -pub type __time_t = ::std::os::raw::c_long; -pub type __useconds_t = ::std::os::raw::c_uint; -pub type __suseconds_t = ::std::os::raw::c_long; -pub type __suseconds64_t = ::std::os::raw::c_long; -pub type __daddr_t = ::std::os::raw::c_int; -pub type __key_t = ::std::os::raw::c_int; -pub type __clockid_t = ::std::os::raw::c_int; -pub type __timer_t = *mut ::std::os::raw::c_void; -pub type __blksize_t = ::std::os::raw::c_long; -pub type __blkcnt_t = ::std::os::raw::c_long; -pub type __blkcnt64_t = ::std::os::raw::c_long; -pub type __fsblkcnt_t = ::std::os::raw::c_ulong; -pub type __fsblkcnt64_t = ::std::os::raw::c_ulong; -pub type __fsfilcnt_t = ::std::os::raw::c_ulong; -pub type __fsfilcnt64_t = ::std::os::raw::c_ulong; -pub type __fsword_t = ::std::os::raw::c_long; -pub type __ssize_t = ::std::os::raw::c_long; -pub type __syscall_slong_t = ::std::os::raw::c_long; -pub type __syscall_ulong_t = ::std::os::raw::c_ulong; -pub type __loff_t = __off64_t; -pub type __caddr_t = *mut ::std::os::raw::c_char; -pub type __intptr_t = ::std::os::raw::c_long; -pub type __socklen_t = ::std::os::raw::c_uint; -pub type __sig_atomic_t = ::std::os::raw::c_int; -pub type int_least8_t = __int_least8_t; -pub type int_least16_t = __int_least16_t; -pub type int_least32_t = __int_least32_t; -pub type int_least64_t = __int_least64_t; -pub type uint_least8_t = __uint_least8_t; -pub type uint_least16_t = __uint_least16_t; -pub type uint_least32_t = __uint_least32_t; -pub type uint_least64_t = __uint_least64_t; -pub type int_fast8_t = ::std::os::raw::c_schar; -pub type int_fast16_t = ::std::os::raw::c_long; -pub type int_fast32_t = ::std::os::raw::c_long; -pub type int_fast64_t = ::std::os::raw::c_long; -pub type uint_fast8_t = ::std::os::raw::c_uchar; -pub type uint_fast16_t = ::std::os::raw::c_ulong; -pub type uint_fast32_t = ::std::os::raw::c_ulong; -pub type uint_fast64_t = ::std::os::raw::c_ulong; -pub type intmax_t = __intmax_t; -pub type uintmax_t = __uintmax_t; -pub type size_t = ::std::os::raw::c_ulong; -pub type wchar_t = ::std::os::raw::c_int; -pub type _Float32 = f32; -pub type _Float64 = f64; -pub type _Float32x = f64; -pub type _Float64x = u128; +pub type __int64_t = ::std::os::raw::c_longlong; +pub type __uint64_t = ::std::os::raw::c_ulonglong; +pub type __darwin_intptr_t = ::std::os::raw::c_long; +pub type __darwin_natural_t = ::std::os::raw::c_uint; +pub type __darwin_ct_rune_t = ::std::os::raw::c_int; #[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct div_t { - pub quot: ::std::os::raw::c_int, - pub rem: ::std::os::raw::c_int, +#[derive(Copy, Clone)] +pub union __mbstate_t { + pub __mbstate8: [::std::os::raw::c_char; 128usize], + pub _mbstateL: ::std::os::raw::c_longlong, } #[test] -fn bindgen_test_layout_div_t() { +fn bindgen_test_layout___mbstate_t() { assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(div_t)) + ::std::mem::size_of::<__mbstate_t>(), + 128usize, + concat!("Size of: ", stringify!(__mbstate_t)) ); assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(div_t)) + ::std::mem::align_of::<__mbstate_t>(), + 8usize, + concat!("Alignment of ", stringify!(__mbstate_t)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).quot as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<__mbstate_t>())).__mbstate8 as *const _ as usize }, 0usize, - concat!("Offset of field: ", stringify!(div_t), "::", stringify!(quot)) + concat!( + "Offset of field: ", + stringify!(__mbstate_t), + "::", + stringify!(__mbstate8) + ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).rem as *const _ as usize }, - 4usize, - concat!("Offset of field: ", stringify!(div_t), "::", stringify!(rem)) + unsafe { &(*(::std::ptr::null::<__mbstate_t>()))._mbstateL as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__mbstate_t), + "::", + stringify!(_mbstateL) + ) ); } +pub type __darwin_mbstate_t = __mbstate_t; +pub type __darwin_ptrdiff_t = ::std::os::raw::c_long; +pub type __darwin_size_t = ::std::os::raw::c_ulong; +pub type __darwin_va_list = __builtin_va_list; +pub type __darwin_wchar_t = ::std::os::raw::c_int; +pub type __darwin_rune_t = __darwin_wchar_t; +pub type __darwin_wint_t = ::std::os::raw::c_int; +pub type __darwin_clock_t = ::std::os::raw::c_ulong; +pub type __darwin_socklen_t = __uint32_t; +pub type __darwin_ssize_t = ::std::os::raw::c_long; +pub type __darwin_time_t = ::std::os::raw::c_long; +pub type __darwin_blkcnt_t = __int64_t; +pub type __darwin_blksize_t = __int32_t; +pub type __darwin_dev_t = __int32_t; +pub type __darwin_fsblkcnt_t = ::std::os::raw::c_uint; +pub type __darwin_fsfilcnt_t = ::std::os::raw::c_uint; +pub type __darwin_gid_t = __uint32_t; +pub type __darwin_id_t = __uint32_t; +pub type __darwin_ino64_t = __uint64_t; +pub type __darwin_ino_t = __darwin_ino64_t; +pub type __darwin_mach_port_name_t = __darwin_natural_t; +pub type __darwin_mach_port_t = __darwin_mach_port_name_t; +pub type __darwin_mode_t = __uint16_t; +pub type __darwin_off_t = __int64_t; +pub type __darwin_pid_t = __int32_t; +pub type __darwin_sigset_t = __uint32_t; +pub type __darwin_suseconds_t = __int32_t; +pub type __darwin_uid_t = __uint32_t; +pub type __darwin_useconds_t = __uint32_t; +pub type __darwin_uuid_t = [::std::os::raw::c_uchar; 16usize]; +pub type __darwin_uuid_string_t = [::std::os::raw::c_char; 37usize]; #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct ldiv_t { - pub quot: ::std::os::raw::c_long, - pub rem: ::std::os::raw::c_long, +pub struct __darwin_pthread_handler_rec { + pub __routine: ::std::option::Option, + pub __arg: *mut ::std::os::raw::c_void, + pub __next: *mut __darwin_pthread_handler_rec, } #[test] -fn bindgen_test_layout_ldiv_t() { +fn bindgen_test_layout___darwin_pthread_handler_rec() { assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(ldiv_t)) + ::std::mem::size_of::<__darwin_pthread_handler_rec>(), + 24usize, + concat!("Size of: ", stringify!(__darwin_pthread_handler_rec)) ); assert_eq!( - ::std::mem::align_of::(), + ::std::mem::align_of::<__darwin_pthread_handler_rec>(), 8usize, - concat!("Alignment of ", stringify!(ldiv_t)) + concat!("Alignment of ", stringify!(__darwin_pthread_handler_rec)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).quot as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<__darwin_pthread_handler_rec>())).__routine as *const _ as usize }, 0usize, - concat!("Offset of field: ", stringify!(ldiv_t), "::", stringify!(quot)) + concat!( + "Offset of field: ", + stringify!(__darwin_pthread_handler_rec), + "::", + stringify!(__routine) + ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).rem as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<__darwin_pthread_handler_rec>())).__arg as *const _ as usize }, 8usize, - concat!("Offset of field: ", stringify!(ldiv_t), "::", stringify!(rem)) + concat!( + "Offset of field: ", + stringify!(__darwin_pthread_handler_rec), + "::", + stringify!(__arg) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_pthread_handler_rec>())).__next as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(__darwin_pthread_handler_rec), + "::", + stringify!(__next) + ) ); } #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct lldiv_t { - pub quot: ::std::os::raw::c_longlong, - pub rem: ::std::os::raw::c_longlong, +pub struct _opaque_pthread_attr_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 56usize], } #[test] -fn bindgen_test_layout_lldiv_t() { +fn bindgen_test_layout__opaque_pthread_attr_t() { assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(lldiv_t)) + ::std::mem::size_of::<_opaque_pthread_attr_t>(), + 64usize, + concat!("Size of: ", stringify!(_opaque_pthread_attr_t)) ); assert_eq!( - ::std::mem::align_of::(), + ::std::mem::align_of::<_opaque_pthread_attr_t>(), 8usize, - concat!("Alignment of ", stringify!(lldiv_t)) + concat!("Alignment of ", stringify!(_opaque_pthread_attr_t)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).quot as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<_opaque_pthread_attr_t>())).__sig as *const _ as usize }, 0usize, - concat!("Offset of field: ", stringify!(lldiv_t), "::", stringify!(quot)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).rem as *const _ as usize }, - 8usize, - concat!("Offset of field: ", stringify!(lldiv_t), "::", stringify!(rem)) - ); -} -extern "C" { - pub fn __ctype_get_mb_cur_max() -> size_t; -} -extern "C" { - pub fn atof(__nptr: *const ::std::os::raw::c_char) -> f64; -} -extern "C" { - pub fn atoi(__nptr: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; -} -extern "C" { - pub fn atol(__nptr: *const ::std::os::raw::c_char) -> ::std::os::raw::c_long; -} -extern "C" { - pub fn atoll(__nptr: *const ::std::os::raw::c_char) -> ::std::os::raw::c_longlong; -} -extern "C" { - pub fn strtod(__nptr: *const ::std::os::raw::c_char, __endptr: *mut *mut ::std::os::raw::c_char) -> f64; -} -extern "C" { - pub fn strtof(__nptr: *const ::std::os::raw::c_char, __endptr: *mut *mut ::std::os::raw::c_char) -> f32; -} -extern "C" { - pub fn strtold(__nptr: *const ::std::os::raw::c_char, __endptr: *mut *mut ::std::os::raw::c_char) -> u128; -} -extern "C" { - pub fn strtol( - __nptr: *const ::std::os::raw::c_char, - __endptr: *mut *mut ::std::os::raw::c_char, - __base: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_long; -} -extern "C" { - pub fn strtoul( - __nptr: *const ::std::os::raw::c_char, - __endptr: *mut *mut ::std::os::raw::c_char, - __base: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_ulong; -} -extern "C" { - pub fn strtoq( - __nptr: *const ::std::os::raw::c_char, - __endptr: *mut *mut ::std::os::raw::c_char, - __base: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_longlong; -} -extern "C" { - pub fn strtouq( - __nptr: *const ::std::os::raw::c_char, - __endptr: *mut *mut ::std::os::raw::c_char, - __base: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_ulonglong; -} -extern "C" { - pub fn strtoll( - __nptr: *const ::std::os::raw::c_char, - __endptr: *mut *mut ::std::os::raw::c_char, - __base: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_longlong; -} -extern "C" { - pub fn strtoull( - __nptr: *const ::std::os::raw::c_char, - __endptr: *mut *mut ::std::os::raw::c_char, - __base: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_ulonglong; -} -extern "C" { - pub fn l64a(__n: ::std::os::raw::c_long) -> *mut ::std::os::raw::c_char; -} -extern "C" { - pub fn a64l(__s: *const ::std::os::raw::c_char) -> ::std::os::raw::c_long; -} -pub type u_char = __u_char; -pub type u_short = __u_short; -pub type u_int = __u_int; -pub type u_long = __u_long; -pub type quad_t = __quad_t; -pub type u_quad_t = __u_quad_t; -pub type fsid_t = __fsid_t; -pub type loff_t = __loff_t; -pub type ino_t = __ino_t; -pub type dev_t = __dev_t; -pub type gid_t = __gid_t; -pub type mode_t = __mode_t; -pub type nlink_t = __nlink_t; -pub type uid_t = __uid_t; -pub type off_t = __off_t; -pub type pid_t = __pid_t; -pub type id_t = __id_t; -pub type ssize_t = __ssize_t; -pub type daddr_t = __daddr_t; -pub type caddr_t = __caddr_t; -pub type key_t = __key_t; -pub type clock_t = __clock_t; -pub type clockid_t = __clockid_t; -pub type time_t = __time_t; -pub type timer_t = __timer_t; -pub type ulong = ::std::os::raw::c_ulong; -pub type ushort = ::std::os::raw::c_ushort; -pub type uint = ::std::os::raw::c_uint; -pub type u_int8_t = __uint8_t; -pub type u_int16_t = __uint16_t; -pub type u_int32_t = __uint32_t; -pub type u_int64_t = __uint64_t; -pub type register_t = ::std::os::raw::c_long; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct __sigset_t { - pub __val: [::std::os::raw::c_ulong; 16usize], -} -#[test] -fn bindgen_test_layout___sigset_t() { - assert_eq!( - ::std::mem::size_of::<__sigset_t>(), - 128usize, - concat!("Size of: ", stringify!(__sigset_t)) + concat!( + "Offset of field: ", + stringify!(_opaque_pthread_attr_t), + "::", + stringify!(__sig) + ) ); assert_eq!( - ::std::mem::align_of::<__sigset_t>(), + unsafe { &(*(::std::ptr::null::<_opaque_pthread_attr_t>())).__opaque as *const _ as usize }, 8usize, - concat!("Alignment of ", stringify!(__sigset_t)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<__sigset_t>())).__val as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(__sigset_t), "::", stringify!(__val)) + concat!( + "Offset of field: ", + stringify!(_opaque_pthread_attr_t), + "::", + stringify!(__opaque) + ) ); } -pub type sigset_t = __sigset_t; #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct timeval { - pub tv_sec: __time_t, - pub tv_usec: __suseconds_t, +pub struct _opaque_pthread_cond_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 40usize], } #[test] -fn bindgen_test_layout_timeval() { +fn bindgen_test_layout__opaque_pthread_cond_t() { assert_eq!( - ::std::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(timeval)) + ::std::mem::size_of::<_opaque_pthread_cond_t>(), + 48usize, + concat!("Size of: ", stringify!(_opaque_pthread_cond_t)) ); assert_eq!( - ::std::mem::align_of::(), + ::std::mem::align_of::<_opaque_pthread_cond_t>(), 8usize, - concat!("Alignment of ", stringify!(timeval)) + concat!("Alignment of ", stringify!(_opaque_pthread_cond_t)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).tv_sec as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<_opaque_pthread_cond_t>())).__sig as *const _ as usize }, 0usize, - concat!("Offset of field: ", stringify!(timeval), "::", stringify!(tv_sec)) + concat!( + "Offset of field: ", + stringify!(_opaque_pthread_cond_t), + "::", + stringify!(__sig) + ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).tv_usec as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<_opaque_pthread_cond_t>())).__opaque as *const _ as usize }, 8usize, - concat!("Offset of field: ", stringify!(timeval), "::", stringify!(tv_usec)) + concat!( + "Offset of field: ", + stringify!(_opaque_pthread_cond_t), + "::", + stringify!(__opaque) + ) ); } #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct timespec { - pub tv_sec: __time_t, - pub tv_nsec: __syscall_slong_t, +pub struct _opaque_pthread_condattr_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 8usize], } #[test] -fn bindgen_test_layout_timespec() { +fn bindgen_test_layout__opaque_pthread_condattr_t() { assert_eq!( - ::std::mem::size_of::(), + ::std::mem::size_of::<_opaque_pthread_condattr_t>(), 16usize, - concat!("Size of: ", stringify!(timespec)) + concat!("Size of: ", stringify!(_opaque_pthread_condattr_t)) ); assert_eq!( - ::std::mem::align_of::(), + ::std::mem::align_of::<_opaque_pthread_condattr_t>(), 8usize, - concat!("Alignment of ", stringify!(timespec)) + concat!("Alignment of ", stringify!(_opaque_pthread_condattr_t)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).tv_sec as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<_opaque_pthread_condattr_t>())).__sig as *const _ as usize }, 0usize, - concat!("Offset of field: ", stringify!(timespec), "::", stringify!(tv_sec)) + concat!( + "Offset of field: ", + stringify!(_opaque_pthread_condattr_t), + "::", + stringify!(__sig) + ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).tv_nsec as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<_opaque_pthread_condattr_t>())).__opaque as *const _ as usize }, 8usize, - concat!("Offset of field: ", stringify!(timespec), "::", stringify!(tv_nsec)) + concat!( + "Offset of field: ", + stringify!(_opaque_pthread_condattr_t), + "::", + stringify!(__opaque) + ) ); } -pub type suseconds_t = __suseconds_t; -pub type __fd_mask = ::std::os::raw::c_long; #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct fd_set { - pub __fds_bits: [__fd_mask; 16usize], +pub struct _opaque_pthread_mutex_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 56usize], } #[test] -fn bindgen_test_layout_fd_set() { +fn bindgen_test_layout__opaque_pthread_mutex_t() { assert_eq!( - ::std::mem::size_of::(), - 128usize, - concat!("Size of: ", stringify!(fd_set)) + ::std::mem::size_of::<_opaque_pthread_mutex_t>(), + 64usize, + concat!("Size of: ", stringify!(_opaque_pthread_mutex_t)) ); assert_eq!( - ::std::mem::align_of::(), + ::std::mem::align_of::<_opaque_pthread_mutex_t>(), 8usize, - concat!("Alignment of ", stringify!(fd_set)) + concat!("Alignment of ", stringify!(_opaque_pthread_mutex_t)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).__fds_bits as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<_opaque_pthread_mutex_t>())).__sig as *const _ as usize }, 0usize, - concat!("Offset of field: ", stringify!(fd_set), "::", stringify!(__fds_bits)) + concat!( + "Offset of field: ", + stringify!(_opaque_pthread_mutex_t), + "::", + stringify!(__sig) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<_opaque_pthread_mutex_t>())).__opaque as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(_opaque_pthread_mutex_t), + "::", + stringify!(__opaque) + ) ); } -pub type fd_mask = __fd_mask; -extern "C" { - pub fn select( - __nfds: ::std::os::raw::c_int, - __readfds: *mut fd_set, - __writefds: *mut fd_set, - __exceptfds: *mut fd_set, - __timeout: *mut timeval, - ) -> ::std::os::raw::c_int; -} -extern "C" { - pub fn pselect( - __nfds: ::std::os::raw::c_int, - __readfds: *mut fd_set, - __writefds: *mut fd_set, - __exceptfds: *mut fd_set, - __timeout: *const timespec, - __sigmask: *const __sigset_t, - ) -> ::std::os::raw::c_int; -} -pub type blksize_t = __blksize_t; -pub type blkcnt_t = __blkcnt_t; -pub type fsblkcnt_t = __fsblkcnt_t; -pub type fsfilcnt_t = __fsfilcnt_t; #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct __pthread_internal_list { - pub __prev: *mut __pthread_internal_list, - pub __next: *mut __pthread_internal_list, +pub struct _opaque_pthread_mutexattr_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 8usize], } #[test] -fn bindgen_test_layout___pthread_internal_list() { +fn bindgen_test_layout__opaque_pthread_mutexattr_t() { assert_eq!( - ::std::mem::size_of::<__pthread_internal_list>(), + ::std::mem::size_of::<_opaque_pthread_mutexattr_t>(), 16usize, - concat!("Size of: ", stringify!(__pthread_internal_list)) + concat!("Size of: ", stringify!(_opaque_pthread_mutexattr_t)) ); assert_eq!( - ::std::mem::align_of::<__pthread_internal_list>(), + ::std::mem::align_of::<_opaque_pthread_mutexattr_t>(), 8usize, - concat!("Alignment of ", stringify!(__pthread_internal_list)) + concat!("Alignment of ", stringify!(_opaque_pthread_mutexattr_t)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_internal_list>())).__prev as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<_opaque_pthread_mutexattr_t>())).__sig as *const _ as usize }, 0usize, concat!( "Offset of field: ", - stringify!(__pthread_internal_list), + stringify!(_opaque_pthread_mutexattr_t), "::", - stringify!(__prev) + stringify!(__sig) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_internal_list>())).__next as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<_opaque_pthread_mutexattr_t>())).__opaque as *const _ as usize }, 8usize, concat!( "Offset of field: ", - stringify!(__pthread_internal_list), + stringify!(_opaque_pthread_mutexattr_t), "::", - stringify!(__next) + stringify!(__opaque) ) ); } -pub type __pthread_list_t = __pthread_internal_list; #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct __pthread_internal_slist { - pub __next: *mut __pthread_internal_slist, +pub struct _opaque_pthread_once_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 8usize], } #[test] -fn bindgen_test_layout___pthread_internal_slist() { +fn bindgen_test_layout__opaque_pthread_once_t() { assert_eq!( - ::std::mem::size_of::<__pthread_internal_slist>(), - 8usize, - concat!("Size of: ", stringify!(__pthread_internal_slist)) + ::std::mem::size_of::<_opaque_pthread_once_t>(), + 16usize, + concat!("Size of: ", stringify!(_opaque_pthread_once_t)) ); assert_eq!( - ::std::mem::align_of::<__pthread_internal_slist>(), + ::std::mem::align_of::<_opaque_pthread_once_t>(), 8usize, - concat!("Alignment of ", stringify!(__pthread_internal_slist)) + concat!("Alignment of ", stringify!(_opaque_pthread_once_t)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_internal_slist>())).__next as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<_opaque_pthread_once_t>())).__sig as *const _ as usize }, 0usize, concat!( "Offset of field: ", - stringify!(__pthread_internal_slist), + stringify!(_opaque_pthread_once_t), "::", - stringify!(__next) + stringify!(__sig) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<_opaque_pthread_once_t>())).__opaque as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(_opaque_pthread_once_t), + "::", + stringify!(__opaque) ) ); } -pub type __pthread_slist_t = __pthread_internal_slist; #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct __pthread_mutex_s { - pub __lock: ::std::os::raw::c_int, - pub __count: ::std::os::raw::c_uint, - pub __owner: ::std::os::raw::c_int, - pub __nusers: ::std::os::raw::c_uint, - pub __kind: ::std::os::raw::c_int, - pub __spins: ::std::os::raw::c_short, - pub __elision: ::std::os::raw::c_short, - pub __list: __pthread_list_t, +pub struct _opaque_pthread_rwlock_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 192usize], } #[test] -fn bindgen_test_layout___pthread_mutex_s() { +fn bindgen_test_layout__opaque_pthread_rwlock_t() { assert_eq!( - ::std::mem::size_of::<__pthread_mutex_s>(), - 40usize, - concat!("Size of: ", stringify!(__pthread_mutex_s)) + ::std::mem::size_of::<_opaque_pthread_rwlock_t>(), + 200usize, + concat!("Size of: ", stringify!(_opaque_pthread_rwlock_t)) ); assert_eq!( - ::std::mem::align_of::<__pthread_mutex_s>(), + ::std::mem::align_of::<_opaque_pthread_rwlock_t>(), 8usize, - concat!("Alignment of ", stringify!(__pthread_mutex_s)) + concat!("Alignment of ", stringify!(_opaque_pthread_rwlock_t)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_mutex_s>())).__lock as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<_opaque_pthread_rwlock_t>())).__sig as *const _ as usize }, 0usize, concat!( "Offset of field: ", - stringify!(__pthread_mutex_s), + stringify!(_opaque_pthread_rwlock_t), "::", - stringify!(__lock) + stringify!(__sig) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_mutex_s>())).__count as *const _ as usize }, - 4usize, + unsafe { &(*(::std::ptr::null::<_opaque_pthread_rwlock_t>())).__opaque as *const _ as usize }, + 8usize, concat!( "Offset of field: ", - stringify!(__pthread_mutex_s), + stringify!(_opaque_pthread_rwlock_t), "::", - stringify!(__count) + stringify!(__opaque) ) ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _opaque_pthread_rwlockattr_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 16usize], +} +#[test] +fn bindgen_test_layout__opaque_pthread_rwlockattr_t() { + assert_eq!( + ::std::mem::size_of::<_opaque_pthread_rwlockattr_t>(), + 24usize, + concat!("Size of: ", stringify!(_opaque_pthread_rwlockattr_t)) + ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_mutex_s>())).__owner as *const _ as usize }, + ::std::mem::align_of::<_opaque_pthread_rwlockattr_t>(), 8usize, - concat!( - "Offset of field: ", - stringify!(__pthread_mutex_s), - "::", - stringify!(__owner) - ) + concat!("Alignment of ", stringify!(_opaque_pthread_rwlockattr_t)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_mutex_s>())).__nusers as *const _ as usize }, - 12usize, + unsafe { &(*(::std::ptr::null::<_opaque_pthread_rwlockattr_t>())).__sig as *const _ as usize }, + 0usize, concat!( "Offset of field: ", - stringify!(__pthread_mutex_s), + stringify!(_opaque_pthread_rwlockattr_t), "::", - stringify!(__nusers) + stringify!(__sig) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_mutex_s>())).__kind as *const _ as usize }, - 16usize, + unsafe { &(*(::std::ptr::null::<_opaque_pthread_rwlockattr_t>())).__opaque as *const _ as usize }, + 8usize, concat!( "Offset of field: ", - stringify!(__pthread_mutex_s), + stringify!(_opaque_pthread_rwlockattr_t), "::", - stringify!(__kind) + stringify!(__opaque) ) ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _opaque_pthread_t { + pub __sig: ::std::os::raw::c_long, + pub __cleanup_stack: *mut __darwin_pthread_handler_rec, + pub __opaque: [::std::os::raw::c_char; 8176usize], +} +#[test] +fn bindgen_test_layout__opaque_pthread_t() { + assert_eq!( + ::std::mem::size_of::<_opaque_pthread_t>(), + 8192usize, + concat!("Size of: ", stringify!(_opaque_pthread_t)) + ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_mutex_s>())).__spins as *const _ as usize }, - 20usize, + ::std::mem::align_of::<_opaque_pthread_t>(), + 8usize, + concat!("Alignment of ", stringify!(_opaque_pthread_t)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<_opaque_pthread_t>())).__sig as *const _ as usize }, + 0usize, concat!( "Offset of field: ", - stringify!(__pthread_mutex_s), + stringify!(_opaque_pthread_t), "::", - stringify!(__spins) + stringify!(__sig) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_mutex_s>())).__elision as *const _ as usize }, - 22usize, + unsafe { &(*(::std::ptr::null::<_opaque_pthread_t>())).__cleanup_stack as *const _ as usize }, + 8usize, concat!( "Offset of field: ", - stringify!(__pthread_mutex_s), + stringify!(_opaque_pthread_t), "::", - stringify!(__elision) + stringify!(__cleanup_stack) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_mutex_s>())).__list as *const _ as usize }, - 24usize, + unsafe { &(*(::std::ptr::null::<_opaque_pthread_t>())).__opaque as *const _ as usize }, + 16usize, concat!( "Offset of field: ", - stringify!(__pthread_mutex_s), + stringify!(_opaque_pthread_t), "::", - stringify!(__list) + stringify!(__opaque) ) ); } +pub type __darwin_pthread_attr_t = _opaque_pthread_attr_t; +pub type __darwin_pthread_cond_t = _opaque_pthread_cond_t; +pub type __darwin_pthread_condattr_t = _opaque_pthread_condattr_t; +pub type __darwin_pthread_key_t = ::std::os::raw::c_ulong; +pub type __darwin_pthread_mutex_t = _opaque_pthread_mutex_t; +pub type __darwin_pthread_mutexattr_t = _opaque_pthread_mutexattr_t; +pub type __darwin_pthread_once_t = _opaque_pthread_once_t; +pub type __darwin_pthread_rwlock_t = _opaque_pthread_rwlock_t; +pub type __darwin_pthread_rwlockattr_t = _opaque_pthread_rwlockattr_t; +pub type __darwin_pthread_t = *mut _opaque_pthread_t; +pub type u_int8_t = ::std::os::raw::c_uchar; +pub type u_int16_t = ::std::os::raw::c_ushort; +pub type u_int32_t = ::std::os::raw::c_uint; +pub type u_int64_t = ::std::os::raw::c_ulonglong; +pub type register_t = i64; +pub type user_addr_t = u_int64_t; +pub type user_size_t = u_int64_t; +pub type user_ssize_t = i64; +pub type user_long_t = i64; +pub type user_ulong_t = u_int64_t; +pub type user_time_t = i64; +pub type user_off_t = i64; +pub type syscall_arg_t = u_int64_t; +pub type intmax_t = ::std::os::raw::c_long; +pub type uintmax_t = ::std::os::raw::c_ulong; +pub type __darwin_nl_item = ::std::os::raw::c_int; +pub type __darwin_wctrans_t = ::std::os::raw::c_int; +pub type __darwin_wctype_t = __uint32_t; +pub const idtype_t_P_ALL: idtype_t = 0; +pub const idtype_t_P_PID: idtype_t = 1; +pub const idtype_t_P_PGID: idtype_t = 2; +pub type idtype_t = ::std::os::raw::c_uint; +pub type pid_t = __darwin_pid_t; +pub type id_t = __darwin_id_t; +pub type sig_atomic_t = ::std::os::raw::c_int; #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct __pthread_rwlock_arch_t { - pub __readers: ::std::os::raw::c_uint, - pub __writers: ::std::os::raw::c_uint, - pub __wrphase_futex: ::std::os::raw::c_uint, - pub __writers_futex: ::std::os::raw::c_uint, - pub __pad3: ::std::os::raw::c_uint, - pub __pad4: ::std::os::raw::c_uint, - pub __cur_writer: ::std::os::raw::c_int, - pub __shared: ::std::os::raw::c_int, - pub __rwelision: ::std::os::raw::c_schar, - pub __pad1: [::std::os::raw::c_uchar; 7usize], - pub __pad2: ::std::os::raw::c_ulong, - pub __flags: ::std::os::raw::c_uint, +pub struct __darwin_i386_thread_state { + pub __eax: ::std::os::raw::c_uint, + pub __ebx: ::std::os::raw::c_uint, + pub __ecx: ::std::os::raw::c_uint, + pub __edx: ::std::os::raw::c_uint, + pub __edi: ::std::os::raw::c_uint, + pub __esi: ::std::os::raw::c_uint, + pub __ebp: ::std::os::raw::c_uint, + pub __esp: ::std::os::raw::c_uint, + pub __ss: ::std::os::raw::c_uint, + pub __eflags: ::std::os::raw::c_uint, + pub __eip: ::std::os::raw::c_uint, + pub __cs: ::std::os::raw::c_uint, + pub __ds: ::std::os::raw::c_uint, + pub __es: ::std::os::raw::c_uint, + pub __fs: ::std::os::raw::c_uint, + pub __gs: ::std::os::raw::c_uint, } #[test] -fn bindgen_test_layout___pthread_rwlock_arch_t() { +fn bindgen_test_layout___darwin_i386_thread_state() { assert_eq!( - ::std::mem::size_of::<__pthread_rwlock_arch_t>(), - 56usize, - concat!("Size of: ", stringify!(__pthread_rwlock_arch_t)) + ::std::mem::size_of::<__darwin_i386_thread_state>(), + 64usize, + concat!("Size of: ", stringify!(__darwin_i386_thread_state)) ); assert_eq!( - ::std::mem::align_of::<__pthread_rwlock_arch_t>(), - 8usize, - concat!("Alignment of ", stringify!(__pthread_rwlock_arch_t)) + ::std::mem::align_of::<__darwin_i386_thread_state>(), + 4usize, + concat!("Alignment of ", stringify!(__darwin_i386_thread_state)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_rwlock_arch_t>())).__readers as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<__darwin_i386_thread_state>())).__eax as *const _ as usize }, 0usize, concat!( "Offset of field: ", - stringify!(__pthread_rwlock_arch_t), + stringify!(__darwin_i386_thread_state), "::", - stringify!(__readers) + stringify!(__eax) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_rwlock_arch_t>())).__writers as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<__darwin_i386_thread_state>())).__ebx as *const _ as usize }, 4usize, concat!( "Offset of field: ", - stringify!(__pthread_rwlock_arch_t), + stringify!(__darwin_i386_thread_state), "::", - stringify!(__writers) + stringify!(__ebx) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_rwlock_arch_t>())).__wrphase_futex as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<__darwin_i386_thread_state>())).__ecx as *const _ as usize }, 8usize, concat!( "Offset of field: ", - stringify!(__pthread_rwlock_arch_t), + stringify!(__darwin_i386_thread_state), "::", - stringify!(__wrphase_futex) + stringify!(__ecx) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_rwlock_arch_t>())).__writers_futex as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<__darwin_i386_thread_state>())).__edx as *const _ as usize }, 12usize, concat!( "Offset of field: ", - stringify!(__pthread_rwlock_arch_t), + stringify!(__darwin_i386_thread_state), "::", - stringify!(__writers_futex) + stringify!(__edx) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_rwlock_arch_t>())).__pad3 as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<__darwin_i386_thread_state>())).__edi as *const _ as usize }, 16usize, concat!( "Offset of field: ", - stringify!(__pthread_rwlock_arch_t), + stringify!(__darwin_i386_thread_state), "::", - stringify!(__pad3) + stringify!(__edi) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_rwlock_arch_t>())).__pad4 as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<__darwin_i386_thread_state>())).__esi as *const _ as usize }, 20usize, concat!( "Offset of field: ", - stringify!(__pthread_rwlock_arch_t), + stringify!(__darwin_i386_thread_state), "::", - stringify!(__pad4) + stringify!(__esi) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_rwlock_arch_t>())).__cur_writer as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<__darwin_i386_thread_state>())).__ebp as *const _ as usize }, 24usize, concat!( "Offset of field: ", - stringify!(__pthread_rwlock_arch_t), + stringify!(__darwin_i386_thread_state), "::", - stringify!(__cur_writer) + stringify!(__ebp) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_rwlock_arch_t>())).__shared as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<__darwin_i386_thread_state>())).__esp as *const _ as usize }, 28usize, concat!( "Offset of field: ", - stringify!(__pthread_rwlock_arch_t), + stringify!(__darwin_i386_thread_state), "::", - stringify!(__shared) + stringify!(__esp) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_rwlock_arch_t>())).__rwelision as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<__darwin_i386_thread_state>())).__ss as *const _ as usize }, 32usize, concat!( "Offset of field: ", - stringify!(__pthread_rwlock_arch_t), + stringify!(__darwin_i386_thread_state), "::", - stringify!(__rwelision) + stringify!(__ss) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_rwlock_arch_t>())).__pad1 as *const _ as usize }, - 33usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_thread_state>())).__eflags as *const _ as usize }, + 36usize, concat!( "Offset of field: ", - stringify!(__pthread_rwlock_arch_t), + stringify!(__darwin_i386_thread_state), "::", - stringify!(__pad1) + stringify!(__eflags) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_rwlock_arch_t>())).__pad2 as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<__darwin_i386_thread_state>())).__eip as *const _ as usize }, 40usize, concat!( "Offset of field: ", - stringify!(__pthread_rwlock_arch_t), + stringify!(__darwin_i386_thread_state), "::", - stringify!(__pad2) + stringify!(__eip) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_rwlock_arch_t>())).__flags as *const _ as usize }, - 48usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_thread_state>())).__cs as *const _ as usize }, + 44usize, concat!( "Offset of field: ", - stringify!(__pthread_rwlock_arch_t), + stringify!(__darwin_i386_thread_state), "::", - stringify!(__flags) + stringify!(__cs) ) ); -} -#[repr(C)] -#[derive(Copy, Clone)] -pub struct __pthread_cond_s { - pub __bindgen_anon_1: __pthread_cond_s__bindgen_ty_1, - pub __bindgen_anon_2: __pthread_cond_s__bindgen_ty_2, - pub __g_refs: [::std::os::raw::c_uint; 2usize], - pub __g_size: [::std::os::raw::c_uint; 2usize], - pub __g1_orig_size: ::std::os::raw::c_uint, - pub __wrefs: ::std::os::raw::c_uint, - pub __g_signals: [::std::os::raw::c_uint; 2usize], -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union __pthread_cond_s__bindgen_ty_1 { - pub __wseq: ::std::os::raw::c_ulonglong, - pub __wseq32: __pthread_cond_s__bindgen_ty_1__bindgen_ty_1, -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct __pthread_cond_s__bindgen_ty_1__bindgen_ty_1 { - pub __low: ::std::os::raw::c_uint, - pub __high: ::std::os::raw::c_uint, -} -#[test] -fn bindgen_test_layout___pthread_cond_s__bindgen_ty_1__bindgen_ty_1() { assert_eq!( - ::std::mem::size_of::<__pthread_cond_s__bindgen_ty_1__bindgen_ty_1>(), - 8usize, - concat!("Size of: ", stringify!(__pthread_cond_s__bindgen_ty_1__bindgen_ty_1)) + unsafe { &(*(::std::ptr::null::<__darwin_i386_thread_state>())).__ds as *const _ as usize }, + 48usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_thread_state), + "::", + stringify!(__ds) + ) ); assert_eq!( - ::std::mem::align_of::<__pthread_cond_s__bindgen_ty_1__bindgen_ty_1>(), - 4usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_thread_state>())).__es as *const _ as usize }, + 52usize, concat!( - "Alignment of ", - stringify!(__pthread_cond_s__bindgen_ty_1__bindgen_ty_1) + "Offset of field: ", + stringify!(__darwin_i386_thread_state), + "::", + stringify!(__es) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_cond_s__bindgen_ty_1__bindgen_ty_1>())).__low as *const _ as usize }, - 0usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_thread_state>())).__fs as *const _ as usize }, + 56usize, concat!( "Offset of field: ", - stringify!(__pthread_cond_s__bindgen_ty_1__bindgen_ty_1), + stringify!(__darwin_i386_thread_state), "::", - stringify!(__low) + stringify!(__fs) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_cond_s__bindgen_ty_1__bindgen_ty_1>())).__high as *const _ as usize }, - 4usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_thread_state>())).__gs as *const _ as usize }, + 60usize, concat!( "Offset of field: ", - stringify!(__pthread_cond_s__bindgen_ty_1__bindgen_ty_1), + stringify!(__darwin_i386_thread_state), "::", - stringify!(__high) + stringify!(__gs) ) ); } +#[repr(C)] +#[repr(align(2))] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_fp_control { + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>, +} #[test] -fn bindgen_test_layout___pthread_cond_s__bindgen_ty_1() { +fn bindgen_test_layout___darwin_fp_control() { assert_eq!( - ::std::mem::size_of::<__pthread_cond_s__bindgen_ty_1>(), - 8usize, - concat!("Size of: ", stringify!(__pthread_cond_s__bindgen_ty_1)) + ::std::mem::size_of::<__darwin_fp_control>(), + 2usize, + concat!("Size of: ", stringify!(__darwin_fp_control)) ); assert_eq!( - ::std::mem::align_of::<__pthread_cond_s__bindgen_ty_1>(), - 8usize, - concat!("Alignment of ", stringify!(__pthread_cond_s__bindgen_ty_1)) + ::std::mem::align_of::<__darwin_fp_control>(), + 2usize, + concat!("Alignment of ", stringify!(__darwin_fp_control)) + ); +} +impl __darwin_fp_control { + #[inline] + pub fn __invalid(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u16) } + } + #[inline] + pub fn set___invalid(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn __denorm(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u16) } + } + #[inline] + pub fn set___denorm(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn __zdiv(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u16) } + } + #[inline] + pub fn set___zdiv(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[inline] + pub fn __ovrfl(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u16) } + } + #[inline] + pub fn set___ovrfl(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 1u8, val as u64) + } + } + #[inline] + pub fn __undfl(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u16) } + } + #[inline] + pub fn set___undfl(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 1u8, val as u64) + } + } + #[inline] + pub fn __precis(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u16) } + } + #[inline] + pub fn set___precis(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 1u8, val as u64) + } + } + #[inline] + pub fn __pc(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 2u8) as u16) } + } + #[inline] + pub fn set___pc(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 2u8, val as u64) + } + } + #[inline] + pub fn __rc(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(10usize, 2u8) as u16) } + } + #[inline] + pub fn set___rc(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(10usize, 2u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + __invalid: ::std::os::raw::c_ushort, + __denorm: ::std::os::raw::c_ushort, + __zdiv: ::std::os::raw::c_ushort, + __ovrfl: ::std::os::raw::c_ushort, + __undfl: ::std::os::raw::c_ushort, + __precis: ::std::os::raw::c_ushort, + __pc: ::std::os::raw::c_ushort, + __rc: ::std::os::raw::c_ushort, + ) -> __BindgenBitfieldUnit<[u8; 2usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let __invalid: u16 = unsafe { ::std::mem::transmute(__invalid) }; + __invalid as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let __denorm: u16 = unsafe { ::std::mem::transmute(__denorm) }; + __denorm as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let __zdiv: u16 = unsafe { ::std::mem::transmute(__zdiv) }; + __zdiv as u64 + }); + __bindgen_bitfield_unit.set(3usize, 1u8, { + let __ovrfl: u16 = unsafe { ::std::mem::transmute(__ovrfl) }; + __ovrfl as u64 + }); + __bindgen_bitfield_unit.set(4usize, 1u8, { + let __undfl: u16 = unsafe { ::std::mem::transmute(__undfl) }; + __undfl as u64 + }); + __bindgen_bitfield_unit.set(5usize, 1u8, { + let __precis: u16 = unsafe { ::std::mem::transmute(__precis) }; + __precis as u64 + }); + __bindgen_bitfield_unit.set(8usize, 2u8, { + let __pc: u16 = unsafe { ::std::mem::transmute(__pc) }; + __pc as u64 + }); + __bindgen_bitfield_unit.set(10usize, 2u8, { + let __rc: u16 = unsafe { ::std::mem::transmute(__rc) }; + __rc as u64 + }); + __bindgen_bitfield_unit + } +} +pub type __darwin_fp_control_t = __darwin_fp_control; +#[repr(C)] +#[repr(align(2))] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_fp_status { + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>, +} +#[test] +fn bindgen_test_layout___darwin_fp_status() { + assert_eq!( + ::std::mem::size_of::<__darwin_fp_status>(), + 2usize, + concat!("Size of: ", stringify!(__darwin_fp_status)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_fp_status>(), + 2usize, + concat!("Alignment of ", stringify!(__darwin_fp_status)) + ); +} +impl __darwin_fp_status { + #[inline] + pub fn __invalid(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u16) } + } + #[inline] + pub fn set___invalid(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn __denorm(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u16) } + } + #[inline] + pub fn set___denorm(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn __zdiv(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u16) } + } + #[inline] + pub fn set___zdiv(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[inline] + pub fn __ovrfl(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u16) } + } + #[inline] + pub fn set___ovrfl(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 1u8, val as u64) + } + } + #[inline] + pub fn __undfl(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u16) } + } + #[inline] + pub fn set___undfl(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 1u8, val as u64) + } + } + #[inline] + pub fn __precis(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u16) } + } + #[inline] + pub fn set___precis(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(5usize, 1u8, val as u64) + } + } + #[inline] + pub fn __stkflt(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 1u8) as u16) } + } + #[inline] + pub fn set___stkflt(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(6usize, 1u8, val as u64) + } + } + #[inline] + pub fn __errsumm(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u16) } + } + #[inline] + pub fn set___errsumm(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(7usize, 1u8, val as u64) + } + } + #[inline] + pub fn __c0(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 1u8) as u16) } + } + #[inline] + pub fn set___c0(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 1u8, val as u64) + } + } + #[inline] + pub fn __c1(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(9usize, 1u8) as u16) } + } + #[inline] + pub fn set___c1(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(9usize, 1u8, val as u64) + } + } + #[inline] + pub fn __c2(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(10usize, 1u8) as u16) } + } + #[inline] + pub fn set___c2(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(10usize, 1u8, val as u64) + } + } + #[inline] + pub fn __tos(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(11usize, 3u8) as u16) } + } + #[inline] + pub fn set___tos(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(11usize, 3u8, val as u64) + } + } + #[inline] + pub fn __c3(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(14usize, 1u8) as u16) } + } + #[inline] + pub fn set___c3(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(14usize, 1u8, val as u64) + } + } + #[inline] + pub fn __busy(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(15usize, 1u8) as u16) } + } + #[inline] + pub fn set___busy(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(15usize, 1u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + __invalid: ::std::os::raw::c_ushort, + __denorm: ::std::os::raw::c_ushort, + __zdiv: ::std::os::raw::c_ushort, + __ovrfl: ::std::os::raw::c_ushort, + __undfl: ::std::os::raw::c_ushort, + __precis: ::std::os::raw::c_ushort, + __stkflt: ::std::os::raw::c_ushort, + __errsumm: ::std::os::raw::c_ushort, + __c0: ::std::os::raw::c_ushort, + __c1: ::std::os::raw::c_ushort, + __c2: ::std::os::raw::c_ushort, + __tos: ::std::os::raw::c_ushort, + __c3: ::std::os::raw::c_ushort, + __busy: ::std::os::raw::c_ushort, + ) -> __BindgenBitfieldUnit<[u8; 2usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let __invalid: u16 = unsafe { ::std::mem::transmute(__invalid) }; + __invalid as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let __denorm: u16 = unsafe { ::std::mem::transmute(__denorm) }; + __denorm as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let __zdiv: u16 = unsafe { ::std::mem::transmute(__zdiv) }; + __zdiv as u64 + }); + __bindgen_bitfield_unit.set(3usize, 1u8, { + let __ovrfl: u16 = unsafe { ::std::mem::transmute(__ovrfl) }; + __ovrfl as u64 + }); + __bindgen_bitfield_unit.set(4usize, 1u8, { + let __undfl: u16 = unsafe { ::std::mem::transmute(__undfl) }; + __undfl as u64 + }); + __bindgen_bitfield_unit.set(5usize, 1u8, { + let __precis: u16 = unsafe { ::std::mem::transmute(__precis) }; + __precis as u64 + }); + __bindgen_bitfield_unit.set(6usize, 1u8, { + let __stkflt: u16 = unsafe { ::std::mem::transmute(__stkflt) }; + __stkflt as u64 + }); + __bindgen_bitfield_unit.set(7usize, 1u8, { + let __errsumm: u16 = unsafe { ::std::mem::transmute(__errsumm) }; + __errsumm as u64 + }); + __bindgen_bitfield_unit.set(8usize, 1u8, { + let __c0: u16 = unsafe { ::std::mem::transmute(__c0) }; + __c0 as u64 + }); + __bindgen_bitfield_unit.set(9usize, 1u8, { + let __c1: u16 = unsafe { ::std::mem::transmute(__c1) }; + __c1 as u64 + }); + __bindgen_bitfield_unit.set(10usize, 1u8, { + let __c2: u16 = unsafe { ::std::mem::transmute(__c2) }; + __c2 as u64 + }); + __bindgen_bitfield_unit.set(11usize, 3u8, { + let __tos: u16 = unsafe { ::std::mem::transmute(__tos) }; + __tos as u64 + }); + __bindgen_bitfield_unit.set(14usize, 1u8, { + let __c3: u16 = unsafe { ::std::mem::transmute(__c3) }; + __c3 as u64 + }); + __bindgen_bitfield_unit.set(15usize, 1u8, { + let __busy: u16 = unsafe { ::std::mem::transmute(__busy) }; + __busy as u64 + }); + __bindgen_bitfield_unit + } +} +pub type __darwin_fp_status_t = __darwin_fp_status; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_mmst_reg { + pub __mmst_reg: [::std::os::raw::c_char; 10usize], + pub __mmst_rsrv: [::std::os::raw::c_char; 6usize], +} +#[test] +fn bindgen_test_layout___darwin_mmst_reg() { + assert_eq!( + ::std::mem::size_of::<__darwin_mmst_reg>(), + 16usize, + concat!("Size of: ", stringify!(__darwin_mmst_reg)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_mmst_reg>(), + 1usize, + concat!("Alignment of ", stringify!(__darwin_mmst_reg)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_cond_s__bindgen_ty_1>())).__wseq as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<__darwin_mmst_reg>())).__mmst_reg as *const _ as usize }, 0usize, concat!( "Offset of field: ", - stringify!(__pthread_cond_s__bindgen_ty_1), + stringify!(__darwin_mmst_reg), "::", - stringify!(__wseq) + stringify!(__mmst_reg) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_cond_s__bindgen_ty_1>())).__wseq32 as *const _ as usize }, - 0usize, + unsafe { &(*(::std::ptr::null::<__darwin_mmst_reg>())).__mmst_rsrv as *const _ as usize }, + 10usize, concat!( "Offset of field: ", - stringify!(__pthread_cond_s__bindgen_ty_1), + stringify!(__darwin_mmst_reg), "::", - stringify!(__wseq32) + stringify!(__mmst_rsrv) ) ); } #[repr(C)] -#[derive(Copy, Clone)] -pub union __pthread_cond_s__bindgen_ty_2 { - pub __g1_start: ::std::os::raw::c_ulonglong, - pub __g1_start32: __pthread_cond_s__bindgen_ty_2__bindgen_ty_1, -} -#[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct __pthread_cond_s__bindgen_ty_2__bindgen_ty_1 { - pub __low: ::std::os::raw::c_uint, - pub __high: ::std::os::raw::c_uint, +pub struct __darwin_xmm_reg { + pub __xmm_reg: [::std::os::raw::c_char; 16usize], } #[test] -fn bindgen_test_layout___pthread_cond_s__bindgen_ty_2__bindgen_ty_1() { +fn bindgen_test_layout___darwin_xmm_reg() { assert_eq!( - ::std::mem::size_of::<__pthread_cond_s__bindgen_ty_2__bindgen_ty_1>(), - 8usize, - concat!("Size of: ", stringify!(__pthread_cond_s__bindgen_ty_2__bindgen_ty_1)) + ::std::mem::size_of::<__darwin_xmm_reg>(), + 16usize, + concat!("Size of: ", stringify!(__darwin_xmm_reg)) ); assert_eq!( - ::std::mem::align_of::<__pthread_cond_s__bindgen_ty_2__bindgen_ty_1>(), - 4usize, - concat!( - "Alignment of ", - stringify!(__pthread_cond_s__bindgen_ty_2__bindgen_ty_1) - ) + ::std::mem::align_of::<__darwin_xmm_reg>(), + 1usize, + concat!("Alignment of ", stringify!(__darwin_xmm_reg)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_cond_s__bindgen_ty_2__bindgen_ty_1>())).__low as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<__darwin_xmm_reg>())).__xmm_reg as *const _ as usize }, 0usize, concat!( "Offset of field: ", - stringify!(__pthread_cond_s__bindgen_ty_2__bindgen_ty_1), + stringify!(__darwin_xmm_reg), "::", - stringify!(__low) + stringify!(__xmm_reg) ) ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_ymm_reg { + pub __ymm_reg: [::std::os::raw::c_char; 32usize], +} +#[test] +fn bindgen_test_layout___darwin_ymm_reg() { assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_cond_s__bindgen_ty_2__bindgen_ty_1>())).__high as *const _ as usize }, - 4usize, + ::std::mem::size_of::<__darwin_ymm_reg>(), + 32usize, + concat!("Size of: ", stringify!(__darwin_ymm_reg)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_ymm_reg>(), + 1usize, + concat!("Alignment of ", stringify!(__darwin_ymm_reg)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_ymm_reg>())).__ymm_reg as *const _ as usize }, + 0usize, concat!( "Offset of field: ", - stringify!(__pthread_cond_s__bindgen_ty_2__bindgen_ty_1), + stringify!(__darwin_ymm_reg), "::", - stringify!(__high) + stringify!(__ymm_reg) ) ); } +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_zmm_reg { + pub __zmm_reg: [::std::os::raw::c_char; 64usize], +} #[test] -fn bindgen_test_layout___pthread_cond_s__bindgen_ty_2() { +fn bindgen_test_layout___darwin_zmm_reg() { assert_eq!( - ::std::mem::size_of::<__pthread_cond_s__bindgen_ty_2>(), - 8usize, - concat!("Size of: ", stringify!(__pthread_cond_s__bindgen_ty_2)) + ::std::mem::size_of::<__darwin_zmm_reg>(), + 64usize, + concat!("Size of: ", stringify!(__darwin_zmm_reg)) ); assert_eq!( - ::std::mem::align_of::<__pthread_cond_s__bindgen_ty_2>(), - 8usize, - concat!("Alignment of ", stringify!(__pthread_cond_s__bindgen_ty_2)) + ::std::mem::align_of::<__darwin_zmm_reg>(), + 1usize, + concat!("Alignment of ", stringify!(__darwin_zmm_reg)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_cond_s__bindgen_ty_2>())).__g1_start as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<__darwin_zmm_reg>())).__zmm_reg as *const _ as usize }, 0usize, concat!( "Offset of field: ", - stringify!(__pthread_cond_s__bindgen_ty_2), + stringify!(__darwin_zmm_reg), "::", - stringify!(__g1_start) + stringify!(__zmm_reg) ) ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_opmask_reg { + pub __opmask_reg: [::std::os::raw::c_char; 8usize], +} +#[test] +fn bindgen_test_layout___darwin_opmask_reg() { + assert_eq!( + ::std::mem::size_of::<__darwin_opmask_reg>(), + 8usize, + concat!("Size of: ", stringify!(__darwin_opmask_reg)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_opmask_reg>(), + 1usize, + concat!("Alignment of ", stringify!(__darwin_opmask_reg)) + ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_cond_s__bindgen_ty_2>())).__g1_start32 as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<__darwin_opmask_reg>())).__opmask_reg as *const _ as usize }, 0usize, concat!( "Offset of field: ", - stringify!(__pthread_cond_s__bindgen_ty_2), + stringify!(__darwin_opmask_reg), "::", - stringify!(__g1_start32) + stringify!(__opmask_reg) ) ); } +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_i386_float_state { + pub __fpu_reserved: [::std::os::raw::c_int; 2usize], + pub __fpu_fcw: __darwin_fp_control, + pub __fpu_fsw: __darwin_fp_status, + pub __fpu_ftw: __uint8_t, + pub __fpu_rsrv1: __uint8_t, + pub __fpu_fop: __uint16_t, + pub __fpu_ip: __uint32_t, + pub __fpu_cs: __uint16_t, + pub __fpu_rsrv2: __uint16_t, + pub __fpu_dp: __uint32_t, + pub __fpu_ds: __uint16_t, + pub __fpu_rsrv3: __uint16_t, + pub __fpu_mxcsr: __uint32_t, + pub __fpu_mxcsrmask: __uint32_t, + pub __fpu_stmm0: __darwin_mmst_reg, + pub __fpu_stmm1: __darwin_mmst_reg, + pub __fpu_stmm2: __darwin_mmst_reg, + pub __fpu_stmm3: __darwin_mmst_reg, + pub __fpu_stmm4: __darwin_mmst_reg, + pub __fpu_stmm5: __darwin_mmst_reg, + pub __fpu_stmm6: __darwin_mmst_reg, + pub __fpu_stmm7: __darwin_mmst_reg, + pub __fpu_xmm0: __darwin_xmm_reg, + pub __fpu_xmm1: __darwin_xmm_reg, + pub __fpu_xmm2: __darwin_xmm_reg, + pub __fpu_xmm3: __darwin_xmm_reg, + pub __fpu_xmm4: __darwin_xmm_reg, + pub __fpu_xmm5: __darwin_xmm_reg, + pub __fpu_xmm6: __darwin_xmm_reg, + pub __fpu_xmm7: __darwin_xmm_reg, + pub __fpu_rsrv4: [::std::os::raw::c_char; 224usize], + pub __fpu_reserved1: ::std::os::raw::c_int, +} #[test] -fn bindgen_test_layout___pthread_cond_s() { +fn bindgen_test_layout___darwin_i386_float_state() { assert_eq!( - ::std::mem::size_of::<__pthread_cond_s>(), - 48usize, - concat!("Size of: ", stringify!(__pthread_cond_s)) + ::std::mem::size_of::<__darwin_i386_float_state>(), + 524usize, + concat!("Size of: ", stringify!(__darwin_i386_float_state)) ); assert_eq!( - ::std::mem::align_of::<__pthread_cond_s>(), - 8usize, - concat!("Alignment of ", stringify!(__pthread_cond_s)) + ::std::mem::align_of::<__darwin_i386_float_state>(), + 4usize, + concat!("Alignment of ", stringify!(__darwin_i386_float_state)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_cond_s>())).__g_refs as *const _ as usize }, - 16usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_reserved as *const _ as usize }, + 0usize, concat!( "Offset of field: ", - stringify!(__pthread_cond_s), + stringify!(__darwin_i386_float_state), "::", - stringify!(__g_refs) + stringify!(__fpu_reserved) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_cond_s>())).__g_size as *const _ as usize }, - 24usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_fcw as *const _ as usize }, + 8usize, concat!( "Offset of field: ", - stringify!(__pthread_cond_s), + stringify!(__darwin_i386_float_state), "::", - stringify!(__g_size) + stringify!(__fpu_fcw) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_cond_s>())).__g1_orig_size as *const _ as usize }, - 32usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_fsw as *const _ as usize }, + 10usize, concat!( "Offset of field: ", - stringify!(__pthread_cond_s), + stringify!(__darwin_i386_float_state), "::", - stringify!(__g1_orig_size) + stringify!(__fpu_fsw) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_cond_s>())).__wrefs as *const _ as usize }, - 36usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_ftw as *const _ as usize }, + 12usize, concat!( "Offset of field: ", - stringify!(__pthread_cond_s), + stringify!(__darwin_i386_float_state), "::", - stringify!(__wrefs) + stringify!(__fpu_ftw) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__pthread_cond_s>())).__g_signals as *const _ as usize }, - 40usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_rsrv1 as *const _ as usize }, + 13usize, concat!( "Offset of field: ", - stringify!(__pthread_cond_s), + stringify!(__darwin_i386_float_state), "::", - stringify!(__g_signals) + stringify!(__fpu_rsrv1) ) ); -} -pub type __tss_t = ::std::os::raw::c_uint; -pub type __thrd_t = ::std::os::raw::c_ulong; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct __once_flag { - pub __data: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout___once_flag() { - assert_eq!( - ::std::mem::size_of::<__once_flag>(), - 4usize, - concat!("Size of: ", stringify!(__once_flag)) - ); - assert_eq!( - ::std::mem::align_of::<__once_flag>(), - 4usize, - concat!("Alignment of ", stringify!(__once_flag)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<__once_flag>())).__data as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(__once_flag), "::", stringify!(__data)) - ); -} -pub type pthread_t = ::std::os::raw::c_ulong; -#[repr(C)] -#[derive(Copy, Clone)] -pub union pthread_mutexattr_t { - pub __size: [::std::os::raw::c_char; 4usize], - pub __align: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_pthread_mutexattr_t() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(pthread_mutexattr_t)) - ); assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(pthread_mutexattr_t)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).__size as *const _ as usize }, - 0usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_fop as *const _ as usize }, + 14usize, concat!( "Offset of field: ", - stringify!(pthread_mutexattr_t), + stringify!(__darwin_i386_float_state), "::", - stringify!(__size) + stringify!(__fpu_fop) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).__align as *const _ as usize }, - 0usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_ip as *const _ as usize }, + 16usize, concat!( "Offset of field: ", - stringify!(pthread_mutexattr_t), + stringify!(__darwin_i386_float_state), "::", - stringify!(__align) + stringify!(__fpu_ip) ) ); -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union pthread_condattr_t { - pub __size: [::std::os::raw::c_char; 4usize], - pub __align: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_pthread_condattr_t() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(pthread_condattr_t)) - ); assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(pthread_condattr_t)) + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_cs as *const _ as usize }, + 20usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_float_state), + "::", + stringify!(__fpu_cs) + ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).__size as *const _ as usize }, - 0usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_rsrv2 as *const _ as usize }, + 22usize, concat!( "Offset of field: ", - stringify!(pthread_condattr_t), + stringify!(__darwin_i386_float_state), "::", - stringify!(__size) + stringify!(__fpu_rsrv2) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).__align as *const _ as usize }, - 0usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_dp as *const _ as usize }, + 24usize, concat!( "Offset of field: ", - stringify!(pthread_condattr_t), + stringify!(__darwin_i386_float_state), "::", - stringify!(__align) + stringify!(__fpu_dp) ) ); -} -pub type pthread_key_t = ::std::os::raw::c_uint; -pub type pthread_once_t = ::std::os::raw::c_int; -#[repr(C)] -#[derive(Copy, Clone)] -pub union pthread_attr_t { - pub __size: [::std::os::raw::c_char; 56usize], - pub __align: ::std::os::raw::c_long, -} -#[test] -fn bindgen_test_layout_pthread_attr_t() { assert_eq!( - ::std::mem::size_of::(), - 56usize, - concat!("Size of: ", stringify!(pthread_attr_t)) + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_ds as *const _ as usize }, + 28usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_float_state), + "::", + stringify!(__fpu_ds) + ) ); assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(pthread_attr_t)) + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_rsrv3 as *const _ as usize }, + 30usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_float_state), + "::", + stringify!(__fpu_rsrv3) + ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).__size as *const _ as usize }, - 0usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_mxcsr as *const _ as usize }, + 32usize, concat!( "Offset of field: ", - stringify!(pthread_attr_t), + stringify!(__darwin_i386_float_state), "::", - stringify!(__size) + stringify!(__fpu_mxcsr) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).__align as *const _ as usize }, - 0usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_mxcsrmask as *const _ as usize }, + 36usize, concat!( "Offset of field: ", - stringify!(pthread_attr_t), + stringify!(__darwin_i386_float_state), "::", - stringify!(__align) + stringify!(__fpu_mxcsrmask) ) ); -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union pthread_mutex_t { - pub __data: __pthread_mutex_s, - pub __size: [::std::os::raw::c_char; 40usize], - pub __align: ::std::os::raw::c_long, -} -#[test] -fn bindgen_test_layout_pthread_mutex_t() { assert_eq!( - ::std::mem::size_of::(), + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_stmm0 as *const _ as usize }, 40usize, - concat!("Size of: ", stringify!(pthread_mutex_t)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(pthread_mutex_t)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).__data as *const _ as usize }, - 0usize, concat!( "Offset of field: ", - stringify!(pthread_mutex_t), + stringify!(__darwin_i386_float_state), "::", - stringify!(__data) + stringify!(__fpu_stmm0) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).__size as *const _ as usize }, - 0usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_stmm1 as *const _ as usize }, + 56usize, concat!( "Offset of field: ", - stringify!(pthread_mutex_t), + stringify!(__darwin_i386_float_state), "::", - stringify!(__size) + stringify!(__fpu_stmm1) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).__align as *const _ as usize }, - 0usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_stmm2 as *const _ as usize }, + 72usize, concat!( "Offset of field: ", - stringify!(pthread_mutex_t), + stringify!(__darwin_i386_float_state), "::", - stringify!(__align) + stringify!(__fpu_stmm2) ) ); -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union pthread_cond_t { - pub __data: __pthread_cond_s, - pub __size: [::std::os::raw::c_char; 48usize], - pub __align: ::std::os::raw::c_longlong, -} -#[test] -fn bindgen_test_layout_pthread_cond_t() { - assert_eq!( - ::std::mem::size_of::(), - 48usize, - concat!("Size of: ", stringify!(pthread_cond_t)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(pthread_cond_t)) - ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).__data as *const _ as usize }, - 0usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_stmm3 as *const _ as usize }, + 88usize, concat!( "Offset of field: ", - stringify!(pthread_cond_t), + stringify!(__darwin_i386_float_state), "::", - stringify!(__data) + stringify!(__fpu_stmm3) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).__size as *const _ as usize }, - 0usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_stmm4 as *const _ as usize }, + 104usize, concat!( "Offset of field: ", - stringify!(pthread_cond_t), + stringify!(__darwin_i386_float_state), "::", - stringify!(__size) + stringify!(__fpu_stmm4) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).__align as *const _ as usize }, - 0usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_stmm5 as *const _ as usize }, + 120usize, concat!( "Offset of field: ", - stringify!(pthread_cond_t), + stringify!(__darwin_i386_float_state), "::", - stringify!(__align) + stringify!(__fpu_stmm5) ) ); -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union pthread_rwlock_t { - pub __data: __pthread_rwlock_arch_t, - pub __size: [::std::os::raw::c_char; 56usize], - pub __align: ::std::os::raw::c_long, -} -#[test] -fn bindgen_test_layout_pthread_rwlock_t() { - assert_eq!( - ::std::mem::size_of::(), - 56usize, - concat!("Size of: ", stringify!(pthread_rwlock_t)) - ); assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(pthread_rwlock_t)) + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_stmm6 as *const _ as usize }, + 136usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_float_state), + "::", + stringify!(__fpu_stmm6) + ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).__data as *const _ as usize }, - 0usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_stmm7 as *const _ as usize }, + 152usize, concat!( "Offset of field: ", - stringify!(pthread_rwlock_t), + stringify!(__darwin_i386_float_state), "::", - stringify!(__data) + stringify!(__fpu_stmm7) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).__size as *const _ as usize }, - 0usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_xmm0 as *const _ as usize }, + 168usize, concat!( "Offset of field: ", - stringify!(pthread_rwlock_t), + stringify!(__darwin_i386_float_state), "::", - stringify!(__size) + stringify!(__fpu_xmm0) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).__align as *const _ as usize }, - 0usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_xmm1 as *const _ as usize }, + 184usize, concat!( "Offset of field: ", - stringify!(pthread_rwlock_t), + stringify!(__darwin_i386_float_state), "::", - stringify!(__align) + stringify!(__fpu_xmm1) ) ); -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union pthread_rwlockattr_t { - pub __size: [::std::os::raw::c_char; 8usize], - pub __align: ::std::os::raw::c_long, -} -#[test] -fn bindgen_test_layout_pthread_rwlockattr_t() { assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(pthread_rwlockattr_t)) + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_xmm2 as *const _ as usize }, + 200usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_float_state), + "::", + stringify!(__fpu_xmm2) + ) ); assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(pthread_rwlockattr_t)) + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_xmm3 as *const _ as usize }, + 216usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_float_state), + "::", + stringify!(__fpu_xmm3) + ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).__size as *const _ as usize }, - 0usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_xmm4 as *const _ as usize }, + 232usize, concat!( "Offset of field: ", - stringify!(pthread_rwlockattr_t), + stringify!(__darwin_i386_float_state), "::", - stringify!(__size) + stringify!(__fpu_xmm4) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).__align as *const _ as usize }, - 0usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_xmm5 as *const _ as usize }, + 248usize, concat!( "Offset of field: ", - stringify!(pthread_rwlockattr_t), + stringify!(__darwin_i386_float_state), "::", - stringify!(__align) + stringify!(__fpu_xmm5) ) ); -} -pub type pthread_spinlock_t = ::std::os::raw::c_int; -#[repr(C)] -#[derive(Copy, Clone)] -pub union pthread_barrier_t { - pub __size: [::std::os::raw::c_char; 32usize], - pub __align: ::std::os::raw::c_long, -} -#[test] -fn bindgen_test_layout_pthread_barrier_t() { assert_eq!( - ::std::mem::size_of::(), - 32usize, - concat!("Size of: ", stringify!(pthread_barrier_t)) + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_xmm6 as *const _ as usize }, + 264usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_float_state), + "::", + stringify!(__fpu_xmm6) + ) ); assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(pthread_barrier_t)) + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_xmm7 as *const _ as usize }, + 280usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_float_state), + "::", + stringify!(__fpu_xmm7) + ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).__size as *const _ as usize }, - 0usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_rsrv4 as *const _ as usize }, + 296usize, concat!( "Offset of field: ", - stringify!(pthread_barrier_t), + stringify!(__darwin_i386_float_state), "::", - stringify!(__size) + stringify!(__fpu_rsrv4) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).__align as *const _ as usize }, - 0usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_float_state>())).__fpu_reserved1 as *const _ as usize }, + 520usize, concat!( "Offset of field: ", - stringify!(pthread_barrier_t), + stringify!(__darwin_i386_float_state), "::", - stringify!(__align) + stringify!(__fpu_reserved1) ) ); } #[repr(C)] -#[derive(Copy, Clone)] -pub union pthread_barrierattr_t { - pub __size: [::std::os::raw::c_char; 4usize], - pub __align: ::std::os::raw::c_int, +#[derive(Debug, Copy, Clone)] +pub struct __darwin_i386_avx_state { + pub __fpu_reserved: [::std::os::raw::c_int; 2usize], + pub __fpu_fcw: __darwin_fp_control, + pub __fpu_fsw: __darwin_fp_status, + pub __fpu_ftw: __uint8_t, + pub __fpu_rsrv1: __uint8_t, + pub __fpu_fop: __uint16_t, + pub __fpu_ip: __uint32_t, + pub __fpu_cs: __uint16_t, + pub __fpu_rsrv2: __uint16_t, + pub __fpu_dp: __uint32_t, + pub __fpu_ds: __uint16_t, + pub __fpu_rsrv3: __uint16_t, + pub __fpu_mxcsr: __uint32_t, + pub __fpu_mxcsrmask: __uint32_t, + pub __fpu_stmm0: __darwin_mmst_reg, + pub __fpu_stmm1: __darwin_mmst_reg, + pub __fpu_stmm2: __darwin_mmst_reg, + pub __fpu_stmm3: __darwin_mmst_reg, + pub __fpu_stmm4: __darwin_mmst_reg, + pub __fpu_stmm5: __darwin_mmst_reg, + pub __fpu_stmm6: __darwin_mmst_reg, + pub __fpu_stmm7: __darwin_mmst_reg, + pub __fpu_xmm0: __darwin_xmm_reg, + pub __fpu_xmm1: __darwin_xmm_reg, + pub __fpu_xmm2: __darwin_xmm_reg, + pub __fpu_xmm3: __darwin_xmm_reg, + pub __fpu_xmm4: __darwin_xmm_reg, + pub __fpu_xmm5: __darwin_xmm_reg, + pub __fpu_xmm6: __darwin_xmm_reg, + pub __fpu_xmm7: __darwin_xmm_reg, + pub __fpu_rsrv4: [::std::os::raw::c_char; 224usize], + pub __fpu_reserved1: ::std::os::raw::c_int, + pub __avx_reserved1: [::std::os::raw::c_char; 64usize], + pub __fpu_ymmh0: __darwin_xmm_reg, + pub __fpu_ymmh1: __darwin_xmm_reg, + pub __fpu_ymmh2: __darwin_xmm_reg, + pub __fpu_ymmh3: __darwin_xmm_reg, + pub __fpu_ymmh4: __darwin_xmm_reg, + pub __fpu_ymmh5: __darwin_xmm_reg, + pub __fpu_ymmh6: __darwin_xmm_reg, + pub __fpu_ymmh7: __darwin_xmm_reg, } #[test] -fn bindgen_test_layout_pthread_barrierattr_t() { +fn bindgen_test_layout___darwin_i386_avx_state() { assert_eq!( - ::std::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(pthread_barrierattr_t)) + ::std::mem::size_of::<__darwin_i386_avx_state>(), + 716usize, + concat!("Size of: ", stringify!(__darwin_i386_avx_state)) ); assert_eq!( - ::std::mem::align_of::(), + ::std::mem::align_of::<__darwin_i386_avx_state>(), 4usize, - concat!("Alignment of ", stringify!(pthread_barrierattr_t)) + concat!("Alignment of ", stringify!(__darwin_i386_avx_state)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).__size as *const _ as usize }, + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_reserved as *const _ as usize }, 0usize, concat!( "Offset of field: ", - stringify!(pthread_barrierattr_t), + stringify!(__darwin_i386_avx_state), "::", - stringify!(__size) + stringify!(__fpu_reserved) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).__align as *const _ as usize }, - 0usize, + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_fcw as *const _ as usize }, + 8usize, concat!( "Offset of field: ", - stringify!(pthread_barrierattr_t), + stringify!(__darwin_i386_avx_state), "::", - stringify!(__align) + stringify!(__fpu_fcw) ) ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_fsw as *const _ as usize }, + 10usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_fsw) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_ftw as *const _ as usize }, + 12usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_ftw) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_rsrv1 as *const _ as usize }, + 13usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_rsrv1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_fop as *const _ as usize }, + 14usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_fop) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_ip as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_ip) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_cs as *const _ as usize }, + 20usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_cs) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_rsrv2 as *const _ as usize }, + 22usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_rsrv2) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_dp as *const _ as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_dp) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_ds as *const _ as usize }, + 28usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_ds) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_rsrv3 as *const _ as usize }, + 30usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_rsrv3) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_mxcsr as *const _ as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_mxcsr) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_mxcsrmask as *const _ as usize }, + 36usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_mxcsrmask) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_stmm0 as *const _ as usize }, + 40usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_stmm0) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_stmm1 as *const _ as usize }, + 56usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_stmm1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_stmm2 as *const _ as usize }, + 72usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_stmm2) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_stmm3 as *const _ as usize }, + 88usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_stmm3) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_stmm4 as *const _ as usize }, + 104usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_stmm4) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_stmm5 as *const _ as usize }, + 120usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_stmm5) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_stmm6 as *const _ as usize }, + 136usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_stmm6) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_stmm7 as *const _ as usize }, + 152usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_stmm7) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_xmm0 as *const _ as usize }, + 168usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_xmm0) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_xmm1 as *const _ as usize }, + 184usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_xmm1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_xmm2 as *const _ as usize }, + 200usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_xmm2) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_xmm3 as *const _ as usize }, + 216usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_xmm3) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_xmm4 as *const _ as usize }, + 232usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_xmm4) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_xmm5 as *const _ as usize }, + 248usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_xmm5) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_xmm6 as *const _ as usize }, + 264usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_xmm6) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_xmm7 as *const _ as usize }, + 280usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_xmm7) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_rsrv4 as *const _ as usize }, + 296usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_rsrv4) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_reserved1 as *const _ as usize }, + 520usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_reserved1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__avx_reserved1 as *const _ as usize }, + 524usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__avx_reserved1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_ymmh0 as *const _ as usize }, + 588usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_ymmh0) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_ymmh1 as *const _ as usize }, + 604usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_ymmh1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_ymmh2 as *const _ as usize }, + 620usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_ymmh2) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_ymmh3 as *const _ as usize }, + 636usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_ymmh3) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_ymmh4 as *const _ as usize }, + 652usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_ymmh4) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_ymmh5 as *const _ as usize }, + 668usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_ymmh5) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_ymmh6 as *const _ as usize }, + 684usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_ymmh6) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx_state>())).__fpu_ymmh7 as *const _ as usize }, + 700usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx_state), + "::", + stringify!(__fpu_ymmh7) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_i386_avx512_state { + pub __fpu_reserved: [::std::os::raw::c_int; 2usize], + pub __fpu_fcw: __darwin_fp_control, + pub __fpu_fsw: __darwin_fp_status, + pub __fpu_ftw: __uint8_t, + pub __fpu_rsrv1: __uint8_t, + pub __fpu_fop: __uint16_t, + pub __fpu_ip: __uint32_t, + pub __fpu_cs: __uint16_t, + pub __fpu_rsrv2: __uint16_t, + pub __fpu_dp: __uint32_t, + pub __fpu_ds: __uint16_t, + pub __fpu_rsrv3: __uint16_t, + pub __fpu_mxcsr: __uint32_t, + pub __fpu_mxcsrmask: __uint32_t, + pub __fpu_stmm0: __darwin_mmst_reg, + pub __fpu_stmm1: __darwin_mmst_reg, + pub __fpu_stmm2: __darwin_mmst_reg, + pub __fpu_stmm3: __darwin_mmst_reg, + pub __fpu_stmm4: __darwin_mmst_reg, + pub __fpu_stmm5: __darwin_mmst_reg, + pub __fpu_stmm6: __darwin_mmst_reg, + pub __fpu_stmm7: __darwin_mmst_reg, + pub __fpu_xmm0: __darwin_xmm_reg, + pub __fpu_xmm1: __darwin_xmm_reg, + pub __fpu_xmm2: __darwin_xmm_reg, + pub __fpu_xmm3: __darwin_xmm_reg, + pub __fpu_xmm4: __darwin_xmm_reg, + pub __fpu_xmm5: __darwin_xmm_reg, + pub __fpu_xmm6: __darwin_xmm_reg, + pub __fpu_xmm7: __darwin_xmm_reg, + pub __fpu_rsrv4: [::std::os::raw::c_char; 224usize], + pub __fpu_reserved1: ::std::os::raw::c_int, + pub __avx_reserved1: [::std::os::raw::c_char; 64usize], + pub __fpu_ymmh0: __darwin_xmm_reg, + pub __fpu_ymmh1: __darwin_xmm_reg, + pub __fpu_ymmh2: __darwin_xmm_reg, + pub __fpu_ymmh3: __darwin_xmm_reg, + pub __fpu_ymmh4: __darwin_xmm_reg, + pub __fpu_ymmh5: __darwin_xmm_reg, + pub __fpu_ymmh6: __darwin_xmm_reg, + pub __fpu_ymmh7: __darwin_xmm_reg, + pub __fpu_k0: __darwin_opmask_reg, + pub __fpu_k1: __darwin_opmask_reg, + pub __fpu_k2: __darwin_opmask_reg, + pub __fpu_k3: __darwin_opmask_reg, + pub __fpu_k4: __darwin_opmask_reg, + pub __fpu_k5: __darwin_opmask_reg, + pub __fpu_k6: __darwin_opmask_reg, + pub __fpu_k7: __darwin_opmask_reg, + pub __fpu_zmmh0: __darwin_ymm_reg, + pub __fpu_zmmh1: __darwin_ymm_reg, + pub __fpu_zmmh2: __darwin_ymm_reg, + pub __fpu_zmmh3: __darwin_ymm_reg, + pub __fpu_zmmh4: __darwin_ymm_reg, + pub __fpu_zmmh5: __darwin_ymm_reg, + pub __fpu_zmmh6: __darwin_ymm_reg, + pub __fpu_zmmh7: __darwin_ymm_reg, +} +#[test] +fn bindgen_test_layout___darwin_i386_avx512_state() { + assert_eq!( + ::std::mem::size_of::<__darwin_i386_avx512_state>(), + 1036usize, + concat!("Size of: ", stringify!(__darwin_i386_avx512_state)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_i386_avx512_state>(), + 4usize, + concat!("Alignment of ", stringify!(__darwin_i386_avx512_state)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_reserved as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_reserved) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_fcw as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_fcw) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_fsw as *const _ as usize }, + 10usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_fsw) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_ftw as *const _ as usize }, + 12usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_ftw) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_rsrv1 as *const _ as usize }, + 13usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_rsrv1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_fop as *const _ as usize }, + 14usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_fop) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_ip as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_ip) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_cs as *const _ as usize }, + 20usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_cs) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_rsrv2 as *const _ as usize }, + 22usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_rsrv2) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_dp as *const _ as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_dp) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_ds as *const _ as usize }, + 28usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_ds) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_rsrv3 as *const _ as usize }, + 30usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_rsrv3) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_mxcsr as *const _ as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_mxcsr) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_mxcsrmask as *const _ as usize }, + 36usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_mxcsrmask) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_stmm0 as *const _ as usize }, + 40usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_stmm0) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_stmm1 as *const _ as usize }, + 56usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_stmm1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_stmm2 as *const _ as usize }, + 72usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_stmm2) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_stmm3 as *const _ as usize }, + 88usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_stmm3) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_stmm4 as *const _ as usize }, + 104usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_stmm4) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_stmm5 as *const _ as usize }, + 120usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_stmm5) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_stmm6 as *const _ as usize }, + 136usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_stmm6) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_stmm7 as *const _ as usize }, + 152usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_stmm7) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_xmm0 as *const _ as usize }, + 168usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_xmm0) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_xmm1 as *const _ as usize }, + 184usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_xmm1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_xmm2 as *const _ as usize }, + 200usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_xmm2) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_xmm3 as *const _ as usize }, + 216usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_xmm3) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_xmm4 as *const _ as usize }, + 232usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_xmm4) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_xmm5 as *const _ as usize }, + 248usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_xmm5) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_xmm6 as *const _ as usize }, + 264usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_xmm6) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_xmm7 as *const _ as usize }, + 280usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_xmm7) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_rsrv4 as *const _ as usize }, + 296usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_rsrv4) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_reserved1 as *const _ as usize }, + 520usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_reserved1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__avx_reserved1 as *const _ as usize }, + 524usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__avx_reserved1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_ymmh0 as *const _ as usize }, + 588usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_ymmh0) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_ymmh1 as *const _ as usize }, + 604usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_ymmh1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_ymmh2 as *const _ as usize }, + 620usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_ymmh2) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_ymmh3 as *const _ as usize }, + 636usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_ymmh3) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_ymmh4 as *const _ as usize }, + 652usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_ymmh4) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_ymmh5 as *const _ as usize }, + 668usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_ymmh5) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_ymmh6 as *const _ as usize }, + 684usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_ymmh6) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_ymmh7 as *const _ as usize }, + 700usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_ymmh7) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_k0 as *const _ as usize }, + 716usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_k0) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_k1 as *const _ as usize }, + 724usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_k1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_k2 as *const _ as usize }, + 732usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_k2) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_k3 as *const _ as usize }, + 740usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_k3) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_k4 as *const _ as usize }, + 748usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_k4) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_k5 as *const _ as usize }, + 756usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_k5) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_k6 as *const _ as usize }, + 764usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_k6) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_k7 as *const _ as usize }, + 772usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_k7) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_zmmh0 as *const _ as usize }, + 780usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_zmmh0) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_zmmh1 as *const _ as usize }, + 812usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_zmmh1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_zmmh2 as *const _ as usize }, + 844usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_zmmh2) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_zmmh3 as *const _ as usize }, + 876usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_zmmh3) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_zmmh4 as *const _ as usize }, + 908usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_zmmh4) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_zmmh5 as *const _ as usize }, + 940usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_zmmh5) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_zmmh6 as *const _ as usize }, + 972usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_zmmh6) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_avx512_state>())).__fpu_zmmh7 as *const _ as usize }, + 1004usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_avx512_state), + "::", + stringify!(__fpu_zmmh7) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_i386_exception_state { + pub __trapno: __uint16_t, + pub __cpu: __uint16_t, + pub __err: __uint32_t, + pub __faultvaddr: __uint32_t, +} +#[test] +fn bindgen_test_layout___darwin_i386_exception_state() { + assert_eq!( + ::std::mem::size_of::<__darwin_i386_exception_state>(), + 12usize, + concat!("Size of: ", stringify!(__darwin_i386_exception_state)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_i386_exception_state>(), + 4usize, + concat!("Alignment of ", stringify!(__darwin_i386_exception_state)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_exception_state>())).__trapno as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_exception_state), + "::", + stringify!(__trapno) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_exception_state>())).__cpu as *const _ as usize }, + 2usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_exception_state), + "::", + stringify!(__cpu) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_exception_state>())).__err as *const _ as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_exception_state), + "::", + stringify!(__err) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_i386_exception_state>())).__faultvaddr as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(__darwin_i386_exception_state), + "::", + stringify!(__faultvaddr) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_x86_debug_state32 { + pub __dr0: ::std::os::raw::c_uint, + pub __dr1: ::std::os::raw::c_uint, + pub __dr2: ::std::os::raw::c_uint, + pub __dr3: ::std::os::raw::c_uint, + pub __dr4: ::std::os::raw::c_uint, + pub __dr5: ::std::os::raw::c_uint, + pub __dr6: ::std::os::raw::c_uint, + pub __dr7: ::std::os::raw::c_uint, +} +#[test] +fn bindgen_test_layout___darwin_x86_debug_state32() { + assert_eq!( + ::std::mem::size_of::<__darwin_x86_debug_state32>(), + 32usize, + concat!("Size of: ", stringify!(__darwin_x86_debug_state32)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_x86_debug_state32>(), + 4usize, + concat!("Alignment of ", stringify!(__darwin_x86_debug_state32)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_debug_state32>())).__dr0 as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_debug_state32), + "::", + stringify!(__dr0) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_debug_state32>())).__dr1 as *const _ as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_debug_state32), + "::", + stringify!(__dr1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_debug_state32>())).__dr2 as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_debug_state32), + "::", + stringify!(__dr2) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_debug_state32>())).__dr3 as *const _ as usize }, + 12usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_debug_state32), + "::", + stringify!(__dr3) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_debug_state32>())).__dr4 as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_debug_state32), + "::", + stringify!(__dr4) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_debug_state32>())).__dr5 as *const _ as usize }, + 20usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_debug_state32), + "::", + stringify!(__dr5) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_debug_state32>())).__dr6 as *const _ as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_debug_state32), + "::", + stringify!(__dr6) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_debug_state32>())).__dr7 as *const _ as usize }, + 28usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_debug_state32), + "::", + stringify!(__dr7) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __x86_instruction_state { + pub __insn_stream_valid_bytes: ::std::os::raw::c_int, + pub __insn_offset: ::std::os::raw::c_int, + pub __out_of_synch: ::std::os::raw::c_int, + pub __insn_bytes: [__uint8_t; 2380usize], + pub __insn_cacheline: [__uint8_t; 64usize], +} +#[test] +fn bindgen_test_layout___x86_instruction_state() { + assert_eq!( + ::std::mem::size_of::<__x86_instruction_state>(), + 2456usize, + concat!("Size of: ", stringify!(__x86_instruction_state)) + ); + assert_eq!( + ::std::mem::align_of::<__x86_instruction_state>(), + 4usize, + concat!("Alignment of ", stringify!(__x86_instruction_state)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__x86_instruction_state>())).__insn_stream_valid_bytes as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__x86_instruction_state), + "::", + stringify!(__insn_stream_valid_bytes) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__x86_instruction_state>())).__insn_offset as *const _ as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(__x86_instruction_state), + "::", + stringify!(__insn_offset) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__x86_instruction_state>())).__out_of_synch as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(__x86_instruction_state), + "::", + stringify!(__out_of_synch) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__x86_instruction_state>())).__insn_bytes as *const _ as usize }, + 12usize, + concat!( + "Offset of field: ", + stringify!(__x86_instruction_state), + "::", + stringify!(__insn_bytes) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__x86_instruction_state>())).__insn_cacheline as *const _ as usize }, + 2392usize, + concat!( + "Offset of field: ", + stringify!(__x86_instruction_state), + "::", + stringify!(__insn_cacheline) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __last_branch_record { + pub __from_ip: __uint64_t, + pub __to_ip: __uint64_t, + pub _bitfield_align_1: [u16; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub __bindgen_padding_0: u32, +} +#[test] +fn bindgen_test_layout___last_branch_record() { + assert_eq!( + ::std::mem::size_of::<__last_branch_record>(), + 24usize, + concat!("Size of: ", stringify!(__last_branch_record)) + ); + assert_eq!( + ::std::mem::align_of::<__last_branch_record>(), + 8usize, + concat!("Alignment of ", stringify!(__last_branch_record)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__last_branch_record>())).__from_ip as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__last_branch_record), + "::", + stringify!(__from_ip) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__last_branch_record>())).__to_ip as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(__last_branch_record), + "::", + stringify!(__to_ip) + ) + ); +} +impl __last_branch_record { + #[inline] + pub fn __mispredict(&self) -> __uint32_t { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set___mispredict(&mut self, val: __uint32_t) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn __tsx_abort(&self) -> __uint32_t { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set___tsx_abort(&mut self, val: __uint32_t) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn __in_tsx(&self) -> __uint32_t { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) } + } + #[inline] + pub fn set___in_tsx(&mut self, val: __uint32_t) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 1u8, val as u64) + } + } + #[inline] + pub fn __cycle_count(&self) -> __uint32_t { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 16u8) as u32) } + } + #[inline] + pub fn set___cycle_count(&mut self, val: __uint32_t) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(3usize, 16u8, val as u64) + } + } + #[inline] + pub fn __reserved(&self) -> __uint32_t { + unsafe { ::std::mem::transmute(self._bitfield_1.get(19usize, 13u8) as u32) } + } + #[inline] + pub fn set___reserved(&mut self, val: __uint32_t) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(19usize, 13u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + __mispredict: __uint32_t, + __tsx_abort: __uint32_t, + __in_tsx: __uint32_t, + __cycle_count: __uint32_t, + __reserved: __uint32_t, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let __mispredict: u32 = unsafe { ::std::mem::transmute(__mispredict) }; + __mispredict as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let __tsx_abort: u32 = unsafe { ::std::mem::transmute(__tsx_abort) }; + __tsx_abort as u64 + }); + __bindgen_bitfield_unit.set(2usize, 1u8, { + let __in_tsx: u32 = unsafe { ::std::mem::transmute(__in_tsx) }; + __in_tsx as u64 + }); + __bindgen_bitfield_unit.set(3usize, 16u8, { + let __cycle_count: u32 = unsafe { ::std::mem::transmute(__cycle_count) }; + __cycle_count as u64 + }); + __bindgen_bitfield_unit.set(19usize, 13u8, { + let __reserved: u32 = unsafe { ::std::mem::transmute(__reserved) }; + __reserved as u64 + }); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __last_branch_state { + pub __lbr_count: ::std::os::raw::c_int, + pub _bitfield_align_1: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub __lbrs: [__last_branch_record; 32usize], +} +#[test] +fn bindgen_test_layout___last_branch_state() { + assert_eq!( + ::std::mem::size_of::<__last_branch_state>(), + 776usize, + concat!("Size of: ", stringify!(__last_branch_state)) + ); + assert_eq!( + ::std::mem::align_of::<__last_branch_state>(), + 8usize, + concat!("Alignment of ", stringify!(__last_branch_state)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__last_branch_state>())).__lbr_count as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__last_branch_state), + "::", + stringify!(__lbr_count) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__last_branch_state>())).__lbrs as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(__last_branch_state), + "::", + stringify!(__lbrs) + ) + ); +} +impl __last_branch_state { + #[inline] + pub fn __lbr_supported_tsx(&self) -> __uint32_t { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } + } + #[inline] + pub fn set___lbr_supported_tsx(&mut self, val: __uint32_t) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub fn __lbr_supported_cycle_count(&self) -> __uint32_t { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } + } + #[inline] + pub fn set___lbr_supported_cycle_count(&mut self, val: __uint32_t) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 1u8, val as u64) + } + } + #[inline] + pub fn __reserved(&self) -> __uint32_t { + unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 30u8) as u32) } + } + #[inline] + pub fn set___reserved(&mut self, val: __uint32_t) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(2usize, 30u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + __lbr_supported_tsx: __uint32_t, + __lbr_supported_cycle_count: __uint32_t, + __reserved: __uint32_t, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 1u8, { + let __lbr_supported_tsx: u32 = unsafe { ::std::mem::transmute(__lbr_supported_tsx) }; + __lbr_supported_tsx as u64 + }); + __bindgen_bitfield_unit.set(1usize, 1u8, { + let __lbr_supported_cycle_count: u32 = unsafe { ::std::mem::transmute(__lbr_supported_cycle_count) }; + __lbr_supported_cycle_count as u64 + }); + __bindgen_bitfield_unit.set(2usize, 30u8, { + let __reserved: u32 = unsafe { ::std::mem::transmute(__reserved) }; + __reserved as u64 + }); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __x86_pagein_state { + pub __pagein_error: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout___x86_pagein_state() { + assert_eq!( + ::std::mem::size_of::<__x86_pagein_state>(), + 4usize, + concat!("Size of: ", stringify!(__x86_pagein_state)) + ); + assert_eq!( + ::std::mem::align_of::<__x86_pagein_state>(), + 4usize, + concat!("Alignment of ", stringify!(__x86_pagein_state)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__x86_pagein_state>())).__pagein_error as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__x86_pagein_state), + "::", + stringify!(__pagein_error) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_x86_thread_state64 { + pub __rax: __uint64_t, + pub __rbx: __uint64_t, + pub __rcx: __uint64_t, + pub __rdx: __uint64_t, + pub __rdi: __uint64_t, + pub __rsi: __uint64_t, + pub __rbp: __uint64_t, + pub __rsp: __uint64_t, + pub __r8: __uint64_t, + pub __r9: __uint64_t, + pub __r10: __uint64_t, + pub __r11: __uint64_t, + pub __r12: __uint64_t, + pub __r13: __uint64_t, + pub __r14: __uint64_t, + pub __r15: __uint64_t, + pub __rip: __uint64_t, + pub __rflags: __uint64_t, + pub __cs: __uint64_t, + pub __fs: __uint64_t, + pub __gs: __uint64_t, +} +#[test] +fn bindgen_test_layout___darwin_x86_thread_state64() { + assert_eq!( + ::std::mem::size_of::<__darwin_x86_thread_state64>(), + 168usize, + concat!("Size of: ", stringify!(__darwin_x86_thread_state64)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_x86_thread_state64>(), + 8usize, + concat!("Alignment of ", stringify!(__darwin_x86_thread_state64)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_thread_state64>())).__rax as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_thread_state64), + "::", + stringify!(__rax) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_thread_state64>())).__rbx as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_thread_state64), + "::", + stringify!(__rbx) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_thread_state64>())).__rcx as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_thread_state64), + "::", + stringify!(__rcx) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_thread_state64>())).__rdx as *const _ as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_thread_state64), + "::", + stringify!(__rdx) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_thread_state64>())).__rdi as *const _ as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_thread_state64), + "::", + stringify!(__rdi) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_thread_state64>())).__rsi as *const _ as usize }, + 40usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_thread_state64), + "::", + stringify!(__rsi) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_thread_state64>())).__rbp as *const _ as usize }, + 48usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_thread_state64), + "::", + stringify!(__rbp) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_thread_state64>())).__rsp as *const _ as usize }, + 56usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_thread_state64), + "::", + stringify!(__rsp) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_thread_state64>())).__r8 as *const _ as usize }, + 64usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_thread_state64), + "::", + stringify!(__r8) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_thread_state64>())).__r9 as *const _ as usize }, + 72usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_thread_state64), + "::", + stringify!(__r9) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_thread_state64>())).__r10 as *const _ as usize }, + 80usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_thread_state64), + "::", + stringify!(__r10) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_thread_state64>())).__r11 as *const _ as usize }, + 88usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_thread_state64), + "::", + stringify!(__r11) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_thread_state64>())).__r12 as *const _ as usize }, + 96usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_thread_state64), + "::", + stringify!(__r12) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_thread_state64>())).__r13 as *const _ as usize }, + 104usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_thread_state64), + "::", + stringify!(__r13) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_thread_state64>())).__r14 as *const _ as usize }, + 112usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_thread_state64), + "::", + stringify!(__r14) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_thread_state64>())).__r15 as *const _ as usize }, + 120usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_thread_state64), + "::", + stringify!(__r15) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_thread_state64>())).__rip as *const _ as usize }, + 128usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_thread_state64), + "::", + stringify!(__rip) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_thread_state64>())).__rflags as *const _ as usize }, + 136usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_thread_state64), + "::", + stringify!(__rflags) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_thread_state64>())).__cs as *const _ as usize }, + 144usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_thread_state64), + "::", + stringify!(__cs) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_thread_state64>())).__fs as *const _ as usize }, + 152usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_thread_state64), + "::", + stringify!(__fs) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_thread_state64>())).__gs as *const _ as usize }, + 160usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_thread_state64), + "::", + stringify!(__gs) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_x86_thread_full_state64 { + pub __ss64: __darwin_x86_thread_state64, + pub __ds: __uint64_t, + pub __es: __uint64_t, + pub __ss: __uint64_t, + pub __gsbase: __uint64_t, +} +#[test] +fn bindgen_test_layout___darwin_x86_thread_full_state64() { + assert_eq!( + ::std::mem::size_of::<__darwin_x86_thread_full_state64>(), + 200usize, + concat!("Size of: ", stringify!(__darwin_x86_thread_full_state64)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_x86_thread_full_state64>(), + 8usize, + concat!("Alignment of ", stringify!(__darwin_x86_thread_full_state64)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_thread_full_state64>())).__ss64 as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_thread_full_state64), + "::", + stringify!(__ss64) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_thread_full_state64>())).__ds as *const _ as usize }, + 168usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_thread_full_state64), + "::", + stringify!(__ds) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_thread_full_state64>())).__es as *const _ as usize }, + 176usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_thread_full_state64), + "::", + stringify!(__es) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_thread_full_state64>())).__ss as *const _ as usize }, + 184usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_thread_full_state64), + "::", + stringify!(__ss) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_thread_full_state64>())).__gsbase as *const _ as usize }, + 192usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_thread_full_state64), + "::", + stringify!(__gsbase) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_x86_float_state64 { + pub __fpu_reserved: [::std::os::raw::c_int; 2usize], + pub __fpu_fcw: __darwin_fp_control, + pub __fpu_fsw: __darwin_fp_status, + pub __fpu_ftw: __uint8_t, + pub __fpu_rsrv1: __uint8_t, + pub __fpu_fop: __uint16_t, + pub __fpu_ip: __uint32_t, + pub __fpu_cs: __uint16_t, + pub __fpu_rsrv2: __uint16_t, + pub __fpu_dp: __uint32_t, + pub __fpu_ds: __uint16_t, + pub __fpu_rsrv3: __uint16_t, + pub __fpu_mxcsr: __uint32_t, + pub __fpu_mxcsrmask: __uint32_t, + pub __fpu_stmm0: __darwin_mmst_reg, + pub __fpu_stmm1: __darwin_mmst_reg, + pub __fpu_stmm2: __darwin_mmst_reg, + pub __fpu_stmm3: __darwin_mmst_reg, + pub __fpu_stmm4: __darwin_mmst_reg, + pub __fpu_stmm5: __darwin_mmst_reg, + pub __fpu_stmm6: __darwin_mmst_reg, + pub __fpu_stmm7: __darwin_mmst_reg, + pub __fpu_xmm0: __darwin_xmm_reg, + pub __fpu_xmm1: __darwin_xmm_reg, + pub __fpu_xmm2: __darwin_xmm_reg, + pub __fpu_xmm3: __darwin_xmm_reg, + pub __fpu_xmm4: __darwin_xmm_reg, + pub __fpu_xmm5: __darwin_xmm_reg, + pub __fpu_xmm6: __darwin_xmm_reg, + pub __fpu_xmm7: __darwin_xmm_reg, + pub __fpu_xmm8: __darwin_xmm_reg, + pub __fpu_xmm9: __darwin_xmm_reg, + pub __fpu_xmm10: __darwin_xmm_reg, + pub __fpu_xmm11: __darwin_xmm_reg, + pub __fpu_xmm12: __darwin_xmm_reg, + pub __fpu_xmm13: __darwin_xmm_reg, + pub __fpu_xmm14: __darwin_xmm_reg, + pub __fpu_xmm15: __darwin_xmm_reg, + pub __fpu_rsrv4: [::std::os::raw::c_char; 96usize], + pub __fpu_reserved1: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout___darwin_x86_float_state64() { + assert_eq!( + ::std::mem::size_of::<__darwin_x86_float_state64>(), + 524usize, + concat!("Size of: ", stringify!(__darwin_x86_float_state64)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_x86_float_state64>(), + 4usize, + concat!("Alignment of ", stringify!(__darwin_x86_float_state64)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_reserved as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_reserved) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_fcw as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_fcw) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_fsw as *const _ as usize }, + 10usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_fsw) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_ftw as *const _ as usize }, + 12usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_ftw) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_rsrv1 as *const _ as usize }, + 13usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_rsrv1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_fop as *const _ as usize }, + 14usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_fop) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_ip as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_ip) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_cs as *const _ as usize }, + 20usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_cs) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_rsrv2 as *const _ as usize }, + 22usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_rsrv2) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_dp as *const _ as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_dp) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_ds as *const _ as usize }, + 28usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_ds) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_rsrv3 as *const _ as usize }, + 30usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_rsrv3) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_mxcsr as *const _ as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_mxcsr) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_mxcsrmask as *const _ as usize }, + 36usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_mxcsrmask) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_stmm0 as *const _ as usize }, + 40usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_stmm0) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_stmm1 as *const _ as usize }, + 56usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_stmm1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_stmm2 as *const _ as usize }, + 72usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_stmm2) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_stmm3 as *const _ as usize }, + 88usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_stmm3) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_stmm4 as *const _ as usize }, + 104usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_stmm4) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_stmm5 as *const _ as usize }, + 120usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_stmm5) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_stmm6 as *const _ as usize }, + 136usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_stmm6) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_stmm7 as *const _ as usize }, + 152usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_stmm7) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_xmm0 as *const _ as usize }, + 168usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_xmm0) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_xmm1 as *const _ as usize }, + 184usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_xmm1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_xmm2 as *const _ as usize }, + 200usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_xmm2) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_xmm3 as *const _ as usize }, + 216usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_xmm3) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_xmm4 as *const _ as usize }, + 232usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_xmm4) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_xmm5 as *const _ as usize }, + 248usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_xmm5) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_xmm6 as *const _ as usize }, + 264usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_xmm6) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_xmm7 as *const _ as usize }, + 280usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_xmm7) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_xmm8 as *const _ as usize }, + 296usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_xmm8) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_xmm9 as *const _ as usize }, + 312usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_xmm9) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_xmm10 as *const _ as usize }, + 328usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_xmm10) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_xmm11 as *const _ as usize }, + 344usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_xmm11) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_xmm12 as *const _ as usize }, + 360usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_xmm12) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_xmm13 as *const _ as usize }, + 376usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_xmm13) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_xmm14 as *const _ as usize }, + 392usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_xmm14) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_xmm15 as *const _ as usize }, + 408usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_xmm15) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_rsrv4 as *const _ as usize }, + 424usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_rsrv4) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_float_state64>())).__fpu_reserved1 as *const _ as usize }, + 520usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_float_state64), + "::", + stringify!(__fpu_reserved1) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_x86_avx_state64 { + pub __fpu_reserved: [::std::os::raw::c_int; 2usize], + pub __fpu_fcw: __darwin_fp_control, + pub __fpu_fsw: __darwin_fp_status, + pub __fpu_ftw: __uint8_t, + pub __fpu_rsrv1: __uint8_t, + pub __fpu_fop: __uint16_t, + pub __fpu_ip: __uint32_t, + pub __fpu_cs: __uint16_t, + pub __fpu_rsrv2: __uint16_t, + pub __fpu_dp: __uint32_t, + pub __fpu_ds: __uint16_t, + pub __fpu_rsrv3: __uint16_t, + pub __fpu_mxcsr: __uint32_t, + pub __fpu_mxcsrmask: __uint32_t, + pub __fpu_stmm0: __darwin_mmst_reg, + pub __fpu_stmm1: __darwin_mmst_reg, + pub __fpu_stmm2: __darwin_mmst_reg, + pub __fpu_stmm3: __darwin_mmst_reg, + pub __fpu_stmm4: __darwin_mmst_reg, + pub __fpu_stmm5: __darwin_mmst_reg, + pub __fpu_stmm6: __darwin_mmst_reg, + pub __fpu_stmm7: __darwin_mmst_reg, + pub __fpu_xmm0: __darwin_xmm_reg, + pub __fpu_xmm1: __darwin_xmm_reg, + pub __fpu_xmm2: __darwin_xmm_reg, + pub __fpu_xmm3: __darwin_xmm_reg, + pub __fpu_xmm4: __darwin_xmm_reg, + pub __fpu_xmm5: __darwin_xmm_reg, + pub __fpu_xmm6: __darwin_xmm_reg, + pub __fpu_xmm7: __darwin_xmm_reg, + pub __fpu_xmm8: __darwin_xmm_reg, + pub __fpu_xmm9: __darwin_xmm_reg, + pub __fpu_xmm10: __darwin_xmm_reg, + pub __fpu_xmm11: __darwin_xmm_reg, + pub __fpu_xmm12: __darwin_xmm_reg, + pub __fpu_xmm13: __darwin_xmm_reg, + pub __fpu_xmm14: __darwin_xmm_reg, + pub __fpu_xmm15: __darwin_xmm_reg, + pub __fpu_rsrv4: [::std::os::raw::c_char; 96usize], + pub __fpu_reserved1: ::std::os::raw::c_int, + pub __avx_reserved1: [::std::os::raw::c_char; 64usize], + pub __fpu_ymmh0: __darwin_xmm_reg, + pub __fpu_ymmh1: __darwin_xmm_reg, + pub __fpu_ymmh2: __darwin_xmm_reg, + pub __fpu_ymmh3: __darwin_xmm_reg, + pub __fpu_ymmh4: __darwin_xmm_reg, + pub __fpu_ymmh5: __darwin_xmm_reg, + pub __fpu_ymmh6: __darwin_xmm_reg, + pub __fpu_ymmh7: __darwin_xmm_reg, + pub __fpu_ymmh8: __darwin_xmm_reg, + pub __fpu_ymmh9: __darwin_xmm_reg, + pub __fpu_ymmh10: __darwin_xmm_reg, + pub __fpu_ymmh11: __darwin_xmm_reg, + pub __fpu_ymmh12: __darwin_xmm_reg, + pub __fpu_ymmh13: __darwin_xmm_reg, + pub __fpu_ymmh14: __darwin_xmm_reg, + pub __fpu_ymmh15: __darwin_xmm_reg, +} +#[test] +fn bindgen_test_layout___darwin_x86_avx_state64() { + assert_eq!( + ::std::mem::size_of::<__darwin_x86_avx_state64>(), + 844usize, + concat!("Size of: ", stringify!(__darwin_x86_avx_state64)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_x86_avx_state64>(), + 4usize, + concat!("Alignment of ", stringify!(__darwin_x86_avx_state64)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_reserved as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_reserved) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_fcw as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_fcw) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_fsw as *const _ as usize }, + 10usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_fsw) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_ftw as *const _ as usize }, + 12usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_ftw) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_rsrv1 as *const _ as usize }, + 13usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_rsrv1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_fop as *const _ as usize }, + 14usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_fop) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_ip as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_ip) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_cs as *const _ as usize }, + 20usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_cs) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_rsrv2 as *const _ as usize }, + 22usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_rsrv2) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_dp as *const _ as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_dp) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_ds as *const _ as usize }, + 28usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_ds) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_rsrv3 as *const _ as usize }, + 30usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_rsrv3) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_mxcsr as *const _ as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_mxcsr) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_mxcsrmask as *const _ as usize }, + 36usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_mxcsrmask) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_stmm0 as *const _ as usize }, + 40usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_stmm0) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_stmm1 as *const _ as usize }, + 56usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_stmm1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_stmm2 as *const _ as usize }, + 72usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_stmm2) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_stmm3 as *const _ as usize }, + 88usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_stmm3) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_stmm4 as *const _ as usize }, + 104usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_stmm4) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_stmm5 as *const _ as usize }, + 120usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_stmm5) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_stmm6 as *const _ as usize }, + 136usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_stmm6) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_stmm7 as *const _ as usize }, + 152usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_stmm7) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_xmm0 as *const _ as usize }, + 168usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_xmm0) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_xmm1 as *const _ as usize }, + 184usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_xmm1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_xmm2 as *const _ as usize }, + 200usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_xmm2) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_xmm3 as *const _ as usize }, + 216usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_xmm3) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_xmm4 as *const _ as usize }, + 232usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_xmm4) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_xmm5 as *const _ as usize }, + 248usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_xmm5) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_xmm6 as *const _ as usize }, + 264usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_xmm6) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_xmm7 as *const _ as usize }, + 280usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_xmm7) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_xmm8 as *const _ as usize }, + 296usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_xmm8) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_xmm9 as *const _ as usize }, + 312usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_xmm9) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_xmm10 as *const _ as usize }, + 328usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_xmm10) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_xmm11 as *const _ as usize }, + 344usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_xmm11) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_xmm12 as *const _ as usize }, + 360usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_xmm12) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_xmm13 as *const _ as usize }, + 376usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_xmm13) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_xmm14 as *const _ as usize }, + 392usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_xmm14) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_xmm15 as *const _ as usize }, + 408usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_xmm15) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_rsrv4 as *const _ as usize }, + 424usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_rsrv4) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_reserved1 as *const _ as usize }, + 520usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_reserved1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__avx_reserved1 as *const _ as usize }, + 524usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__avx_reserved1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_ymmh0 as *const _ as usize }, + 588usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_ymmh0) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_ymmh1 as *const _ as usize }, + 604usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_ymmh1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_ymmh2 as *const _ as usize }, + 620usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_ymmh2) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_ymmh3 as *const _ as usize }, + 636usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_ymmh3) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_ymmh4 as *const _ as usize }, + 652usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_ymmh4) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_ymmh5 as *const _ as usize }, + 668usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_ymmh5) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_ymmh6 as *const _ as usize }, + 684usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_ymmh6) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_ymmh7 as *const _ as usize }, + 700usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_ymmh7) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_ymmh8 as *const _ as usize }, + 716usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_ymmh8) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_ymmh9 as *const _ as usize }, + 732usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_ymmh9) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_ymmh10 as *const _ as usize }, + 748usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_ymmh10) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_ymmh11 as *const _ as usize }, + 764usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_ymmh11) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_ymmh12 as *const _ as usize }, + 780usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_ymmh12) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_ymmh13 as *const _ as usize }, + 796usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_ymmh13) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_ymmh14 as *const _ as usize }, + 812usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_ymmh14) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx_state64>())).__fpu_ymmh15 as *const _ as usize }, + 828usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx_state64), + "::", + stringify!(__fpu_ymmh15) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_x86_avx512_state64 { + pub __fpu_reserved: [::std::os::raw::c_int; 2usize], + pub __fpu_fcw: __darwin_fp_control, + pub __fpu_fsw: __darwin_fp_status, + pub __fpu_ftw: __uint8_t, + pub __fpu_rsrv1: __uint8_t, + pub __fpu_fop: __uint16_t, + pub __fpu_ip: __uint32_t, + pub __fpu_cs: __uint16_t, + pub __fpu_rsrv2: __uint16_t, + pub __fpu_dp: __uint32_t, + pub __fpu_ds: __uint16_t, + pub __fpu_rsrv3: __uint16_t, + pub __fpu_mxcsr: __uint32_t, + pub __fpu_mxcsrmask: __uint32_t, + pub __fpu_stmm0: __darwin_mmst_reg, + pub __fpu_stmm1: __darwin_mmst_reg, + pub __fpu_stmm2: __darwin_mmst_reg, + pub __fpu_stmm3: __darwin_mmst_reg, + pub __fpu_stmm4: __darwin_mmst_reg, + pub __fpu_stmm5: __darwin_mmst_reg, + pub __fpu_stmm6: __darwin_mmst_reg, + pub __fpu_stmm7: __darwin_mmst_reg, + pub __fpu_xmm0: __darwin_xmm_reg, + pub __fpu_xmm1: __darwin_xmm_reg, + pub __fpu_xmm2: __darwin_xmm_reg, + pub __fpu_xmm3: __darwin_xmm_reg, + pub __fpu_xmm4: __darwin_xmm_reg, + pub __fpu_xmm5: __darwin_xmm_reg, + pub __fpu_xmm6: __darwin_xmm_reg, + pub __fpu_xmm7: __darwin_xmm_reg, + pub __fpu_xmm8: __darwin_xmm_reg, + pub __fpu_xmm9: __darwin_xmm_reg, + pub __fpu_xmm10: __darwin_xmm_reg, + pub __fpu_xmm11: __darwin_xmm_reg, + pub __fpu_xmm12: __darwin_xmm_reg, + pub __fpu_xmm13: __darwin_xmm_reg, + pub __fpu_xmm14: __darwin_xmm_reg, + pub __fpu_xmm15: __darwin_xmm_reg, + pub __fpu_rsrv4: [::std::os::raw::c_char; 96usize], + pub __fpu_reserved1: ::std::os::raw::c_int, + pub __avx_reserved1: [::std::os::raw::c_char; 64usize], + pub __fpu_ymmh0: __darwin_xmm_reg, + pub __fpu_ymmh1: __darwin_xmm_reg, + pub __fpu_ymmh2: __darwin_xmm_reg, + pub __fpu_ymmh3: __darwin_xmm_reg, + pub __fpu_ymmh4: __darwin_xmm_reg, + pub __fpu_ymmh5: __darwin_xmm_reg, + pub __fpu_ymmh6: __darwin_xmm_reg, + pub __fpu_ymmh7: __darwin_xmm_reg, + pub __fpu_ymmh8: __darwin_xmm_reg, + pub __fpu_ymmh9: __darwin_xmm_reg, + pub __fpu_ymmh10: __darwin_xmm_reg, + pub __fpu_ymmh11: __darwin_xmm_reg, + pub __fpu_ymmh12: __darwin_xmm_reg, + pub __fpu_ymmh13: __darwin_xmm_reg, + pub __fpu_ymmh14: __darwin_xmm_reg, + pub __fpu_ymmh15: __darwin_xmm_reg, + pub __fpu_k0: __darwin_opmask_reg, + pub __fpu_k1: __darwin_opmask_reg, + pub __fpu_k2: __darwin_opmask_reg, + pub __fpu_k3: __darwin_opmask_reg, + pub __fpu_k4: __darwin_opmask_reg, + pub __fpu_k5: __darwin_opmask_reg, + pub __fpu_k6: __darwin_opmask_reg, + pub __fpu_k7: __darwin_opmask_reg, + pub __fpu_zmmh0: __darwin_ymm_reg, + pub __fpu_zmmh1: __darwin_ymm_reg, + pub __fpu_zmmh2: __darwin_ymm_reg, + pub __fpu_zmmh3: __darwin_ymm_reg, + pub __fpu_zmmh4: __darwin_ymm_reg, + pub __fpu_zmmh5: __darwin_ymm_reg, + pub __fpu_zmmh6: __darwin_ymm_reg, + pub __fpu_zmmh7: __darwin_ymm_reg, + pub __fpu_zmmh8: __darwin_ymm_reg, + pub __fpu_zmmh9: __darwin_ymm_reg, + pub __fpu_zmmh10: __darwin_ymm_reg, + pub __fpu_zmmh11: __darwin_ymm_reg, + pub __fpu_zmmh12: __darwin_ymm_reg, + pub __fpu_zmmh13: __darwin_ymm_reg, + pub __fpu_zmmh14: __darwin_ymm_reg, + pub __fpu_zmmh15: __darwin_ymm_reg, + pub __fpu_zmm16: __darwin_zmm_reg, + pub __fpu_zmm17: __darwin_zmm_reg, + pub __fpu_zmm18: __darwin_zmm_reg, + pub __fpu_zmm19: __darwin_zmm_reg, + pub __fpu_zmm20: __darwin_zmm_reg, + pub __fpu_zmm21: __darwin_zmm_reg, + pub __fpu_zmm22: __darwin_zmm_reg, + pub __fpu_zmm23: __darwin_zmm_reg, + pub __fpu_zmm24: __darwin_zmm_reg, + pub __fpu_zmm25: __darwin_zmm_reg, + pub __fpu_zmm26: __darwin_zmm_reg, + pub __fpu_zmm27: __darwin_zmm_reg, + pub __fpu_zmm28: __darwin_zmm_reg, + pub __fpu_zmm29: __darwin_zmm_reg, + pub __fpu_zmm30: __darwin_zmm_reg, + pub __fpu_zmm31: __darwin_zmm_reg, +} +#[test] +fn bindgen_test_layout___darwin_x86_avx512_state64() { + assert_eq!( + ::std::mem::size_of::<__darwin_x86_avx512_state64>(), + 2444usize, + concat!("Size of: ", stringify!(__darwin_x86_avx512_state64)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_x86_avx512_state64>(), + 4usize, + concat!("Alignment of ", stringify!(__darwin_x86_avx512_state64)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_reserved as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_reserved) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_fcw as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_fcw) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_fsw as *const _ as usize }, + 10usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_fsw) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_ftw as *const _ as usize }, + 12usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_ftw) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_rsrv1 as *const _ as usize }, + 13usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_rsrv1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_fop as *const _ as usize }, + 14usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_fop) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_ip as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_ip) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_cs as *const _ as usize }, + 20usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_cs) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_rsrv2 as *const _ as usize }, + 22usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_rsrv2) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_dp as *const _ as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_dp) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_ds as *const _ as usize }, + 28usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_ds) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_rsrv3 as *const _ as usize }, + 30usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_rsrv3) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_mxcsr as *const _ as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_mxcsr) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_mxcsrmask as *const _ as usize }, + 36usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_mxcsrmask) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_stmm0 as *const _ as usize }, + 40usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_stmm0) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_stmm1 as *const _ as usize }, + 56usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_stmm1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_stmm2 as *const _ as usize }, + 72usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_stmm2) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_stmm3 as *const _ as usize }, + 88usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_stmm3) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_stmm4 as *const _ as usize }, + 104usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_stmm4) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_stmm5 as *const _ as usize }, + 120usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_stmm5) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_stmm6 as *const _ as usize }, + 136usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_stmm6) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_stmm7 as *const _ as usize }, + 152usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_stmm7) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_xmm0 as *const _ as usize }, + 168usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_xmm0) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_xmm1 as *const _ as usize }, + 184usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_xmm1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_xmm2 as *const _ as usize }, + 200usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_xmm2) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_xmm3 as *const _ as usize }, + 216usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_xmm3) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_xmm4 as *const _ as usize }, + 232usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_xmm4) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_xmm5 as *const _ as usize }, + 248usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_xmm5) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_xmm6 as *const _ as usize }, + 264usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_xmm6) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_xmm7 as *const _ as usize }, + 280usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_xmm7) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_xmm8 as *const _ as usize }, + 296usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_xmm8) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_xmm9 as *const _ as usize }, + 312usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_xmm9) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_xmm10 as *const _ as usize }, + 328usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_xmm10) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_xmm11 as *const _ as usize }, + 344usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_xmm11) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_xmm12 as *const _ as usize }, + 360usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_xmm12) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_xmm13 as *const _ as usize }, + 376usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_xmm13) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_xmm14 as *const _ as usize }, + 392usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_xmm14) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_xmm15 as *const _ as usize }, + 408usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_xmm15) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_rsrv4 as *const _ as usize }, + 424usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_rsrv4) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_reserved1 as *const _ as usize }, + 520usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_reserved1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__avx_reserved1 as *const _ as usize }, + 524usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__avx_reserved1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_ymmh0 as *const _ as usize }, + 588usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_ymmh0) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_ymmh1 as *const _ as usize }, + 604usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_ymmh1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_ymmh2 as *const _ as usize }, + 620usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_ymmh2) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_ymmh3 as *const _ as usize }, + 636usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_ymmh3) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_ymmh4 as *const _ as usize }, + 652usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_ymmh4) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_ymmh5 as *const _ as usize }, + 668usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_ymmh5) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_ymmh6 as *const _ as usize }, + 684usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_ymmh6) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_ymmh7 as *const _ as usize }, + 700usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_ymmh7) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_ymmh8 as *const _ as usize }, + 716usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_ymmh8) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_ymmh9 as *const _ as usize }, + 732usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_ymmh9) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_ymmh10 as *const _ as usize }, + 748usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_ymmh10) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_ymmh11 as *const _ as usize }, + 764usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_ymmh11) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_ymmh12 as *const _ as usize }, + 780usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_ymmh12) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_ymmh13 as *const _ as usize }, + 796usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_ymmh13) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_ymmh14 as *const _ as usize }, + 812usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_ymmh14) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_ymmh15 as *const _ as usize }, + 828usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_ymmh15) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_k0 as *const _ as usize }, + 844usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_k0) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_k1 as *const _ as usize }, + 852usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_k1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_k2 as *const _ as usize }, + 860usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_k2) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_k3 as *const _ as usize }, + 868usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_k3) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_k4 as *const _ as usize }, + 876usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_k4) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_k5 as *const _ as usize }, + 884usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_k5) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_k6 as *const _ as usize }, + 892usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_k6) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_k7 as *const _ as usize }, + 900usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_k7) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmmh0 as *const _ as usize }, + 908usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmmh0) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmmh1 as *const _ as usize }, + 940usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmmh1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmmh2 as *const _ as usize }, + 972usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmmh2) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmmh3 as *const _ as usize }, + 1004usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmmh3) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmmh4 as *const _ as usize }, + 1036usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmmh4) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmmh5 as *const _ as usize }, + 1068usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmmh5) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmmh6 as *const _ as usize }, + 1100usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmmh6) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmmh7 as *const _ as usize }, + 1132usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmmh7) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmmh8 as *const _ as usize }, + 1164usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmmh8) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmmh9 as *const _ as usize }, + 1196usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmmh9) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmmh10 as *const _ as usize }, + 1228usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmmh10) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmmh11 as *const _ as usize }, + 1260usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmmh11) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmmh12 as *const _ as usize }, + 1292usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmmh12) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmmh13 as *const _ as usize }, + 1324usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmmh13) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmmh14 as *const _ as usize }, + 1356usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmmh14) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmmh15 as *const _ as usize }, + 1388usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmmh15) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmm16 as *const _ as usize }, + 1420usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmm16) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmm17 as *const _ as usize }, + 1484usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmm17) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmm18 as *const _ as usize }, + 1548usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmm18) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmm19 as *const _ as usize }, + 1612usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmm19) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmm20 as *const _ as usize }, + 1676usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmm20) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmm21 as *const _ as usize }, + 1740usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmm21) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmm22 as *const _ as usize }, + 1804usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmm22) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmm23 as *const _ as usize }, + 1868usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmm23) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmm24 as *const _ as usize }, + 1932usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmm24) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmm25 as *const _ as usize }, + 1996usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmm25) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmm26 as *const _ as usize }, + 2060usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmm26) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmm27 as *const _ as usize }, + 2124usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmm27) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmm28 as *const _ as usize }, + 2188usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmm28) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmm29 as *const _ as usize }, + 2252usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmm29) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmm30 as *const _ as usize }, + 2316usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmm30) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_avx512_state64>())).__fpu_zmm31 as *const _ as usize }, + 2380usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_avx512_state64), + "::", + stringify!(__fpu_zmm31) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_x86_exception_state64 { + pub __trapno: __uint16_t, + pub __cpu: __uint16_t, + pub __err: __uint32_t, + pub __faultvaddr: __uint64_t, +} +#[test] +fn bindgen_test_layout___darwin_x86_exception_state64() { + assert_eq!( + ::std::mem::size_of::<__darwin_x86_exception_state64>(), + 16usize, + concat!("Size of: ", stringify!(__darwin_x86_exception_state64)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_x86_exception_state64>(), + 8usize, + concat!("Alignment of ", stringify!(__darwin_x86_exception_state64)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_exception_state64>())).__trapno as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_exception_state64), + "::", + stringify!(__trapno) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_exception_state64>())).__cpu as *const _ as usize }, + 2usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_exception_state64), + "::", + stringify!(__cpu) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_exception_state64>())).__err as *const _ as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_exception_state64), + "::", + stringify!(__err) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_exception_state64>())).__faultvaddr as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_exception_state64), + "::", + stringify!(__faultvaddr) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_x86_debug_state64 { + pub __dr0: __uint64_t, + pub __dr1: __uint64_t, + pub __dr2: __uint64_t, + pub __dr3: __uint64_t, + pub __dr4: __uint64_t, + pub __dr5: __uint64_t, + pub __dr6: __uint64_t, + pub __dr7: __uint64_t, +} +#[test] +fn bindgen_test_layout___darwin_x86_debug_state64() { + assert_eq!( + ::std::mem::size_of::<__darwin_x86_debug_state64>(), + 64usize, + concat!("Size of: ", stringify!(__darwin_x86_debug_state64)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_x86_debug_state64>(), + 8usize, + concat!("Alignment of ", stringify!(__darwin_x86_debug_state64)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_debug_state64>())).__dr0 as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_debug_state64), + "::", + stringify!(__dr0) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_debug_state64>())).__dr1 as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_debug_state64), + "::", + stringify!(__dr1) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_debug_state64>())).__dr2 as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_debug_state64), + "::", + stringify!(__dr2) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_debug_state64>())).__dr3 as *const _ as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_debug_state64), + "::", + stringify!(__dr3) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_debug_state64>())).__dr4 as *const _ as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_debug_state64), + "::", + stringify!(__dr4) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_debug_state64>())).__dr5 as *const _ as usize }, + 40usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_debug_state64), + "::", + stringify!(__dr5) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_debug_state64>())).__dr6 as *const _ as usize }, + 48usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_debug_state64), + "::", + stringify!(__dr6) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_debug_state64>())).__dr7 as *const _ as usize }, + 56usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_debug_state64), + "::", + stringify!(__dr7) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_x86_cpmu_state64 { + pub __ctrs: [__uint64_t; 16usize], +} +#[test] +fn bindgen_test_layout___darwin_x86_cpmu_state64() { + assert_eq!( + ::std::mem::size_of::<__darwin_x86_cpmu_state64>(), + 128usize, + concat!("Size of: ", stringify!(__darwin_x86_cpmu_state64)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_x86_cpmu_state64>(), + 8usize, + concat!("Alignment of ", stringify!(__darwin_x86_cpmu_state64)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_x86_cpmu_state64>())).__ctrs as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__darwin_x86_cpmu_state64), + "::", + stringify!(__ctrs) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_mcontext32 { + pub __es: __darwin_i386_exception_state, + pub __ss: __darwin_i386_thread_state, + pub __fs: __darwin_i386_float_state, +} +#[test] +fn bindgen_test_layout___darwin_mcontext32() { + assert_eq!( + ::std::mem::size_of::<__darwin_mcontext32>(), + 600usize, + concat!("Size of: ", stringify!(__darwin_mcontext32)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_mcontext32>(), + 4usize, + concat!("Alignment of ", stringify!(__darwin_mcontext32)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext32>())).__es as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext32), + "::", + stringify!(__es) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext32>())).__ss as *const _ as usize }, + 12usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext32), + "::", + stringify!(__ss) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext32>())).__fs as *const _ as usize }, + 76usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext32), + "::", + stringify!(__fs) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_mcontext_avx32 { + pub __es: __darwin_i386_exception_state, + pub __ss: __darwin_i386_thread_state, + pub __fs: __darwin_i386_avx_state, +} +#[test] +fn bindgen_test_layout___darwin_mcontext_avx32() { + assert_eq!( + ::std::mem::size_of::<__darwin_mcontext_avx32>(), + 792usize, + concat!("Size of: ", stringify!(__darwin_mcontext_avx32)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_mcontext_avx32>(), + 4usize, + concat!("Alignment of ", stringify!(__darwin_mcontext_avx32)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext_avx32>())).__es as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext_avx32), + "::", + stringify!(__es) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext_avx32>())).__ss as *const _ as usize }, + 12usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext_avx32), + "::", + stringify!(__ss) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext_avx32>())).__fs as *const _ as usize }, + 76usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext_avx32), + "::", + stringify!(__fs) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_mcontext_avx512_32 { + pub __es: __darwin_i386_exception_state, + pub __ss: __darwin_i386_thread_state, + pub __fs: __darwin_i386_avx512_state, +} +#[test] +fn bindgen_test_layout___darwin_mcontext_avx512_32() { + assert_eq!( + ::std::mem::size_of::<__darwin_mcontext_avx512_32>(), + 1112usize, + concat!("Size of: ", stringify!(__darwin_mcontext_avx512_32)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_mcontext_avx512_32>(), + 4usize, + concat!("Alignment of ", stringify!(__darwin_mcontext_avx512_32)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext_avx512_32>())).__es as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext_avx512_32), + "::", + stringify!(__es) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext_avx512_32>())).__ss as *const _ as usize }, + 12usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext_avx512_32), + "::", + stringify!(__ss) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext_avx512_32>())).__fs as *const _ as usize }, + 76usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext_avx512_32), + "::", + stringify!(__fs) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_mcontext64 { + pub __es: __darwin_x86_exception_state64, + pub __ss: __darwin_x86_thread_state64, + pub __fs: __darwin_x86_float_state64, +} +#[test] +fn bindgen_test_layout___darwin_mcontext64() { + assert_eq!( + ::std::mem::size_of::<__darwin_mcontext64>(), + 712usize, + concat!("Size of: ", stringify!(__darwin_mcontext64)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_mcontext64>(), + 8usize, + concat!("Alignment of ", stringify!(__darwin_mcontext64)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext64>())).__es as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext64), + "::", + stringify!(__es) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext64>())).__ss as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext64), + "::", + stringify!(__ss) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext64>())).__fs as *const _ as usize }, + 184usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext64), + "::", + stringify!(__fs) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_mcontext64_full { + pub __es: __darwin_x86_exception_state64, + pub __ss: __darwin_x86_thread_full_state64, + pub __fs: __darwin_x86_float_state64, +} +#[test] +fn bindgen_test_layout___darwin_mcontext64_full() { + assert_eq!( + ::std::mem::size_of::<__darwin_mcontext64_full>(), + 744usize, + concat!("Size of: ", stringify!(__darwin_mcontext64_full)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_mcontext64_full>(), + 8usize, + concat!("Alignment of ", stringify!(__darwin_mcontext64_full)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext64_full>())).__es as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext64_full), + "::", + stringify!(__es) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext64_full>())).__ss as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext64_full), + "::", + stringify!(__ss) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext64_full>())).__fs as *const _ as usize }, + 216usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext64_full), + "::", + stringify!(__fs) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_mcontext_avx64 { + pub __es: __darwin_x86_exception_state64, + pub __ss: __darwin_x86_thread_state64, + pub __fs: __darwin_x86_avx_state64, +} +#[test] +fn bindgen_test_layout___darwin_mcontext_avx64() { + assert_eq!( + ::std::mem::size_of::<__darwin_mcontext_avx64>(), + 1032usize, + concat!("Size of: ", stringify!(__darwin_mcontext_avx64)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_mcontext_avx64>(), + 8usize, + concat!("Alignment of ", stringify!(__darwin_mcontext_avx64)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext_avx64>())).__es as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext_avx64), + "::", + stringify!(__es) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext_avx64>())).__ss as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext_avx64), + "::", + stringify!(__ss) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext_avx64>())).__fs as *const _ as usize }, + 184usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext_avx64), + "::", + stringify!(__fs) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_mcontext_avx64_full { + pub __es: __darwin_x86_exception_state64, + pub __ss: __darwin_x86_thread_full_state64, + pub __fs: __darwin_x86_avx_state64, +} +#[test] +fn bindgen_test_layout___darwin_mcontext_avx64_full() { + assert_eq!( + ::std::mem::size_of::<__darwin_mcontext_avx64_full>(), + 1064usize, + concat!("Size of: ", stringify!(__darwin_mcontext_avx64_full)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_mcontext_avx64_full>(), + 8usize, + concat!("Alignment of ", stringify!(__darwin_mcontext_avx64_full)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext_avx64_full>())).__es as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext_avx64_full), + "::", + stringify!(__es) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext_avx64_full>())).__ss as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext_avx64_full), + "::", + stringify!(__ss) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext_avx64_full>())).__fs as *const _ as usize }, + 216usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext_avx64_full), + "::", + stringify!(__fs) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_mcontext_avx512_64 { + pub __es: __darwin_x86_exception_state64, + pub __ss: __darwin_x86_thread_state64, + pub __fs: __darwin_x86_avx512_state64, +} +#[test] +fn bindgen_test_layout___darwin_mcontext_avx512_64() { + assert_eq!( + ::std::mem::size_of::<__darwin_mcontext_avx512_64>(), + 2632usize, + concat!("Size of: ", stringify!(__darwin_mcontext_avx512_64)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_mcontext_avx512_64>(), + 8usize, + concat!("Alignment of ", stringify!(__darwin_mcontext_avx512_64)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext_avx512_64>())).__es as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext_avx512_64), + "::", + stringify!(__es) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext_avx512_64>())).__ss as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext_avx512_64), + "::", + stringify!(__ss) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext_avx512_64>())).__fs as *const _ as usize }, + 184usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext_avx512_64), + "::", + stringify!(__fs) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_mcontext_avx512_64_full { + pub __es: __darwin_x86_exception_state64, + pub __ss: __darwin_x86_thread_full_state64, + pub __fs: __darwin_x86_avx512_state64, +} +#[test] +fn bindgen_test_layout___darwin_mcontext_avx512_64_full() { + assert_eq!( + ::std::mem::size_of::<__darwin_mcontext_avx512_64_full>(), + 2664usize, + concat!("Size of: ", stringify!(__darwin_mcontext_avx512_64_full)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_mcontext_avx512_64_full>(), + 8usize, + concat!("Alignment of ", stringify!(__darwin_mcontext_avx512_64_full)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext_avx512_64_full>())).__es as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext_avx512_64_full), + "::", + stringify!(__es) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext_avx512_64_full>())).__ss as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext_avx512_64_full), + "::", + stringify!(__ss) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_mcontext_avx512_64_full>())).__fs as *const _ as usize }, + 216usize, + concat!( + "Offset of field: ", + stringify!(__darwin_mcontext_avx512_64_full), + "::", + stringify!(__fs) + ) + ); +} +pub type mcontext_t = *mut __darwin_mcontext64; +pub type pthread_attr_t = __darwin_pthread_attr_t; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_sigaltstack { + pub ss_sp: *mut ::std::os::raw::c_void, + pub ss_size: __darwin_size_t, + pub ss_flags: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout___darwin_sigaltstack() { + assert_eq!( + ::std::mem::size_of::<__darwin_sigaltstack>(), + 24usize, + concat!("Size of: ", stringify!(__darwin_sigaltstack)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_sigaltstack>(), + 8usize, + concat!("Alignment of ", stringify!(__darwin_sigaltstack)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_sigaltstack>())).ss_sp as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__darwin_sigaltstack), + "::", + stringify!(ss_sp) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_sigaltstack>())).ss_size as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(__darwin_sigaltstack), + "::", + stringify!(ss_size) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_sigaltstack>())).ss_flags as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(__darwin_sigaltstack), + "::", + stringify!(ss_flags) + ) + ); +} +pub type stack_t = __darwin_sigaltstack; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_ucontext { + pub uc_onstack: ::std::os::raw::c_int, + pub uc_sigmask: __darwin_sigset_t, + pub uc_stack: __darwin_sigaltstack, + pub uc_link: *mut __darwin_ucontext, + pub uc_mcsize: __darwin_size_t, + pub uc_mcontext: *mut __darwin_mcontext64, +} +#[test] +fn bindgen_test_layout___darwin_ucontext() { + assert_eq!( + ::std::mem::size_of::<__darwin_ucontext>(), + 56usize, + concat!("Size of: ", stringify!(__darwin_ucontext)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_ucontext>(), + 8usize, + concat!("Alignment of ", stringify!(__darwin_ucontext)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_ucontext>())).uc_onstack as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__darwin_ucontext), + "::", + stringify!(uc_onstack) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_ucontext>())).uc_sigmask as *const _ as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(__darwin_ucontext), + "::", + stringify!(uc_sigmask) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_ucontext>())).uc_stack as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(__darwin_ucontext), + "::", + stringify!(uc_stack) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_ucontext>())).uc_link as *const _ as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(__darwin_ucontext), + "::", + stringify!(uc_link) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_ucontext>())).uc_mcsize as *const _ as usize }, + 40usize, + concat!( + "Offset of field: ", + stringify!(__darwin_ucontext), + "::", + stringify!(uc_mcsize) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__darwin_ucontext>())).uc_mcontext as *const _ as usize }, + 48usize, + concat!( + "Offset of field: ", + stringify!(__darwin_ucontext), + "::", + stringify!(uc_mcontext) + ) + ); +} +pub type ucontext_t = __darwin_ucontext; +pub type sigset_t = __darwin_sigset_t; +pub type size_t = __darwin_size_t; +pub type uid_t = __darwin_uid_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub union sigval { + pub sival_int: ::std::os::raw::c_int, + pub sival_ptr: *mut ::std::os::raw::c_void, +} +#[test] +fn bindgen_test_layout_sigval() { + assert_eq!( + ::std::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(sigval)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(sigval)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).sival_int as *const _ as usize }, + 0usize, + concat!("Offset of field: ", stringify!(sigval), "::", stringify!(sival_int)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).sival_ptr as *const _ as usize }, + 0usize, + concat!("Offset of field: ", stringify!(sigval), "::", stringify!(sival_ptr)) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct sigevent { + pub sigev_notify: ::std::os::raw::c_int, + pub sigev_signo: ::std::os::raw::c_int, + pub sigev_value: sigval, + pub sigev_notify_function: ::std::option::Option, + pub sigev_notify_attributes: *mut pthread_attr_t, +} +#[test] +fn bindgen_test_layout_sigevent() { + assert_eq!( + ::std::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(sigevent)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(sigevent)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).sigev_notify as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(sigevent), + "::", + stringify!(sigev_notify) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).sigev_signo as *const _ as usize }, + 4usize, + concat!("Offset of field: ", stringify!(sigevent), "::", stringify!(sigev_signo)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).sigev_value as *const _ as usize }, + 8usize, + concat!("Offset of field: ", stringify!(sigevent), "::", stringify!(sigev_value)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).sigev_notify_function as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(sigevent), + "::", + stringify!(sigev_notify_function) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).sigev_notify_attributes as *const _ as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(sigevent), + "::", + stringify!(sigev_notify_attributes) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct __siginfo { + pub si_signo: ::std::os::raw::c_int, + pub si_errno: ::std::os::raw::c_int, + pub si_code: ::std::os::raw::c_int, + pub si_pid: pid_t, + pub si_uid: uid_t, + pub si_status: ::std::os::raw::c_int, + pub si_addr: *mut ::std::os::raw::c_void, + pub si_value: sigval, + pub si_band: ::std::os::raw::c_long, + pub __pad: [::std::os::raw::c_ulong; 7usize], +} +#[test] +fn bindgen_test_layout___siginfo() { + assert_eq!( + ::std::mem::size_of::<__siginfo>(), + 104usize, + concat!("Size of: ", stringify!(__siginfo)) + ); + assert_eq!( + ::std::mem::align_of::<__siginfo>(), + 8usize, + concat!("Alignment of ", stringify!(__siginfo)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__siginfo>())).si_signo as *const _ as usize }, + 0usize, + concat!("Offset of field: ", stringify!(__siginfo), "::", stringify!(si_signo)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__siginfo>())).si_errno as *const _ as usize }, + 4usize, + concat!("Offset of field: ", stringify!(__siginfo), "::", stringify!(si_errno)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__siginfo>())).si_code as *const _ as usize }, + 8usize, + concat!("Offset of field: ", stringify!(__siginfo), "::", stringify!(si_code)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__siginfo>())).si_pid as *const _ as usize }, + 12usize, + concat!("Offset of field: ", stringify!(__siginfo), "::", stringify!(si_pid)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__siginfo>())).si_uid as *const _ as usize }, + 16usize, + concat!("Offset of field: ", stringify!(__siginfo), "::", stringify!(si_uid)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__siginfo>())).si_status as *const _ as usize }, + 20usize, + concat!("Offset of field: ", stringify!(__siginfo), "::", stringify!(si_status)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__siginfo>())).si_addr as *const _ as usize }, + 24usize, + concat!("Offset of field: ", stringify!(__siginfo), "::", stringify!(si_addr)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__siginfo>())).si_value as *const _ as usize }, + 32usize, + concat!("Offset of field: ", stringify!(__siginfo), "::", stringify!(si_value)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__siginfo>())).si_band as *const _ as usize }, + 40usize, + concat!("Offset of field: ", stringify!(__siginfo), "::", stringify!(si_band)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__siginfo>())).__pad as *const _ as usize }, + 48usize, + concat!("Offset of field: ", stringify!(__siginfo), "::", stringify!(__pad)) + ); +} +pub type siginfo_t = __siginfo; +#[repr(C)] +#[derive(Copy, Clone)] +pub union __sigaction_u { + pub __sa_handler: ::std::option::Option, + pub __sa_sigaction: ::std::option::Option< + unsafe extern "C" fn(arg1: ::std::os::raw::c_int, arg2: *mut __siginfo, arg3: *mut ::std::os::raw::c_void), + >, +} +#[test] +fn bindgen_test_layout___sigaction_u() { + assert_eq!( + ::std::mem::size_of::<__sigaction_u>(), + 8usize, + concat!("Size of: ", stringify!(__sigaction_u)) + ); + assert_eq!( + ::std::mem::align_of::<__sigaction_u>(), + 8usize, + concat!("Alignment of ", stringify!(__sigaction_u)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__sigaction_u>())).__sa_handler as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__sigaction_u), + "::", + stringify!(__sa_handler) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__sigaction_u>())).__sa_sigaction as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__sigaction_u), + "::", + stringify!(__sa_sigaction) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct __sigaction { + pub __sigaction_u: __sigaction_u, + pub sa_tramp: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: ::std::os::raw::c_int, + arg3: ::std::os::raw::c_int, + arg4: *mut siginfo_t, + arg5: *mut ::std::os::raw::c_void, + ), + >, + pub sa_mask: sigset_t, + pub sa_flags: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout___sigaction() { + assert_eq!( + ::std::mem::size_of::<__sigaction>(), + 24usize, + concat!("Size of: ", stringify!(__sigaction)) + ); + assert_eq!( + ::std::mem::align_of::<__sigaction>(), + 8usize, + concat!("Alignment of ", stringify!(__sigaction)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__sigaction>())).__sigaction_u as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__sigaction), + "::", + stringify!(__sigaction_u) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__sigaction>())).sa_tramp as *const _ as usize }, + 8usize, + concat!("Offset of field: ", stringify!(__sigaction), "::", stringify!(sa_tramp)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__sigaction>())).sa_mask as *const _ as usize }, + 16usize, + concat!("Offset of field: ", stringify!(__sigaction), "::", stringify!(sa_mask)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__sigaction>())).sa_flags as *const _ as usize }, + 20usize, + concat!("Offset of field: ", stringify!(__sigaction), "::", stringify!(sa_flags)) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct sigaction { + pub __sigaction_u: __sigaction_u, + pub sa_mask: sigset_t, + pub sa_flags: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout_sigaction() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(sigaction)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(sigaction)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).__sigaction_u as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(sigaction), + "::", + stringify!(__sigaction_u) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).sa_mask as *const _ as usize }, + 8usize, + concat!("Offset of field: ", stringify!(sigaction), "::", stringify!(sa_mask)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).sa_flags as *const _ as usize }, + 12usize, + concat!("Offset of field: ", stringify!(sigaction), "::", stringify!(sa_flags)) + ); +} +pub type sig_t = ::std::option::Option; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct sigvec { + pub sv_handler: ::std::option::Option, + pub sv_mask: ::std::os::raw::c_int, + pub sv_flags: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout_sigvec() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(sigvec)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(sigvec)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).sv_handler as *const _ as usize }, + 0usize, + concat!("Offset of field: ", stringify!(sigvec), "::", stringify!(sv_handler)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).sv_mask as *const _ as usize }, + 8usize, + concat!("Offset of field: ", stringify!(sigvec), "::", stringify!(sv_mask)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).sv_flags as *const _ as usize }, + 12usize, + concat!("Offset of field: ", stringify!(sigvec), "::", stringify!(sv_flags)) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct sigstack { + pub ss_sp: *mut ::std::os::raw::c_char, + pub ss_onstack: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout_sigstack() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(sigstack)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(sigstack)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ss_sp as *const _ as usize }, + 0usize, + concat!("Offset of field: ", stringify!(sigstack), "::", stringify!(ss_sp)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ss_onstack as *const _ as usize }, + 8usize, + concat!("Offset of field: ", stringify!(sigstack), "::", stringify!(ss_onstack)) + ); +} +extern "C" { + pub fn signal( + arg1: ::std::os::raw::c_int, + arg2: ::std::option::Option, + ) -> ::std::option::Option< + unsafe extern "C" fn( + arg1: ::std::os::raw::c_int, + arg2: ::std::option::Option, + ), + >; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct timeval { + pub tv_sec: __darwin_time_t, + pub tv_usec: __darwin_suseconds_t, +} +#[test] +fn bindgen_test_layout_timeval() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(timeval)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(timeval)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tv_sec as *const _ as usize }, + 0usize, + concat!("Offset of field: ", stringify!(timeval), "::", stringify!(tv_sec)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tv_usec as *const _ as usize }, + 8usize, + concat!("Offset of field: ", stringify!(timeval), "::", stringify!(tv_usec)) + ); +} +pub type rlim_t = __uint64_t; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct rusage { + pub ru_utime: timeval, + pub ru_stime: timeval, + pub ru_maxrss: ::std::os::raw::c_long, + pub ru_ixrss: ::std::os::raw::c_long, + pub ru_idrss: ::std::os::raw::c_long, + pub ru_isrss: ::std::os::raw::c_long, + pub ru_minflt: ::std::os::raw::c_long, + pub ru_majflt: ::std::os::raw::c_long, + pub ru_nswap: ::std::os::raw::c_long, + pub ru_inblock: ::std::os::raw::c_long, + pub ru_oublock: ::std::os::raw::c_long, + pub ru_msgsnd: ::std::os::raw::c_long, + pub ru_msgrcv: ::std::os::raw::c_long, + pub ru_nsignals: ::std::os::raw::c_long, + pub ru_nvcsw: ::std::os::raw::c_long, + pub ru_nivcsw: ::std::os::raw::c_long, +} +#[test] +fn bindgen_test_layout_rusage() { + assert_eq!( + ::std::mem::size_of::(), + 144usize, + concat!("Size of: ", stringify!(rusage)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(rusage)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ru_utime as *const _ as usize }, + 0usize, + concat!("Offset of field: ", stringify!(rusage), "::", stringify!(ru_utime)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ru_stime as *const _ as usize }, + 16usize, + concat!("Offset of field: ", stringify!(rusage), "::", stringify!(ru_stime)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ru_maxrss as *const _ as usize }, + 32usize, + concat!("Offset of field: ", stringify!(rusage), "::", stringify!(ru_maxrss)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ru_ixrss as *const _ as usize }, + 40usize, + concat!("Offset of field: ", stringify!(rusage), "::", stringify!(ru_ixrss)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ru_idrss as *const _ as usize }, + 48usize, + concat!("Offset of field: ", stringify!(rusage), "::", stringify!(ru_idrss)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ru_isrss as *const _ as usize }, + 56usize, + concat!("Offset of field: ", stringify!(rusage), "::", stringify!(ru_isrss)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ru_minflt as *const _ as usize }, + 64usize, + concat!("Offset of field: ", stringify!(rusage), "::", stringify!(ru_minflt)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ru_majflt as *const _ as usize }, + 72usize, + concat!("Offset of field: ", stringify!(rusage), "::", stringify!(ru_majflt)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ru_nswap as *const _ as usize }, + 80usize, + concat!("Offset of field: ", stringify!(rusage), "::", stringify!(ru_nswap)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ru_inblock as *const _ as usize }, + 88usize, + concat!("Offset of field: ", stringify!(rusage), "::", stringify!(ru_inblock)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ru_oublock as *const _ as usize }, + 96usize, + concat!("Offset of field: ", stringify!(rusage), "::", stringify!(ru_oublock)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ru_msgsnd as *const _ as usize }, + 104usize, + concat!("Offset of field: ", stringify!(rusage), "::", stringify!(ru_msgsnd)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ru_msgrcv as *const _ as usize }, + 112usize, + concat!("Offset of field: ", stringify!(rusage), "::", stringify!(ru_msgrcv)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ru_nsignals as *const _ as usize }, + 120usize, + concat!("Offset of field: ", stringify!(rusage), "::", stringify!(ru_nsignals)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ru_nvcsw as *const _ as usize }, + 128usize, + concat!("Offset of field: ", stringify!(rusage), "::", stringify!(ru_nvcsw)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ru_nivcsw as *const _ as usize }, + 136usize, + concat!("Offset of field: ", stringify!(rusage), "::", stringify!(ru_nivcsw)) + ); +} +pub type rusage_info_t = *mut ::std::os::raw::c_void; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct rusage_info_v0 { + pub ri_uuid: [u8; 16usize], + pub ri_user_time: u64, + pub ri_system_time: u64, + pub ri_pkg_idle_wkups: u64, + pub ri_interrupt_wkups: u64, + pub ri_pageins: u64, + pub ri_wired_size: u64, + pub ri_resident_size: u64, + pub ri_phys_footprint: u64, + pub ri_proc_start_abstime: u64, + pub ri_proc_exit_abstime: u64, +} +#[test] +fn bindgen_test_layout_rusage_info_v0() { + assert_eq!( + ::std::mem::size_of::(), + 96usize, + concat!("Size of: ", stringify!(rusage_info_v0)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(rusage_info_v0)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_uuid as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v0), + "::", + stringify!(ri_uuid) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_user_time as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v0), + "::", + stringify!(ri_user_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_system_time as *const _ as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v0), + "::", + stringify!(ri_system_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_pkg_idle_wkups as *const _ as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v0), + "::", + stringify!(ri_pkg_idle_wkups) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_interrupt_wkups as *const _ as usize }, + 40usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v0), + "::", + stringify!(ri_interrupt_wkups) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_pageins as *const _ as usize }, + 48usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v0), + "::", + stringify!(ri_pageins) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_wired_size as *const _ as usize }, + 56usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v0), + "::", + stringify!(ri_wired_size) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_resident_size as *const _ as usize }, + 64usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v0), + "::", + stringify!(ri_resident_size) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_phys_footprint as *const _ as usize }, + 72usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v0), + "::", + stringify!(ri_phys_footprint) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_proc_start_abstime as *const _ as usize }, + 80usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v0), + "::", + stringify!(ri_proc_start_abstime) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_proc_exit_abstime as *const _ as usize }, + 88usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v0), + "::", + stringify!(ri_proc_exit_abstime) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct rusage_info_v1 { + pub ri_uuid: [u8; 16usize], + pub ri_user_time: u64, + pub ri_system_time: u64, + pub ri_pkg_idle_wkups: u64, + pub ri_interrupt_wkups: u64, + pub ri_pageins: u64, + pub ri_wired_size: u64, + pub ri_resident_size: u64, + pub ri_phys_footprint: u64, + pub ri_proc_start_abstime: u64, + pub ri_proc_exit_abstime: u64, + pub ri_child_user_time: u64, + pub ri_child_system_time: u64, + pub ri_child_pkg_idle_wkups: u64, + pub ri_child_interrupt_wkups: u64, + pub ri_child_pageins: u64, + pub ri_child_elapsed_abstime: u64, +} +#[test] +fn bindgen_test_layout_rusage_info_v1() { + assert_eq!( + ::std::mem::size_of::(), + 144usize, + concat!("Size of: ", stringify!(rusage_info_v1)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(rusage_info_v1)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_uuid as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v1), + "::", + stringify!(ri_uuid) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_user_time as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v1), + "::", + stringify!(ri_user_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_system_time as *const _ as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v1), + "::", + stringify!(ri_system_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_pkg_idle_wkups as *const _ as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v1), + "::", + stringify!(ri_pkg_idle_wkups) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_interrupt_wkups as *const _ as usize }, + 40usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v1), + "::", + stringify!(ri_interrupt_wkups) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_pageins as *const _ as usize }, + 48usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v1), + "::", + stringify!(ri_pageins) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_wired_size as *const _ as usize }, + 56usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v1), + "::", + stringify!(ri_wired_size) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_resident_size as *const _ as usize }, + 64usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v1), + "::", + stringify!(ri_resident_size) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_phys_footprint as *const _ as usize }, + 72usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v1), + "::", + stringify!(ri_phys_footprint) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_proc_start_abstime as *const _ as usize }, + 80usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v1), + "::", + stringify!(ri_proc_start_abstime) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_proc_exit_abstime as *const _ as usize }, + 88usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v1), + "::", + stringify!(ri_proc_exit_abstime) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_user_time as *const _ as usize }, + 96usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v1), + "::", + stringify!(ri_child_user_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_system_time as *const _ as usize }, + 104usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v1), + "::", + stringify!(ri_child_system_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_pkg_idle_wkups as *const _ as usize }, + 112usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v1), + "::", + stringify!(ri_child_pkg_idle_wkups) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_interrupt_wkups as *const _ as usize }, + 120usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v1), + "::", + stringify!(ri_child_interrupt_wkups) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_pageins as *const _ as usize }, + 128usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v1), + "::", + stringify!(ri_child_pageins) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_elapsed_abstime as *const _ as usize }, + 136usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v1), + "::", + stringify!(ri_child_elapsed_abstime) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct rusage_info_v2 { + pub ri_uuid: [u8; 16usize], + pub ri_user_time: u64, + pub ri_system_time: u64, + pub ri_pkg_idle_wkups: u64, + pub ri_interrupt_wkups: u64, + pub ri_pageins: u64, + pub ri_wired_size: u64, + pub ri_resident_size: u64, + pub ri_phys_footprint: u64, + pub ri_proc_start_abstime: u64, + pub ri_proc_exit_abstime: u64, + pub ri_child_user_time: u64, + pub ri_child_system_time: u64, + pub ri_child_pkg_idle_wkups: u64, + pub ri_child_interrupt_wkups: u64, + pub ri_child_pageins: u64, + pub ri_child_elapsed_abstime: u64, + pub ri_diskio_bytesread: u64, + pub ri_diskio_byteswritten: u64, +} +#[test] +fn bindgen_test_layout_rusage_info_v2() { + assert_eq!( + ::std::mem::size_of::(), + 160usize, + concat!("Size of: ", stringify!(rusage_info_v2)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(rusage_info_v2)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_uuid as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v2), + "::", + stringify!(ri_uuid) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_user_time as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v2), + "::", + stringify!(ri_user_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_system_time as *const _ as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v2), + "::", + stringify!(ri_system_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_pkg_idle_wkups as *const _ as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v2), + "::", + stringify!(ri_pkg_idle_wkups) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_interrupt_wkups as *const _ as usize }, + 40usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v2), + "::", + stringify!(ri_interrupt_wkups) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_pageins as *const _ as usize }, + 48usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v2), + "::", + stringify!(ri_pageins) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_wired_size as *const _ as usize }, + 56usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v2), + "::", + stringify!(ri_wired_size) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_resident_size as *const _ as usize }, + 64usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v2), + "::", + stringify!(ri_resident_size) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_phys_footprint as *const _ as usize }, + 72usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v2), + "::", + stringify!(ri_phys_footprint) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_proc_start_abstime as *const _ as usize }, + 80usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v2), + "::", + stringify!(ri_proc_start_abstime) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_proc_exit_abstime as *const _ as usize }, + 88usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v2), + "::", + stringify!(ri_proc_exit_abstime) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_user_time as *const _ as usize }, + 96usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v2), + "::", + stringify!(ri_child_user_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_system_time as *const _ as usize }, + 104usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v2), + "::", + stringify!(ri_child_system_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_pkg_idle_wkups as *const _ as usize }, + 112usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v2), + "::", + stringify!(ri_child_pkg_idle_wkups) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_interrupt_wkups as *const _ as usize }, + 120usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v2), + "::", + stringify!(ri_child_interrupt_wkups) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_pageins as *const _ as usize }, + 128usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v2), + "::", + stringify!(ri_child_pageins) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_elapsed_abstime as *const _ as usize }, + 136usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v2), + "::", + stringify!(ri_child_elapsed_abstime) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_diskio_bytesread as *const _ as usize }, + 144usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v2), + "::", + stringify!(ri_diskio_bytesread) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_diskio_byteswritten as *const _ as usize }, + 152usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v2), + "::", + stringify!(ri_diskio_byteswritten) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct rusage_info_v3 { + pub ri_uuid: [u8; 16usize], + pub ri_user_time: u64, + pub ri_system_time: u64, + pub ri_pkg_idle_wkups: u64, + pub ri_interrupt_wkups: u64, + pub ri_pageins: u64, + pub ri_wired_size: u64, + pub ri_resident_size: u64, + pub ri_phys_footprint: u64, + pub ri_proc_start_abstime: u64, + pub ri_proc_exit_abstime: u64, + pub ri_child_user_time: u64, + pub ri_child_system_time: u64, + pub ri_child_pkg_idle_wkups: u64, + pub ri_child_interrupt_wkups: u64, + pub ri_child_pageins: u64, + pub ri_child_elapsed_abstime: u64, + pub ri_diskio_bytesread: u64, + pub ri_diskio_byteswritten: u64, + pub ri_cpu_time_qos_default: u64, + pub ri_cpu_time_qos_maintenance: u64, + pub ri_cpu_time_qos_background: u64, + pub ri_cpu_time_qos_utility: u64, + pub ri_cpu_time_qos_legacy: u64, + pub ri_cpu_time_qos_user_initiated: u64, + pub ri_cpu_time_qos_user_interactive: u64, + pub ri_billed_system_time: u64, + pub ri_serviced_system_time: u64, +} +#[test] +fn bindgen_test_layout_rusage_info_v3() { + assert_eq!( + ::std::mem::size_of::(), + 232usize, + concat!("Size of: ", stringify!(rusage_info_v3)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(rusage_info_v3)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_uuid as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_uuid) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_user_time as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_user_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_system_time as *const _ as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_system_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_pkg_idle_wkups as *const _ as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_pkg_idle_wkups) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_interrupt_wkups as *const _ as usize }, + 40usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_interrupt_wkups) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_pageins as *const _ as usize }, + 48usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_pageins) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_wired_size as *const _ as usize }, + 56usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_wired_size) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_resident_size as *const _ as usize }, + 64usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_resident_size) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_phys_footprint as *const _ as usize }, + 72usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_phys_footprint) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_proc_start_abstime as *const _ as usize }, + 80usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_proc_start_abstime) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_proc_exit_abstime as *const _ as usize }, + 88usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_proc_exit_abstime) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_user_time as *const _ as usize }, + 96usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_child_user_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_system_time as *const _ as usize }, + 104usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_child_system_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_pkg_idle_wkups as *const _ as usize }, + 112usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_child_pkg_idle_wkups) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_interrupt_wkups as *const _ as usize }, + 120usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_child_interrupt_wkups) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_pageins as *const _ as usize }, + 128usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_child_pageins) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_elapsed_abstime as *const _ as usize }, + 136usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_child_elapsed_abstime) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_diskio_bytesread as *const _ as usize }, + 144usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_diskio_bytesread) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_diskio_byteswritten as *const _ as usize }, + 152usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_diskio_byteswritten) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_cpu_time_qos_default as *const _ as usize }, + 160usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_cpu_time_qos_default) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_cpu_time_qos_maintenance as *const _ as usize }, + 168usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_cpu_time_qos_maintenance) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_cpu_time_qos_background as *const _ as usize }, + 176usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_cpu_time_qos_background) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_cpu_time_qos_utility as *const _ as usize }, + 184usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_cpu_time_qos_utility) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_cpu_time_qos_legacy as *const _ as usize }, + 192usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_cpu_time_qos_legacy) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_cpu_time_qos_user_initiated as *const _ as usize }, + 200usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_cpu_time_qos_user_initiated) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_cpu_time_qos_user_interactive as *const _ as usize }, + 208usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_cpu_time_qos_user_interactive) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_billed_system_time as *const _ as usize }, + 216usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_billed_system_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_serviced_system_time as *const _ as usize }, + 224usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v3), + "::", + stringify!(ri_serviced_system_time) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct rusage_info_v4 { + pub ri_uuid: [u8; 16usize], + pub ri_user_time: u64, + pub ri_system_time: u64, + pub ri_pkg_idle_wkups: u64, + pub ri_interrupt_wkups: u64, + pub ri_pageins: u64, + pub ri_wired_size: u64, + pub ri_resident_size: u64, + pub ri_phys_footprint: u64, + pub ri_proc_start_abstime: u64, + pub ri_proc_exit_abstime: u64, + pub ri_child_user_time: u64, + pub ri_child_system_time: u64, + pub ri_child_pkg_idle_wkups: u64, + pub ri_child_interrupt_wkups: u64, + pub ri_child_pageins: u64, + pub ri_child_elapsed_abstime: u64, + pub ri_diskio_bytesread: u64, + pub ri_diskio_byteswritten: u64, + pub ri_cpu_time_qos_default: u64, + pub ri_cpu_time_qos_maintenance: u64, + pub ri_cpu_time_qos_background: u64, + pub ri_cpu_time_qos_utility: u64, + pub ri_cpu_time_qos_legacy: u64, + pub ri_cpu_time_qos_user_initiated: u64, + pub ri_cpu_time_qos_user_interactive: u64, + pub ri_billed_system_time: u64, + pub ri_serviced_system_time: u64, + pub ri_logical_writes: u64, + pub ri_lifetime_max_phys_footprint: u64, + pub ri_instructions: u64, + pub ri_cycles: u64, + pub ri_billed_energy: u64, + pub ri_serviced_energy: u64, + pub ri_interval_max_phys_footprint: u64, + pub ri_runnable_time: u64, +} +#[test] +fn bindgen_test_layout_rusage_info_v4() { + assert_eq!( + ::std::mem::size_of::(), + 296usize, + concat!("Size of: ", stringify!(rusage_info_v4)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(rusage_info_v4)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_uuid as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_uuid) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_user_time as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_user_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_system_time as *const _ as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_system_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_pkg_idle_wkups as *const _ as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_pkg_idle_wkups) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_interrupt_wkups as *const _ as usize }, + 40usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_interrupt_wkups) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_pageins as *const _ as usize }, + 48usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_pageins) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_wired_size as *const _ as usize }, + 56usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_wired_size) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_resident_size as *const _ as usize }, + 64usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_resident_size) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_phys_footprint as *const _ as usize }, + 72usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_phys_footprint) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_proc_start_abstime as *const _ as usize }, + 80usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_proc_start_abstime) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_proc_exit_abstime as *const _ as usize }, + 88usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_proc_exit_abstime) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_user_time as *const _ as usize }, + 96usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_child_user_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_system_time as *const _ as usize }, + 104usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_child_system_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_pkg_idle_wkups as *const _ as usize }, + 112usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_child_pkg_idle_wkups) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_interrupt_wkups as *const _ as usize }, + 120usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_child_interrupt_wkups) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_pageins as *const _ as usize }, + 128usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_child_pageins) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_elapsed_abstime as *const _ as usize }, + 136usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_child_elapsed_abstime) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_diskio_bytesread as *const _ as usize }, + 144usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_diskio_bytesread) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_diskio_byteswritten as *const _ as usize }, + 152usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_diskio_byteswritten) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_cpu_time_qos_default as *const _ as usize }, + 160usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_cpu_time_qos_default) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_cpu_time_qos_maintenance as *const _ as usize }, + 168usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_cpu_time_qos_maintenance) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_cpu_time_qos_background as *const _ as usize }, + 176usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_cpu_time_qos_background) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_cpu_time_qos_utility as *const _ as usize }, + 184usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_cpu_time_qos_utility) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_cpu_time_qos_legacy as *const _ as usize }, + 192usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_cpu_time_qos_legacy) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_cpu_time_qos_user_initiated as *const _ as usize }, + 200usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_cpu_time_qos_user_initiated) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_cpu_time_qos_user_interactive as *const _ as usize }, + 208usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_cpu_time_qos_user_interactive) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_billed_system_time as *const _ as usize }, + 216usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_billed_system_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_serviced_system_time as *const _ as usize }, + 224usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_serviced_system_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_logical_writes as *const _ as usize }, + 232usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_logical_writes) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_lifetime_max_phys_footprint as *const _ as usize }, + 240usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_lifetime_max_phys_footprint) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_instructions as *const _ as usize }, + 248usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_instructions) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_cycles as *const _ as usize }, + 256usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_cycles) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_billed_energy as *const _ as usize }, + 264usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_billed_energy) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_serviced_energy as *const _ as usize }, + 272usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_serviced_energy) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_interval_max_phys_footprint as *const _ as usize }, + 280usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_interval_max_phys_footprint) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_runnable_time as *const _ as usize }, + 288usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v4), + "::", + stringify!(ri_runnable_time) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct rusage_info_v5 { + pub ri_uuid: [u8; 16usize], + pub ri_user_time: u64, + pub ri_system_time: u64, + pub ri_pkg_idle_wkups: u64, + pub ri_interrupt_wkups: u64, + pub ri_pageins: u64, + pub ri_wired_size: u64, + pub ri_resident_size: u64, + pub ri_phys_footprint: u64, + pub ri_proc_start_abstime: u64, + pub ri_proc_exit_abstime: u64, + pub ri_child_user_time: u64, + pub ri_child_system_time: u64, + pub ri_child_pkg_idle_wkups: u64, + pub ri_child_interrupt_wkups: u64, + pub ri_child_pageins: u64, + pub ri_child_elapsed_abstime: u64, + pub ri_diskio_bytesread: u64, + pub ri_diskio_byteswritten: u64, + pub ri_cpu_time_qos_default: u64, + pub ri_cpu_time_qos_maintenance: u64, + pub ri_cpu_time_qos_background: u64, + pub ri_cpu_time_qos_utility: u64, + pub ri_cpu_time_qos_legacy: u64, + pub ri_cpu_time_qos_user_initiated: u64, + pub ri_cpu_time_qos_user_interactive: u64, + pub ri_billed_system_time: u64, + pub ri_serviced_system_time: u64, + pub ri_logical_writes: u64, + pub ri_lifetime_max_phys_footprint: u64, + pub ri_instructions: u64, + pub ri_cycles: u64, + pub ri_billed_energy: u64, + pub ri_serviced_energy: u64, + pub ri_interval_max_phys_footprint: u64, + pub ri_runnable_time: u64, + pub ri_flags: u64, +} +#[test] +fn bindgen_test_layout_rusage_info_v5() { + assert_eq!( + ::std::mem::size_of::(), + 304usize, + concat!("Size of: ", stringify!(rusage_info_v5)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(rusage_info_v5)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_uuid as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_uuid) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_user_time as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_user_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_system_time as *const _ as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_system_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_pkg_idle_wkups as *const _ as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_pkg_idle_wkups) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_interrupt_wkups as *const _ as usize }, + 40usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_interrupt_wkups) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_pageins as *const _ as usize }, + 48usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_pageins) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_wired_size as *const _ as usize }, + 56usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_wired_size) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_resident_size as *const _ as usize }, + 64usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_resident_size) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_phys_footprint as *const _ as usize }, + 72usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_phys_footprint) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_proc_start_abstime as *const _ as usize }, + 80usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_proc_start_abstime) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_proc_exit_abstime as *const _ as usize }, + 88usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_proc_exit_abstime) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_user_time as *const _ as usize }, + 96usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_child_user_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_system_time as *const _ as usize }, + 104usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_child_system_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_pkg_idle_wkups as *const _ as usize }, + 112usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_child_pkg_idle_wkups) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_interrupt_wkups as *const _ as usize }, + 120usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_child_interrupt_wkups) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_pageins as *const _ as usize }, + 128usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_child_pageins) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_child_elapsed_abstime as *const _ as usize }, + 136usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_child_elapsed_abstime) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_diskio_bytesread as *const _ as usize }, + 144usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_diskio_bytesread) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_diskio_byteswritten as *const _ as usize }, + 152usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_diskio_byteswritten) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_cpu_time_qos_default as *const _ as usize }, + 160usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_cpu_time_qos_default) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_cpu_time_qos_maintenance as *const _ as usize }, + 168usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_cpu_time_qos_maintenance) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_cpu_time_qos_background as *const _ as usize }, + 176usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_cpu_time_qos_background) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_cpu_time_qos_utility as *const _ as usize }, + 184usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_cpu_time_qos_utility) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_cpu_time_qos_legacy as *const _ as usize }, + 192usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_cpu_time_qos_legacy) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_cpu_time_qos_user_initiated as *const _ as usize }, + 200usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_cpu_time_qos_user_initiated) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_cpu_time_qos_user_interactive as *const _ as usize }, + 208usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_cpu_time_qos_user_interactive) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_billed_system_time as *const _ as usize }, + 216usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_billed_system_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_serviced_system_time as *const _ as usize }, + 224usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_serviced_system_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_logical_writes as *const _ as usize }, + 232usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_logical_writes) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_lifetime_max_phys_footprint as *const _ as usize }, + 240usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_lifetime_max_phys_footprint) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_instructions as *const _ as usize }, + 248usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_instructions) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_cycles as *const _ as usize }, + 256usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_cycles) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_billed_energy as *const _ as usize }, + 264usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_billed_energy) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_serviced_energy as *const _ as usize }, + 272usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_serviced_energy) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_interval_max_phys_footprint as *const _ as usize }, + 280usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_interval_max_phys_footprint) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_runnable_time as *const _ as usize }, + 288usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_runnable_time) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).ri_flags as *const _ as usize }, + 296usize, + concat!( + "Offset of field: ", + stringify!(rusage_info_v5), + "::", + stringify!(ri_flags) + ) + ); +} +pub type rusage_info_current = rusage_info_v5; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct rlimit { + pub rlim_cur: rlim_t, + pub rlim_max: rlim_t, +} +#[test] +fn bindgen_test_layout_rlimit() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(rlimit)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(rlimit)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).rlim_cur as *const _ as usize }, + 0usize, + concat!("Offset of field: ", stringify!(rlimit), "::", stringify!(rlim_cur)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).rlim_max as *const _ as usize }, + 8usize, + concat!("Offset of field: ", stringify!(rlimit), "::", stringify!(rlim_max)) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct proc_rlimit_control_wakeupmon { + pub wm_flags: u32, + pub wm_rate: i32, +} +#[test] +fn bindgen_test_layout_proc_rlimit_control_wakeupmon() { + assert_eq!( + ::std::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(proc_rlimit_control_wakeupmon)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(proc_rlimit_control_wakeupmon)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).wm_flags as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(proc_rlimit_control_wakeupmon), + "::", + stringify!(wm_flags) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).wm_rate as *const _ as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(proc_rlimit_control_wakeupmon), + "::", + stringify!(wm_rate) + ) + ); +} +extern "C" { + pub fn getpriority(arg1: ::std::os::raw::c_int, arg2: id_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getiopolicy_np(arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getrlimit(arg1: ::std::os::raw::c_int, arg2: *mut rlimit) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getrusage(arg1: ::std::os::raw::c_int, arg2: *mut rusage) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn setpriority(arg1: ::std::os::raw::c_int, arg2: id_t, arg3: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn setiopolicy_np( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + arg3: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn setrlimit(arg1: ::std::os::raw::c_int, arg2: *const rlimit) -> ::std::os::raw::c_int; +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union wait { + pub w_status: ::std::os::raw::c_int, + pub w_T: wait__bindgen_ty_1, + pub w_S: wait__bindgen_ty_2, +} +#[repr(C)] +#[repr(align(4))] +#[derive(Debug, Copy, Clone)] +pub struct wait__bindgen_ty_1 { + pub _bitfield_align_1: [u16; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +#[test] +fn bindgen_test_layout_wait__bindgen_ty_1() { + assert_eq!( + ::std::mem::size_of::(), + 4usize, + concat!("Size of: ", stringify!(wait__bindgen_ty_1)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(wait__bindgen_ty_1)) + ); +} +impl wait__bindgen_ty_1 { + #[inline] + pub fn w_Termsig(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 7u8) as u32) } + } + #[inline] + pub fn set_w_Termsig(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 7u8, val as u64) + } + } + #[inline] + pub fn w_Coredump(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u32) } + } + #[inline] + pub fn set_w_Coredump(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(7usize, 1u8, val as u64) + } + } + #[inline] + pub fn w_Retcode(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 8u8) as u32) } + } + #[inline] + pub fn set_w_Retcode(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 8u8, val as u64) + } + } + #[inline] + pub fn w_Filler(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 16u8) as u32) } + } + #[inline] + pub fn set_w_Filler(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 16u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + w_Termsig: ::std::os::raw::c_uint, + w_Coredump: ::std::os::raw::c_uint, + w_Retcode: ::std::os::raw::c_uint, + w_Filler: ::std::os::raw::c_uint, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 7u8, { + let w_Termsig: u32 = unsafe { ::std::mem::transmute(w_Termsig) }; + w_Termsig as u64 + }); + __bindgen_bitfield_unit.set(7usize, 1u8, { + let w_Coredump: u32 = unsafe { ::std::mem::transmute(w_Coredump) }; + w_Coredump as u64 + }); + __bindgen_bitfield_unit.set(8usize, 8u8, { + let w_Retcode: u32 = unsafe { ::std::mem::transmute(w_Retcode) }; + w_Retcode as u64 + }); + __bindgen_bitfield_unit.set(16usize, 16u8, { + let w_Filler: u32 = unsafe { ::std::mem::transmute(w_Filler) }; + w_Filler as u64 + }); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[repr(align(4))] +#[derive(Debug, Copy, Clone)] +pub struct wait__bindgen_ty_2 { + pub _bitfield_align_1: [u16; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +#[test] +fn bindgen_test_layout_wait__bindgen_ty_2() { + assert_eq!( + ::std::mem::size_of::(), + 4usize, + concat!("Size of: ", stringify!(wait__bindgen_ty_2)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(wait__bindgen_ty_2)) + ); +} +impl wait__bindgen_ty_2 { + #[inline] + pub fn w_Stopval(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 8u8) as u32) } + } + #[inline] + pub fn set_w_Stopval(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 8u8, val as u64) + } + } + #[inline] + pub fn w_Stopsig(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 8u8) as u32) } + } + #[inline] + pub fn set_w_Stopsig(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 8u8, val as u64) + } + } + #[inline] + pub fn w_Filler(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 16u8) as u32) } + } + #[inline] + pub fn set_w_Filler(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 16u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + w_Stopval: ::std::os::raw::c_uint, + w_Stopsig: ::std::os::raw::c_uint, + w_Filler: ::std::os::raw::c_uint, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit.set(0usize, 8u8, { + let w_Stopval: u32 = unsafe { ::std::mem::transmute(w_Stopval) }; + w_Stopval as u64 + }); + __bindgen_bitfield_unit.set(8usize, 8u8, { + let w_Stopsig: u32 = unsafe { ::std::mem::transmute(w_Stopsig) }; + w_Stopsig as u64 + }); + __bindgen_bitfield_unit.set(16usize, 16u8, { + let w_Filler: u32 = unsafe { ::std::mem::transmute(w_Filler) }; + w_Filler as u64 + }); + __bindgen_bitfield_unit + } +} +#[test] +fn bindgen_test_layout_wait() { + assert_eq!( + ::std::mem::size_of::(), + 4usize, + concat!("Size of: ", stringify!(wait)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(wait)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).w_status as *const _ as usize }, + 0usize, + concat!("Offset of field: ", stringify!(wait), "::", stringify!(w_status)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).w_T as *const _ as usize }, + 0usize, + concat!("Offset of field: ", stringify!(wait), "::", stringify!(w_T)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).w_S as *const _ as usize }, + 0usize, + concat!("Offset of field: ", stringify!(wait), "::", stringify!(w_S)) + ); +} +extern "C" { + pub fn wait(arg1: *mut ::std::os::raw::c_int) -> pid_t; +} +extern "C" { + pub fn waitpid(arg1: pid_t, arg2: *mut ::std::os::raw::c_int, arg3: ::std::os::raw::c_int) -> pid_t; +} +extern "C" { + pub fn waitid( + arg1: idtype_t, + arg2: id_t, + arg3: *mut siginfo_t, + arg4: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn wait3(arg1: *mut ::std::os::raw::c_int, arg2: ::std::os::raw::c_int, arg3: *mut rusage) -> pid_t; +} +extern "C" { + pub fn wait4( + arg1: pid_t, + arg2: *mut ::std::os::raw::c_int, + arg3: ::std::os::raw::c_int, + arg4: *mut rusage, + ) -> pid_t; +} +extern "C" { + pub fn alloca(arg1: ::std::os::raw::c_ulong) -> *mut ::std::os::raw::c_void; +} +pub type ct_rune_t = __darwin_ct_rune_t; +pub type rune_t = __darwin_rune_t; +pub type wchar_t = __darwin_wchar_t; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct div_t { + pub quot: ::std::os::raw::c_int, + pub rem: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout_div_t() { + assert_eq!( + ::std::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(div_t)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(div_t)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).quot as *const _ as usize }, + 0usize, + concat!("Offset of field: ", stringify!(div_t), "::", stringify!(quot)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).rem as *const _ as usize }, + 4usize, + concat!("Offset of field: ", stringify!(div_t), "::", stringify!(rem)) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ldiv_t { + pub quot: ::std::os::raw::c_long, + pub rem: ::std::os::raw::c_long, +} +#[test] +fn bindgen_test_layout_ldiv_t() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(ldiv_t)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(ldiv_t)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).quot as *const _ as usize }, + 0usize, + concat!("Offset of field: ", stringify!(ldiv_t), "::", stringify!(quot)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).rem as *const _ as usize }, + 8usize, + concat!("Offset of field: ", stringify!(ldiv_t), "::", stringify!(rem)) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct lldiv_t { + pub quot: ::std::os::raw::c_longlong, + pub rem: ::std::os::raw::c_longlong, +} +#[test] +fn bindgen_test_layout_lldiv_t() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(lldiv_t)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(lldiv_t)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).quot as *const _ as usize }, + 0usize, + concat!("Offset of field: ", stringify!(lldiv_t), "::", stringify!(quot)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).rem as *const _ as usize }, + 8usize, + concat!("Offset of field: ", stringify!(lldiv_t), "::", stringify!(rem)) + ); +} +extern "C" { + pub static mut __mb_cur_max: ::std::os::raw::c_int; +} +extern "C" { + pub fn malloc(__size: ::std::os::raw::c_ulong) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn calloc(__count: ::std::os::raw::c_ulong, __size: ::std::os::raw::c_ulong) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn free(arg1: *mut ::std::os::raw::c_void); +} +extern "C" { + pub fn realloc(__ptr: *mut ::std::os::raw::c_void, __size: ::std::os::raw::c_ulong) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn valloc(arg1: size_t) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn aligned_alloc( + __alignment: ::std::os::raw::c_ulong, + __size: ::std::os::raw::c_ulong, + ) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn posix_memalign( + __memptr: *mut *mut ::std::os::raw::c_void, + __alignment: size_t, + __size: size_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn abort(); +} +extern "C" { + pub fn abs(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn atexit(arg1: ::std::option::Option) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn atof(arg1: *const ::std::os::raw::c_char) -> f64; +} +extern "C" { + pub fn atoi(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn atol(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_long; } extern "C" { - pub fn random() -> ::std::os::raw::c_long; + pub fn atoll(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_longlong; } extern "C" { - pub fn srandom(__seed: ::std::os::raw::c_uint); + pub fn bsearch( + __key: *const ::std::os::raw::c_void, + __base: *const ::std::os::raw::c_void, + __nel: size_t, + __width: size_t, + __compar: ::std::option::Option< + unsafe extern "C" fn( + arg1: *const ::std::os::raw::c_void, + arg2: *const ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int, + >, + ) -> *mut ::std::os::raw::c_void; } extern "C" { - pub fn initstate( - __seed: ::std::os::raw::c_uint, - __statebuf: *mut ::std::os::raw::c_char, - __statelen: size_t, - ) -> *mut ::std::os::raw::c_char; + pub fn div(arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int) -> div_t; } extern "C" { - pub fn setstate(__statebuf: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; + pub fn exit(arg1: ::std::os::raw::c_int); } -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct random_data { - pub fptr: *mut i32, - pub rptr: *mut i32, - pub state: *mut i32, - pub rand_type: ::std::os::raw::c_int, - pub rand_deg: ::std::os::raw::c_int, - pub rand_sep: ::std::os::raw::c_int, - pub end_ptr: *mut i32, +extern "C" { + pub fn getenv(arg1: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; } -#[test] -fn bindgen_test_layout_random_data() { - assert_eq!( - ::std::mem::size_of::(), - 48usize, - concat!("Size of: ", stringify!(random_data)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(random_data)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).fptr as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(random_data), "::", stringify!(fptr)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).rptr as *const _ as usize }, - 8usize, - concat!("Offset of field: ", stringify!(random_data), "::", stringify!(rptr)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).state as *const _ as usize }, - 16usize, - concat!("Offset of field: ", stringify!(random_data), "::", stringify!(state)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).rand_type as *const _ as usize }, - 24usize, - concat!( - "Offset of field: ", - stringify!(random_data), - "::", - stringify!(rand_type) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).rand_deg as *const _ as usize }, - 28usize, - concat!("Offset of field: ", stringify!(random_data), "::", stringify!(rand_deg)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).rand_sep as *const _ as usize }, - 32usize, - concat!("Offset of field: ", stringify!(random_data), "::", stringify!(rand_sep)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).end_ptr as *const _ as usize }, - 40usize, - concat!("Offset of field: ", stringify!(random_data), "::", stringify!(end_ptr)) - ); +extern "C" { + pub fn labs(arg1: ::std::os::raw::c_long) -> ::std::os::raw::c_long; } extern "C" { - pub fn random_r(__buf: *mut random_data, __result: *mut i32) -> ::std::os::raw::c_int; + pub fn ldiv(arg1: ::std::os::raw::c_long, arg2: ::std::os::raw::c_long) -> ldiv_t; } extern "C" { - pub fn srandom_r(__seed: ::std::os::raw::c_uint, __buf: *mut random_data) -> ::std::os::raw::c_int; + pub fn llabs(arg1: ::std::os::raw::c_longlong) -> ::std::os::raw::c_longlong; } extern "C" { - pub fn initstate_r( - __seed: ::std::os::raw::c_uint, - __statebuf: *mut ::std::os::raw::c_char, - __statelen: size_t, - __buf: *mut random_data, - ) -> ::std::os::raw::c_int; + pub fn lldiv(arg1: ::std::os::raw::c_longlong, arg2: ::std::os::raw::c_longlong) -> lldiv_t; } extern "C" { - pub fn setstate_r(__statebuf: *mut ::std::os::raw::c_char, __buf: *mut random_data) -> ::std::os::raw::c_int; + pub fn mblen(__s: *const ::std::os::raw::c_char, __n: size_t) -> ::std::os::raw::c_int; } extern "C" { - pub fn rand() -> ::std::os::raw::c_int; + pub fn mbstowcs(arg1: *mut wchar_t, arg2: *const ::std::os::raw::c_char, arg3: size_t) -> size_t; } extern "C" { - pub fn srand(__seed: ::std::os::raw::c_uint); + pub fn mbtowc(arg1: *mut wchar_t, arg2: *const ::std::os::raw::c_char, arg3: size_t) -> ::std::os::raw::c_int; } extern "C" { - pub fn rand_r(__seed: *mut ::std::os::raw::c_uint) -> ::std::os::raw::c_int; + pub fn qsort( + __base: *mut ::std::os::raw::c_void, + __nel: size_t, + __width: size_t, + __compar: ::std::option::Option< + unsafe extern "C" fn( + arg1: *const ::std::os::raw::c_void, + arg2: *const ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int, + >, + ); } extern "C" { - pub fn drand48() -> f64; + pub fn rand() -> ::std::os::raw::c_int; } extern "C" { - pub fn erand48(__xsubi: *mut ::std::os::raw::c_ushort) -> f64; + pub fn srand(arg1: ::std::os::raw::c_uint); } extern "C" { - pub fn lrand48() -> ::std::os::raw::c_long; + pub fn strtod(arg1: *const ::std::os::raw::c_char, arg2: *mut *mut ::std::os::raw::c_char) -> f64; } extern "C" { - pub fn nrand48(__xsubi: *mut ::std::os::raw::c_ushort) -> ::std::os::raw::c_long; + pub fn strtof(arg1: *const ::std::os::raw::c_char, arg2: *mut *mut ::std::os::raw::c_char) -> f32; } extern "C" { - pub fn mrand48() -> ::std::os::raw::c_long; + pub fn strtol( + __str: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_long; } extern "C" { - pub fn jrand48(__xsubi: *mut ::std::os::raw::c_ushort) -> ::std::os::raw::c_long; + pub fn strtold(arg1: *const ::std::os::raw::c_char, arg2: *mut *mut ::std::os::raw::c_char) -> u128; } extern "C" { - pub fn srand48(__seedval: ::std::os::raw::c_long); + pub fn strtoll( + __str: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_longlong; } extern "C" { - pub fn seed48(__seed16v: *mut ::std::os::raw::c_ushort) -> *mut ::std::os::raw::c_ushort; + pub fn strtoul( + __str: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_ulong; } extern "C" { - pub fn lcong48(__param: *mut ::std::os::raw::c_ushort); + pub fn strtoull( + __str: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_ulonglong; } -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct drand48_data { - pub __x: [::std::os::raw::c_ushort; 3usize], - pub __old_x: [::std::os::raw::c_ushort; 3usize], - pub __c: ::std::os::raw::c_ushort, - pub __init: ::std::os::raw::c_ushort, - pub __a: ::std::os::raw::c_ulonglong, +extern "C" { + pub fn system(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; } -#[test] -fn bindgen_test_layout_drand48_data() { - assert_eq!( - ::std::mem::size_of::(), - 24usize, - concat!("Size of: ", stringify!(drand48_data)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(drand48_data)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).__x as *const _ as usize }, - 0usize, - concat!("Offset of field: ", stringify!(drand48_data), "::", stringify!(__x)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).__old_x as *const _ as usize }, - 6usize, - concat!("Offset of field: ", stringify!(drand48_data), "::", stringify!(__old_x)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).__c as *const _ as usize }, - 12usize, - concat!("Offset of field: ", stringify!(drand48_data), "::", stringify!(__c)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).__init as *const _ as usize }, - 14usize, - concat!("Offset of field: ", stringify!(drand48_data), "::", stringify!(__init)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).__a as *const _ as usize }, - 16usize, - concat!("Offset of field: ", stringify!(drand48_data), "::", stringify!(__a)) - ); +extern "C" { + pub fn wcstombs(arg1: *mut ::std::os::raw::c_char, arg2: *const wchar_t, arg3: size_t) -> size_t; } extern "C" { - pub fn drand48_r(__buffer: *mut drand48_data, __result: *mut f64) -> ::std::os::raw::c_int; + pub fn wctomb(arg1: *mut ::std::os::raw::c_char, arg2: wchar_t) -> ::std::os::raw::c_int; } extern "C" { - pub fn erand48_r( - __xsubi: *mut ::std::os::raw::c_ushort, - __buffer: *mut drand48_data, - __result: *mut f64, - ) -> ::std::os::raw::c_int; + pub fn _Exit(arg1: ::std::os::raw::c_int); } extern "C" { - pub fn lrand48_r(__buffer: *mut drand48_data, __result: *mut ::std::os::raw::c_long) -> ::std::os::raw::c_int; + pub fn a64l(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_long; } extern "C" { - pub fn nrand48_r( - __xsubi: *mut ::std::os::raw::c_ushort, - __buffer: *mut drand48_data, - __result: *mut ::std::os::raw::c_long, - ) -> ::std::os::raw::c_int; + pub fn drand48() -> f64; } extern "C" { - pub fn mrand48_r(__buffer: *mut drand48_data, __result: *mut ::std::os::raw::c_long) -> ::std::os::raw::c_int; + pub fn ecvt( + arg1: f64, + arg2: ::std::os::raw::c_int, + arg3: *mut ::std::os::raw::c_int, + arg4: *mut ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; } extern "C" { - pub fn jrand48_r( - __xsubi: *mut ::std::os::raw::c_ushort, - __buffer: *mut drand48_data, - __result: *mut ::std::os::raw::c_long, - ) -> ::std::os::raw::c_int; + pub fn erand48(arg1: *mut ::std::os::raw::c_ushort) -> f64; } extern "C" { - pub fn srand48_r(__seedval: ::std::os::raw::c_long, __buffer: *mut drand48_data) -> ::std::os::raw::c_int; + pub fn fcvt( + arg1: f64, + arg2: ::std::os::raw::c_int, + arg3: *mut ::std::os::raw::c_int, + arg4: *mut ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; } extern "C" { - pub fn seed48_r(__seed16v: *mut ::std::os::raw::c_ushort, __buffer: *mut drand48_data) -> ::std::os::raw::c_int; + pub fn gcvt( + arg1: f64, + arg2: ::std::os::raw::c_int, + arg3: *mut ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; } extern "C" { - pub fn lcong48_r(__param: *mut ::std::os::raw::c_ushort, __buffer: *mut drand48_data) -> ::std::os::raw::c_int; + pub fn getsubopt( + arg1: *mut *mut ::std::os::raw::c_char, + arg2: *const *mut ::std::os::raw::c_char, + arg3: *mut *mut ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; } extern "C" { - pub fn malloc(__size: ::std::os::raw::c_ulong) -> *mut ::std::os::raw::c_void; + pub fn grantpt(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; } extern "C" { - pub fn calloc(__nmemb: ::std::os::raw::c_ulong, __size: ::std::os::raw::c_ulong) -> *mut ::std::os::raw::c_void; + pub fn initstate( + arg1: ::std::os::raw::c_uint, + arg2: *mut ::std::os::raw::c_char, + arg3: size_t, + ) -> *mut ::std::os::raw::c_char; } extern "C" { - pub fn realloc(__ptr: *mut ::std::os::raw::c_void, __size: ::std::os::raw::c_ulong) -> *mut ::std::os::raw::c_void; + pub fn jrand48(arg1: *mut ::std::os::raw::c_ushort) -> ::std::os::raw::c_long; } extern "C" { - pub fn reallocarray( - __ptr: *mut ::std::os::raw::c_void, - __nmemb: size_t, - __size: size_t, - ) -> *mut ::std::os::raw::c_void; + pub fn l64a(arg1: ::std::os::raw::c_long) -> *mut ::std::os::raw::c_char; } extern "C" { - pub fn free(__ptr: *mut ::std::os::raw::c_void); + pub fn lcong48(arg1: *mut ::std::os::raw::c_ushort); } extern "C" { - pub fn alloca(__size: ::std::os::raw::c_ulong) -> *mut ::std::os::raw::c_void; + pub fn lrand48() -> ::std::os::raw::c_long; } extern "C" { - pub fn valloc(__size: size_t) -> *mut ::std::os::raw::c_void; + pub fn mktemp(arg1: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; } extern "C" { - pub fn posix_memalign( - __memptr: *mut *mut ::std::os::raw::c_void, - __alignment: size_t, - __size: size_t, - ) -> ::std::os::raw::c_int; + pub fn mkstemp(arg1: *mut ::std::os::raw::c_char) -> ::std::os::raw::c_int; } extern "C" { - pub fn aligned_alloc( - __alignment: ::std::os::raw::c_ulong, - __size: ::std::os::raw::c_ulong, - ) -> *mut ::std::os::raw::c_void; + pub fn mrand48() -> ::std::os::raw::c_long; } extern "C" { - pub fn abort(); + pub fn nrand48(arg1: *mut ::std::os::raw::c_ushort) -> ::std::os::raw::c_long; } extern "C" { - pub fn atexit(__func: ::std::option::Option) -> ::std::os::raw::c_int; + pub fn posix_openpt(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; } extern "C" { - pub fn at_quick_exit(__func: ::std::option::Option) -> ::std::os::raw::c_int; + pub fn ptsname(arg1: ::std::os::raw::c_int) -> *mut ::std::os::raw::c_char; } extern "C" { - pub fn on_exit( - __func: ::std::option::Option< - unsafe extern "C" fn(__status: ::std::os::raw::c_int, __arg: *mut ::std::os::raw::c_void), - >, - __arg: *mut ::std::os::raw::c_void, + pub fn ptsname_r( + fildes: ::std::os::raw::c_int, + buffer: *mut ::std::os::raw::c_char, + buflen: size_t, ) -> ::std::os::raw::c_int; } extern "C" { - pub fn exit(__status: ::std::os::raw::c_int); + pub fn putenv(arg1: *mut ::std::os::raw::c_char) -> ::std::os::raw::c_int; } extern "C" { - pub fn quick_exit(__status: ::std::os::raw::c_int); + pub fn random() -> ::std::os::raw::c_long; } extern "C" { - pub fn _Exit(__status: ::std::os::raw::c_int); + pub fn rand_r(arg1: *mut ::std::os::raw::c_uint) -> ::std::os::raw::c_int; } extern "C" { - pub fn getenv(__name: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; + pub fn realpath( + arg1: *const ::std::os::raw::c_char, + arg2: *mut ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; } extern "C" { - pub fn putenv(__string: *mut ::std::os::raw::c_char) -> ::std::os::raw::c_int; + pub fn seed48(arg1: *mut ::std::os::raw::c_ushort) -> *mut ::std::os::raw::c_ushort; } extern "C" { pub fn setenv( __name: *const ::std::os::raw::c_char, __value: *const ::std::os::raw::c_char, - __replace: ::std::os::raw::c_int, + __overwrite: ::std::os::raw::c_int, ) -> ::std::os::raw::c_int; } extern "C" { - pub fn unsetenv(__name: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; + pub fn setkey(arg1: *const ::std::os::raw::c_char); } extern "C" { - pub fn clearenv() -> ::std::os::raw::c_int; + pub fn setstate(arg1: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; } extern "C" { - pub fn mktemp(__template: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; + pub fn srand48(arg1: ::std::os::raw::c_long); } extern "C" { - pub fn mkstemp(__template: *mut ::std::os::raw::c_char) -> ::std::os::raw::c_int; + pub fn srandom(arg1: ::std::os::raw::c_uint); } extern "C" { - pub fn mkstemps( - __template: *mut ::std::os::raw::c_char, - __suffixlen: ::std::os::raw::c_int, - ) -> ::std::os::raw::c_int; + pub fn unlockpt(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; } extern "C" { - pub fn mkdtemp(__template: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; + pub fn unsetenv(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; } +pub type dev_t = __darwin_dev_t; +pub type mode_t = __darwin_mode_t; extern "C" { - pub fn system(__command: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; + pub fn arc4random() -> u32; } extern "C" { - pub fn realpath( - __name: *const ::std::os::raw::c_char, - __resolved: *mut ::std::os::raw::c_char, - ) -> *mut ::std::os::raw::c_char; + pub fn arc4random_addrandom(arg1: *mut ::std::os::raw::c_uchar, arg2: ::std::os::raw::c_int); } -pub type __compar_fn_t = ::std::option::Option< - unsafe extern "C" fn( - arg1: *const ::std::os::raw::c_void, - arg2: *const ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int, ->; extern "C" { - pub fn bsearch( + pub fn arc4random_buf(__buf: *mut ::std::os::raw::c_void, __nbytes: size_t); +} +extern "C" { + pub fn arc4random_stir(); +} +extern "C" { + pub fn arc4random_uniform(__upper_bound: u32) -> u32; +} +extern "C" { + pub fn atexit_b(arg1: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn bsearch_b( __key: *const ::std::os::raw::c_void, __base: *const ::std::os::raw::c_void, - __nmemb: size_t, - __size: size_t, - __compar: __compar_fn_t, + __nel: size_t, + __width: size_t, + __compar: *mut ::std::os::raw::c_void, ) -> *mut ::std::os::raw::c_void; } extern "C" { - pub fn qsort(__base: *mut ::std::os::raw::c_void, __nmemb: size_t, __size: size_t, __compar: __compar_fn_t); + pub fn cgetcap( + arg1: *mut ::std::os::raw::c_char, + arg2: *const ::std::os::raw::c_char, + arg3: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn cgetclose() -> ::std::os::raw::c_int; } extern "C" { - pub fn abs(__x: ::std::os::raw::c_int) -> ::std::os::raw::c_int; + pub fn cgetent( + arg1: *mut *mut ::std::os::raw::c_char, + arg2: *mut *mut ::std::os::raw::c_char, + arg3: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; } extern "C" { - pub fn labs(__x: ::std::os::raw::c_long) -> ::std::os::raw::c_long; + pub fn cgetfirst( + arg1: *mut *mut ::std::os::raw::c_char, + arg2: *mut *mut ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; } extern "C" { - pub fn llabs(__x: ::std::os::raw::c_longlong) -> ::std::os::raw::c_longlong; + pub fn cgetmatch(arg1: *const ::std::os::raw::c_char, arg2: *const ::std::os::raw::c_char) + -> ::std::os::raw::c_int; } extern "C" { - pub fn div(__numer: ::std::os::raw::c_int, __denom: ::std::os::raw::c_int) -> div_t; + pub fn cgetnext( + arg1: *mut *mut ::std::os::raw::c_char, + arg2: *mut *mut ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; } extern "C" { - pub fn ldiv(__numer: ::std::os::raw::c_long, __denom: ::std::os::raw::c_long) -> ldiv_t; + pub fn cgetnum( + arg1: *mut ::std::os::raw::c_char, + arg2: *const ::std::os::raw::c_char, + arg3: *mut ::std::os::raw::c_long, + ) -> ::std::os::raw::c_int; } extern "C" { - pub fn lldiv(__numer: ::std::os::raw::c_longlong, __denom: ::std::os::raw::c_longlong) -> lldiv_t; + pub fn cgetset(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; } extern "C" { - pub fn ecvt( - __value: f64, - __ndigit: ::std::os::raw::c_int, - __decpt: *mut ::std::os::raw::c_int, - __sign: *mut ::std::os::raw::c_int, - ) -> *mut ::std::os::raw::c_char; + pub fn cgetstr( + arg1: *mut ::std::os::raw::c_char, + arg2: *const ::std::os::raw::c_char, + arg3: *mut *mut ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; } extern "C" { - pub fn fcvt( - __value: f64, - __ndigit: ::std::os::raw::c_int, - __decpt: *mut ::std::os::raw::c_int, - __sign: *mut ::std::os::raw::c_int, - ) -> *mut ::std::os::raw::c_char; + pub fn cgetustr( + arg1: *mut ::std::os::raw::c_char, + arg2: *const ::std::os::raw::c_char, + arg3: *mut *mut ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; } extern "C" { - pub fn gcvt( - __value: f64, - __ndigit: ::std::os::raw::c_int, - __buf: *mut ::std::os::raw::c_char, - ) -> *mut ::std::os::raw::c_char; + pub fn daemon(arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int) -> ::std::os::raw::c_int; } extern "C" { - pub fn qecvt( - __value: u128, - __ndigit: ::std::os::raw::c_int, - __decpt: *mut ::std::os::raw::c_int, - __sign: *mut ::std::os::raw::c_int, - ) -> *mut ::std::os::raw::c_char; + pub fn devname(arg1: dev_t, arg2: mode_t) -> *mut ::std::os::raw::c_char; } extern "C" { - pub fn qfcvt( - __value: u128, - __ndigit: ::std::os::raw::c_int, - __decpt: *mut ::std::os::raw::c_int, - __sign: *mut ::std::os::raw::c_int, + pub fn devname_r( + arg1: dev_t, + arg2: mode_t, + buf: *mut ::std::os::raw::c_char, + len: ::std::os::raw::c_int, ) -> *mut ::std::os::raw::c_char; } extern "C" { - pub fn qgcvt( - __value: u128, - __ndigit: ::std::os::raw::c_int, - __buf: *mut ::std::os::raw::c_char, - ) -> *mut ::std::os::raw::c_char; + pub fn getbsize(arg1: *mut ::std::os::raw::c_int, arg2: *mut ::std::os::raw::c_long) + -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn getloadavg(arg1: *mut f64, arg2: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getprogname() -> *const ::std::os::raw::c_char; +} +extern "C" { + pub fn setprogname(arg1: *const ::std::os::raw::c_char); } extern "C" { - pub fn ecvt_r( - __value: f64, - __ndigit: ::std::os::raw::c_int, - __decpt: *mut ::std::os::raw::c_int, - __sign: *mut ::std::os::raw::c_int, - __buf: *mut ::std::os::raw::c_char, - __len: size_t, + pub fn heapsort( + __base: *mut ::std::os::raw::c_void, + __nel: size_t, + __width: size_t, + __compar: ::std::option::Option< + unsafe extern "C" fn( + arg1: *const ::std::os::raw::c_void, + arg2: *const ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int, + >, ) -> ::std::os::raw::c_int; } extern "C" { - pub fn fcvt_r( - __value: f64, - __ndigit: ::std::os::raw::c_int, - __decpt: *mut ::std::os::raw::c_int, - __sign: *mut ::std::os::raw::c_int, - __buf: *mut ::std::os::raw::c_char, - __len: size_t, + pub fn heapsort_b( + __base: *mut ::std::os::raw::c_void, + __nel: size_t, + __width: size_t, + __compar: *mut ::std::os::raw::c_void, ) -> ::std::os::raw::c_int; } extern "C" { - pub fn qecvt_r( - __value: u128, - __ndigit: ::std::os::raw::c_int, - __decpt: *mut ::std::os::raw::c_int, - __sign: *mut ::std::os::raw::c_int, - __buf: *mut ::std::os::raw::c_char, - __len: size_t, + pub fn mergesort( + __base: *mut ::std::os::raw::c_void, + __nel: size_t, + __width: size_t, + __compar: ::std::option::Option< + unsafe extern "C" fn( + arg1: *const ::std::os::raw::c_void, + arg2: *const ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int, + >, ) -> ::std::os::raw::c_int; } extern "C" { - pub fn qfcvt_r( - __value: u128, - __ndigit: ::std::os::raw::c_int, - __decpt: *mut ::std::os::raw::c_int, - __sign: *mut ::std::os::raw::c_int, - __buf: *mut ::std::os::raw::c_char, - __len: size_t, + pub fn mergesort_b( + __base: *mut ::std::os::raw::c_void, + __nel: size_t, + __width: size_t, + __compar: *mut ::std::os::raw::c_void, ) -> ::std::os::raw::c_int; } extern "C" { - pub fn mblen(__s: *const ::std::os::raw::c_char, __n: size_t) -> ::std::os::raw::c_int; + pub fn psort( + __base: *mut ::std::os::raw::c_void, + __nel: size_t, + __width: size_t, + __compar: ::std::option::Option< + unsafe extern "C" fn( + arg1: *const ::std::os::raw::c_void, + arg2: *const ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int, + >, + ); +} +extern "C" { + pub fn psort_b( + __base: *mut ::std::os::raw::c_void, + __nel: size_t, + __width: size_t, + __compar: *mut ::std::os::raw::c_void, + ); } extern "C" { - pub fn mbtowc(__pwc: *mut wchar_t, __s: *const ::std::os::raw::c_char, __n: size_t) -> ::std::os::raw::c_int; + pub fn psort_r( + __base: *mut ::std::os::raw::c_void, + __nel: size_t, + __width: size_t, + arg1: *mut ::std::os::raw::c_void, + __compar: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *const ::std::os::raw::c_void, + arg3: *const ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int, + >, + ); } extern "C" { - pub fn wctomb(__s: *mut ::std::os::raw::c_char, __wchar: wchar_t) -> ::std::os::raw::c_int; + pub fn qsort_b( + __base: *mut ::std::os::raw::c_void, + __nel: size_t, + __width: size_t, + __compar: *mut ::std::os::raw::c_void, + ); } extern "C" { - pub fn mbstowcs(__pwcs: *mut wchar_t, __s: *const ::std::os::raw::c_char, __n: size_t) -> size_t; + pub fn qsort_r( + __base: *mut ::std::os::raw::c_void, + __nel: size_t, + __width: size_t, + arg1: *mut ::std::os::raw::c_void, + __compar: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *const ::std::os::raw::c_void, + arg3: *const ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int, + >, + ); } extern "C" { - pub fn wcstombs(__s: *mut ::std::os::raw::c_char, __pwcs: *const wchar_t, __n: size_t) -> size_t; + pub fn radixsort( + __base: *mut *const ::std::os::raw::c_uchar, + __nel: ::std::os::raw::c_int, + __table: *const ::std::os::raw::c_uchar, + __endbyte: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; } extern "C" { - pub fn rpmatch(__response: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; + pub fn rpmatch(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; } extern "C" { - pub fn getsubopt( - __optionp: *mut *mut ::std::os::raw::c_char, - __tokens: *const *mut ::std::os::raw::c_char, - __valuep: *mut *mut ::std::os::raw::c_char, + pub fn sradixsort( + __base: *mut *const ::std::os::raw::c_uchar, + __nel: ::std::os::raw::c_int, + __table: *const ::std::os::raw::c_uchar, + __endbyte: ::std::os::raw::c_uint, ) -> ::std::os::raw::c_int; } extern "C" { - pub fn getloadavg(__loadavg: *mut f64, __nelem: ::std::os::raw::c_int) -> ::std::os::raw::c_int; + pub fn sranddev(); +} +extern "C" { + pub fn srandomdev(); +} +extern "C" { + pub fn reallocf(__ptr: *mut ::std::os::raw::c_void, __size: size_t) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn strtonum( + __numstr: *const ::std::os::raw::c_char, + __minval: ::std::os::raw::c_longlong, + __maxval: ::std::os::raw::c_longlong, + __errstrp: *mut *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_longlong; +} +extern "C" { + pub fn strtoq( + __str: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_longlong; +} +extern "C" { + pub fn strtouq( + __str: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_ulonglong; +} +extern "C" { + pub static mut suboptarg: *mut ::std::os::raw::c_char; } pub type idx_t = u64; pub const DUCKDB_TYPE_DUCKDB_TYPE_INVALID: DUCKDB_TYPE = 0; @@ -2410,10 +10731,10 @@ fn bindgen_test_layout_duckdb_blob() { #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct duckdb_column { - pub data: *mut ::std::os::raw::c_void, - pub nullmask: *mut bool, - pub type_: duckdb_type, - pub name: *mut ::std::os::raw::c_char, + pub __deprecated_data: *mut ::std::os::raw::c_void, + pub __deprecated_nullmask: *mut bool, + pub __deprecated_type: duckdb_type, + pub __deprecated_name: *mut ::std::os::raw::c_char, pub internal_data: *mut ::std::os::raw::c_void, } #[test] @@ -2429,29 +10750,44 @@ fn bindgen_test_layout_duckdb_column() { concat!("Alignment of ", stringify!(duckdb_column)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).data as *const _ as usize }, + unsafe { &(*(::std::ptr::null::())).__deprecated_data as *const _ as usize }, 0usize, - concat!("Offset of field: ", stringify!(duckdb_column), "::", stringify!(data)) + concat!( + "Offset of field: ", + stringify!(duckdb_column), + "::", + stringify!(__deprecated_data) + ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).nullmask as *const _ as usize }, + unsafe { &(*(::std::ptr::null::())).__deprecated_nullmask as *const _ as usize }, 8usize, concat!( "Offset of field: ", stringify!(duckdb_column), "::", - stringify!(nullmask) + stringify!(__deprecated_nullmask) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).type_ as *const _ as usize }, + unsafe { &(*(::std::ptr::null::())).__deprecated_type as *const _ as usize }, 16usize, - concat!("Offset of field: ", stringify!(duckdb_column), "::", stringify!(type_)) + concat!( + "Offset of field: ", + stringify!(duckdb_column), + "::", + stringify!(__deprecated_type) + ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).name as *const _ as usize }, + unsafe { &(*(::std::ptr::null::())).__deprecated_name as *const _ as usize }, 24usize, - concat!("Offset of field: ", stringify!(duckdb_column), "::", stringify!(name)) + concat!( + "Offset of field: ", + stringify!(duckdb_column), + "::", + stringify!(__deprecated_name) + ) ); assert_eq!( unsafe { &(*(::std::ptr::null::())).internal_data as *const _ as usize }, @@ -2467,11 +10803,11 @@ fn bindgen_test_layout_duckdb_column() { #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct duckdb_result { - pub column_count: idx_t, - pub row_count: idx_t, - pub rows_changed: idx_t, - pub columns: *mut duckdb_column, - pub error_message: *mut ::std::os::raw::c_char, + pub __deprecated_column_count: idx_t, + pub __deprecated_row_count: idx_t, + pub __deprecated_rows_changed: idx_t, + pub __deprecated_columns: *mut duckdb_column, + pub __deprecated_error_message: *mut ::std::os::raw::c_char, pub internal_data: *mut ::std::os::raw::c_void, } #[test] @@ -2487,53 +10823,53 @@ fn bindgen_test_layout_duckdb_result() { concat!("Alignment of ", stringify!(duckdb_result)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).column_count as *const _ as usize }, + unsafe { &(*(::std::ptr::null::())).__deprecated_column_count as *const _ as usize }, 0usize, concat!( "Offset of field: ", stringify!(duckdb_result), "::", - stringify!(column_count) + stringify!(__deprecated_column_count) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).row_count as *const _ as usize }, + unsafe { &(*(::std::ptr::null::())).__deprecated_row_count as *const _ as usize }, 8usize, concat!( "Offset of field: ", stringify!(duckdb_result), "::", - stringify!(row_count) + stringify!(__deprecated_row_count) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).rows_changed as *const _ as usize }, + unsafe { &(*(::std::ptr::null::())).__deprecated_rows_changed as *const _ as usize }, 16usize, concat!( "Offset of field: ", stringify!(duckdb_result), "::", - stringify!(rows_changed) + stringify!(__deprecated_rows_changed) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).columns as *const _ as usize }, + unsafe { &(*(::std::ptr::null::())).__deprecated_columns as *const _ as usize }, 24usize, concat!( "Offset of field: ", stringify!(duckdb_result), "::", - stringify!(columns) + stringify!(__deprecated_columns) ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).error_message as *const _ as usize }, + unsafe { &(*(::std::ptr::null::())).__deprecated_error_message as *const _ as usize }, 32usize, concat!( "Offset of field: ", stringify!(duckdb_result), "::", - stringify!(error_message) + stringify!(__deprecated_error_message) ) ); assert_eq!( @@ -3384,3 +11720,65 @@ extern "C" { #[doc = " result: The result to destroy."] pub fn duckdb_destroy_arrow(result: *mut duckdb_arrow); } +pub type __builtin_va_list = [__va_list_tag; 1usize]; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __va_list_tag { + pub gp_offset: ::std::os::raw::c_uint, + pub fp_offset: ::std::os::raw::c_uint, + pub overflow_arg_area: *mut ::std::os::raw::c_void, + pub reg_save_area: *mut ::std::os::raw::c_void, +} +#[test] +fn bindgen_test_layout___va_list_tag() { + assert_eq!( + ::std::mem::size_of::<__va_list_tag>(), + 24usize, + concat!("Size of: ", stringify!(__va_list_tag)) + ); + assert_eq!( + ::std::mem::align_of::<__va_list_tag>(), + 8usize, + concat!("Alignment of ", stringify!(__va_list_tag)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__va_list_tag>())).gp_offset as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__va_list_tag), + "::", + stringify!(gp_offset) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__va_list_tag>())).fp_offset as *const _ as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(__va_list_tag), + "::", + stringify!(fp_offset) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__va_list_tag>())).overflow_arg_area as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(__va_list_tag), + "::", + stringify!(overflow_arg_area) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__va_list_tag>())).reg_save_area as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(__va_list_tag), + "::", + stringify!(reg_save_area) + ) + ); +} diff --git a/libduckdb-sys/duckdb/duckdb.cpp b/libduckdb-sys/duckdb/duckdb.cpp index 99f68d67..4789c3dc 100644 --- a/libduckdb-sys/duckdb/duckdb.cpp +++ b/libduckdb-sys/duckdb/duckdb.cpp @@ -33,18 +33,27 @@ class ClientContext; //! The schema search path, in order by which entries are searched if no schema entry is provided class CatalogSearchPath { public: - explicit CatalogSearchPath(ClientContext &client_p); + DUCKDB_API explicit CatalogSearchPath(ClientContext &client_p); CatalogSearchPath(const CatalogSearchPath &other) = delete; - const vector &Get(); - const string &GetDefault(); - const string &GetOrDefault(const string &name); + DUCKDB_API void Set(const string &new_value, bool is_set_schema); + 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); private: static vector ParsePaths(const string &value); + + void SetPaths(vector new_paths); + +private: ClientContext &context; - string last_value; vector paths; + //! Only the paths that were explicitly set (minus the always included paths) + vector set_paths; }; } // namespace duckdb @@ -283,121 +292,6 @@ enum class IndexType { -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/tableref.hpp -// -// -//===----------------------------------------------------------------------===// - - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/enums/tableref_type.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -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 -}; - -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/parsed_data/sample_options.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - - - -namespace duckdb { - -enum class SampleMethod : uint8_t { SYSTEM_SAMPLE = 0, BERNOULLI_SAMPLE = 1, RESERVOIR_SAMPLE = 2 }; - -string SampleMethodToString(SampleMethod method); - -struct SampleOptions { - Value sample_size; - bool is_percentage; - SampleMethod method; - int64_t seed = -1; - - unique_ptr Copy(); - void Serialize(Serializer &serializer); - static unique_ptr Deserialize(Deserializer &source); - static bool Equals(SampleOptions *a, SampleOptions *b); -}; - -} // namespace duckdb - - -namespace duckdb { -class Deserializer; -class Serializer; - -//! Represents a generic expression that returns a table. -class TableRef { -public: - explicit TableRef(TableReferenceType type) : type(type) { - } - virtual ~TableRef() { - } - - TableReferenceType type; - string alias; - //! Sample options (if any) - unique_ptr sample; - //! The location in the query (if any) - idx_t query_location = INVALID_INDEX; - -public: - //! Convert the object to a string - virtual string ToString() const; - void Print(); - - virtual bool Equals(const TableRef *other) const; - - virtual unique_ptr Copy() = 0; - - //! Serializes a TableRef to a stand-alone binary blob - virtual void Serialize(Serializer &serializer); - //! Deserializes a blob back into a TableRef - static unique_ptr Deserialize(Deserializer &source); - - //! Copy the properties of this table ref to the target - void CopyProperties(TableRef &target) const; -}; -} // namespace duckdb @@ -412,7 +306,7 @@ class BaseTableRef : public TableRef { string schema_name; //! Table name string table_name; - //! Alises for the column names + //! Aliases for the column names vector column_name_alias; public: @@ -422,9 +316,9 @@ class BaseTableRef : public TableRef { unique_ptr Copy() override; //! Serializes a blob into a BaseTableRef - void Serialize(Serializer &serializer) override; + void Serialize(FieldWriter &serializer) const override; //! Deserializes a blob back into a BaseTableRef - static unique_ptr Deserialize(Deserializer &source); + static unique_ptr Deserialize(FieldReader &source); }; } // namespace duckdb @@ -511,1067 +405,6 @@ class IndexCatalogEntry : public StandardEntry { -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/binder.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/tokens.hpp -// -// -//===----------------------------------------------------------------------===// - - - -namespace duckdb { - -//===--------------------------------------------------------------------===// -// Statements -//===--------------------------------------------------------------------===// -class SQLStatement; - -class AlterStatement; -class CallStatement; -class CopyStatement; -class CreateStatement; -class DeleteStatement; -class DropStatement; -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; - -//===--------------------------------------------------------------------===// -// Query Node -//===--------------------------------------------------------------------===// -class QueryNode; -class SelectNode; -class SetOperationNode; -class RecursiveCTENode; - -//===--------------------------------------------------------------------===// -// Expressions -//===--------------------------------------------------------------------===// -class ParsedExpression; - -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; - -//===--------------------------------------------------------------------===// -// Constraints -//===--------------------------------------------------------------------===// -class Constraint; - -class NotNullConstraint; -class CheckConstraint; -class UniqueConstraint; - -//===--------------------------------------------------------------------===// -// TableRefs -//===--------------------------------------------------------------------===// -class TableRef; - -class BaseTableRef; -class CrossProductRef; -class JoinRef; -class SubqueryRef; -class TableFunctionRef; -class EmptyTableRef; -class ExpressionListRef; - -//===--------------------------------------------------------------------===// -// Other -//===--------------------------------------------------------------------===// -struct SampleOptions; - -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/bind_context.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -//===----------------------------------------------------------------------===// -// 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: - TableFunctionCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateTableFunctionInfo *info); - - //! The table function - vector functions; -}; -} // namespace duckdb - - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/expression/columnref_expression.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -namespace duckdb { - -//! 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); - - //! Column name that is referenced - string column_name; - //! Table name of the column name that is referenced (optional) - string table_name; - -public: - bool IsScalar() const override { - return false; - } - - string GetName() const override; - string ToString() const override; - - static bool Equals(const ColumnRefExpression *a, const ColumnRefExpression *b); - hash_t Hash() const override; - - unique_ptr Copy() const override; - - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(ExpressionType type, Deserializer &source); -}; -} // namespace duckdb - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/qualified_name_set.hpp -// -// -//===----------------------------------------------------------------------===// - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/qualified_name.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - -namespace duckdb { - -struct QualifiedName { - 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(string input) { - string schema; - string name; - idx_t idx = 0; - vector entries; - string entry; - normal: - //! quote - for (; idx < input.size(); idx++) { - if (input[idx] == '"') { - idx++; - goto quoted; - } else if (input[idx] == '.') { - goto separator; - } - entry += input[idx]; - } - goto end; - separator: - entries.push_back(entry); - entry = ""; - idx++; - goto normal; - 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!"); - end: - if (entries.empty()) { - schema = INVALID_SCHEMA; - name = entry; - } else if (entries.size() == 1) { - schema = entries[0]; - name = entry; - } else { - throw ParserException("Expected schema.entry or entry: too many entries found"); - } - return QualifiedName {schema, name}; - } -}; - -struct QualifiedColumnName { - QualifiedColumnName() { - } - QualifiedColumnName(string table_p, string column_p) : table(move(table_p)), column(move(column_p)) { - } - - string schema; - string table; - string column; -}; - -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/types/hash.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - -namespace duckdb { - -struct string_t; - -// efficient hash function that maximizes the avalanche effect and minimizes -// bias -// see: https://nullprogram.com/blog/2018/07/31/ - -inline hash_t murmurhash64(uint64_t x) { - return x * UINT64_C(0xbf58476d1ce4e5b9); -} - -inline hash_t murmurhash32(uint32_t x) { - return murmurhash64(x); -} - -template -hash_t Hash(T value) { - return murmurhash32(value); -} - -//! Combine two hashes by XORing them -inline hash_t CombineHash(hash_t left, hash_t right) { - return left ^ right; -} - -template <> -hash_t Hash(uint64_t val); -template <> -hash_t Hash(int64_t val); -template <> -hash_t Hash(hugeint_t val); -template <> -hash_t Hash(float val); -template <> -hash_t Hash(double val); -template <> -hash_t Hash(const char *val); -template <> -hash_t Hash(char *val); -template <> -hash_t Hash(string_t val); -template <> -hash_t Hash(interval_t val); -hash_t Hash(const char *val, size_t size); -hash_t Hash(uint8_t *val, size_t size); - -} // namespace duckdb - - - -namespace duckdb { - -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); - } -}; - -struct QualifiedColumnEquality { - bool operator()(const QualifiedColumnName &a, const QualifiedColumnName &b) const { - return a.schema == b.schema && a.table == b.table && a.column == b.column; - } -}; - -using qualified_column_set_t = unordered_set; - -} // namespace duckdb - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/expression_binder.hpp -// -// -//===----------------------------------------------------------------------===// - - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/expression/bound_expression.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - - -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) - : ParsedExpression(ExpressionType::INVALID, ExpressionClass::BOUND_EXPRESSION), expr(move(expr)) { - } - - unique_ptr expr; - -public: - string ToString() const override { - return expr->ToString(); - } - - bool Equals(const BaseExpression *other) const override { - return false; - } - hash_t Hash() const override { - return 0; - } - - unique_ptr Copy() const override { - throw SerializationException("Cannot copy or serialize bound expression"); - } -}; - -} // namespace duckdb - - - - - - -namespace duckdb { - -class Binder; -class ClientContext; -class QueryNode; - -class ScalarFunctionCatalogEntry; -class AggregateFunctionCatalogEntry; -class MacroCatalogEntry; -class CatalogEntry; -class SimpleFunction; - -struct MacroBinding; - -struct BoundColumnReferenceInfo { - string name; - idx_t query_location; -}; - -struct BindResult { - explicit BindResult(string error) : error(error) { - } - explicit BindResult(unique_ptr expr) : expression(move(expr)) { - } - - bool HasError() { - return !error.empty(); - } - - unique_ptr expression; - string error; -}; - -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; - -public: - unique_ptr Bind(unique_ptr &expr, LogicalType *result_type = nullptr, - bool root_expression = true); - - //! 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; - } - - string Bind(unique_ptr *expr, idx_t depth, bool root_expression = false); - - // Bind table names to ColumnRefExpressions - static void BindTableNames(Binder &binder, ParsedExpression &expr, - unordered_map *alias_map = nullptr); - static unique_ptr PushCollation(ClientContext &context, unique_ptr source, - const string &collation, bool equality_only = false); - static void TestCollation(ClientContext &context, const string &collation); - - bool BindCorrelatedColumns(unique_ptr &expr); - - void BindChild(unique_ptr &expr, idx_t depth, string &error); - static void ExtractCorrelatedExpressions(Binder &binder, Expression &expr); - - 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); - - static void ResolveParameterType(LogicalType &type); - static void ResolveParameterType(unique_ptr &expr); - - //! 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); - -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); - BindResult BindExpression(OperatorExpression &expr, idx_t depth); - BindResult BindExpression(ParameterExpression &expr, idx_t depth); - BindResult BindExpression(PositionalReferenceExpression &ref, idx_t depth); - BindResult BindExpression(StarExpression &expr, idx_t depth); - BindResult BindExpression(SubqueryExpression &expr, idx_t depth); - -protected: - virtual BindResult BindGroupingFunction(OperatorExpression &op, idx_t depth); - virtual BindResult BindFunction(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, MacroCatalogEntry *macro, idx_t depth, - unique_ptr *expr_ptr); - - virtual void ReplaceMacroParametersRecursive(unique_ptr &expr); - virtual void ReplaceMacroParametersRecursive(ParsedExpression &expr, QueryNode &node); - virtual void ReplaceMacroParametersRecursive(ParsedExpression &expr, TableRef &ref); - - virtual string UnsupportedAggregateMessage(); - virtual string UnsupportedUnnestMessage(); - - Binder &binder; - ClientContext &context; - ExpressionBinder *stored_binder; - MacroBinding *macro_binding; - vector bound_columns; -}; - -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/table_binding.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - - - - -namespace duckdb { -class BindContext; -class BoundQueryNode; -class ColumnRefExpression; -class SubqueryRef; -class LogicalGet; -class TableCatalogEntry; -class TableFunctionCatalogEntry; -class BoundTableFunction; - -//! A Binding represents a binding to a table, table-producing function or subquery with a specified table index. -struct Binding { - Binding(const string &alias, vector types, vector names, idx_t index); - virtual ~Binding() = default; - - //! 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; - -public: - bool TryGetBindingIndex(const string &column_name, column_t &column_index); - bool HasMatchingBinding(const string &column_name); - virtual BindResult Bind(ColumnRefExpression &colref, idx_t depth); -}; - -//! 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, LogicalGet &get, idx_t index, - bool add_row_id = false); - - //! the underlying LogicalGet - LogicalGet &get; - -public: - BindResult Bind(ColumnRefExpression &colref, idx_t depth) override; -}; - -//! MacroBinding is like the Binding, except the alias and index are set by default. Used for binding Macro -//! Params/Arguments. -struct MacroBinding : public Binding { - MacroBinding(vector types_p, vector names_p, string macro_name); - - //! Arguments - vector> arguments; - //! The name of the macro - string macro_name; - -public: - BindResult Bind(ColumnRefExpression &colref, idx_t depth) override; - - //! Given the parameter colref, returns a copy of the argument that was supplied for this parameter - unique_ptr ParamToArg(ColumnRefExpression &colref); -}; - -} // namespace duckdb - - -namespace duckdb { -class Binder; -class LogicalGet; -class BoundQueryNode; - -class StarExpression; - -struct UsingColumnSet { - string primary_binding; - unordered_set bindings; -}; - -//! 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; - -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); - - 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); - - //! 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; - } - - //! 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, - LogicalGet &get); - //! 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, LogicalGet &get); - //! Adds a subquery with a given alias to the BindContext. - void AddSubquery(idx_t index, const string &alias, SubqueryRef &ref, BoundQueryNode &subquery); - //! 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); - - //! 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); - - //! Add an implicit join condition (e.g. USING (x)) - void AddUsingBinding(const string &column_name, UsingColumnSet *set); - - void AddUsingBindingSet(unique_ptr set); - - //! 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); - - //! 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); - - case_insensitive_map_t> GetCTEBindings() { - return cte_bindings; - } - void SetCTEBindings(case_insensitive_map_t> bindings) { - cte_bindings = bindings; - } - - //! 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); - - //! Add all the bindings from a BindContext to this BindContext. The other BindContext is destroyed in the process. - void AddContext(BindContext other); - -private: - void AddBinding(const string &alias, unique_ptr binding); - //! 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); - -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 set of CTE bindings - case_insensitive_map_t> cte_bindings; -}; -} // namespace duckdb - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/expression/bound_columnref_expression.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - -namespace duckdb { - -//! 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); - - //! 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; - -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; -}; -} // namespace duckdb - - - - - -namespace duckdb { -class BoundResultModifier; -class BoundSelectNode; -class ClientContext; -class ExpressionBinder; -class LimitModifier; -class OrderBinder; -class TableCatalogEntry; -class ViewCatalogEntry; - -struct CreateInfo; -struct BoundCreateTableInfo; -struct BoundCreateFunctionInfo; -struct CommonTableExpressionInfo; - -struct CorrelatedColumnInfo { - ColumnBinding binding; - LogicalType type; - string name; - idx_t depth; - - explicit CorrelatedColumnInfo(BoundColumnRefExpression &expr) - : binding(expr.binding), type(expr.return_type), name(expr.GetName()), depth(expr.depth) { - } - - 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; - -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 - vector *parameters; - //! Whether or not the bound statement is read-only - bool read_only; - //! Whether or not the statement requires a valid transaction to run - bool requires_valid_transaction; - //! Whether or not the statement can be streamed to the client - bool allow_stream_result; - //! The alias for the currently processing subquery, if it exists - string alias; - //! Macro parameter bindings (if any) - MacroBinding *macro_binding = 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(unordered_map &types, unordered_map &values, - QueryErrorContext &error_context, string &func_name); - - unique_ptr Bind(TableRef &ref); - unique_ptr CreatePlan(BoundTableRef &ref); - - //! Generates an unused index for a table - idx_t GenerateTableIndex(); - - //! 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); - - bool CTEIsAlreadyBound(CommonTableExpressionInfo *cte); - - 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); - - string FormatError(ParsedExpression &expr_context, const string &message); - string FormatError(TableRef &ref_context, const string &message); - - 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...); - } - - 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 = ""); - -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; - -private: - //! Bind the default values of the columns of a table - void BindDefaultValues(vector &columns, vector> &bound_defaults); - //! Bind a delimiter value (LIMIT or OFFSET) - unique_ptr BindDelimiter(ClientContext &context, unique_ptr delimiter, - int64_t &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(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(SetStatement &stmt); - BoundStatement Bind(LoadStatement &stmt); - - unique_ptr BindNode(SelectNode &node); - unique_ptr BindNode(SetOperationNode &node); - unique_ptr BindNode(RecursiveCTENode &node); - unique_ptr BindNode(QueryNode &node); - - 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); - - 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); - - bool BindFunctionParameters(vector> &expressions, vector &arguments, - vector ¶meters, unordered_map &named_parameters, - unique_ptr &subquery, string &error); - - 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); - - unique_ptr BindTable(TableCatalogEntry &table, BaseTableRef &ref); - unique_ptr BindView(ViewCatalogEntry &view, BaseTableRef &ref); - unique_ptr BindTableOrView(BaseTableRef &ref); - - 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(LimitModifier &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); - - string FindBinding(const string &using_column, const string &join_side); - bool TryFindBinding(const string &using_column, const string &join_side, string &result); - - void AddUsingBindingSet(unique_ptr set); - string RetrieveUsingBinding(Binder ¤t_binder, UsingColumnSet *current_set, const string &column_name, - const string &join_side, UsingColumnSet *new_set); - -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); -}; - -} // namespace duckdb @@ -1691,7 +524,7 @@ class MacroCatalogEntry : public StandardEntry { namespace duckdb { -enum class PragmaType : uint8_t { PRAGMA_STATEMENT, PRAGMA_ASSIGNMENT, PRAGMA_CALL }; +enum class PragmaType : uint8_t { PRAGMA_STATEMENT, PRAGMA_CALL }; struct PragmaInfo : public ParseInfo { //! Name of the PRAGMA statement @@ -1699,7 +532,7 @@ struct PragmaInfo : public ParseInfo { //! Parameter list (if any) vector parameters; //! Named parameter list (if any) - unordered_map named_parameters; + named_parameter_map_t named_parameters; public: unique_ptr Copy() const { @@ -1729,33 +562,28 @@ typedef void (*pragma_function_t)(ClientContext &context, const FunctionParamete //! -> 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 -//! * Assignment: value assignment, e.g. PRAGMA memory_limit='8GB' -//! -> assignments take a single parameter -//! -> assignments can also be called through SET memory_limit='8GB' //! Pragma functions can either return a new query to execute (pragma_query_t) //! or they can class PragmaFunction : public SimpleNamedParameterFunction { public: // Call - static PragmaFunction PragmaCall(const string &name, pragma_query_t query, vector arguments, - LogicalType varargs = LogicalType::INVALID); - static PragmaFunction PragmaCall(const string &name, pragma_function_t function, vector arguments, - LogicalType varargs = LogicalType::INVALID); + 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 - static PragmaFunction PragmaStatement(const string &name, pragma_query_t query); - static PragmaFunction PragmaStatement(const string &name, pragma_function_t function); - // Assignment - static PragmaFunction PragmaAssignment(const string &name, pragma_query_t query, LogicalType type); - static PragmaFunction PragmaAssignment(const string &name, pragma_function_t function, LogicalType type); + DUCKDB_API static PragmaFunction PragmaStatement(const string &name, pragma_query_t query); + DUCKDB_API static PragmaFunction PragmaStatement(const string &name, pragma_function_t function); - string ToString() override; + DUCKDB_API string ToString() override; public: PragmaType type; pragma_query_t query; pragma_function_t function; - unordered_map named_parameters; + named_parameter_type_map_t named_parameters; private: PragmaFunction(string name, PragmaType pragma_type, pragma_query_t query, pragma_function_t function, @@ -1853,121 +681,6 @@ class ScalarFunctionCatalogEntry : public StandardEntry { } // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/catalog/catalog_entry/sequence_catalog_entry.hpp -// -// -//===----------------------------------------------------------------------===// - - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/parsed_data/create_sequence_info.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - -namespace duckdb { - -struct CreateSequenceInfo : public CreateInfo { - CreateSequenceInfo() - : CreateInfo(CatalogType::SEQUENCE_ENTRY, INVALID_SCHEMA), name(string()), usage_count(0), increment(1), - min_value(1), max_value(NumericLimits::Maximum()), start_value(1), cycle(false) { - } - - //! Sequence name to create - string name; - //! Usage count of the sequence - uint64_t usage_count; - //! The increment value - int64_t increment; - //! The minimum value of the sequence - int64_t min_value; - //! The maximum value of the sequence - int64_t max_value; - //! The start value of the sequence - int64_t start_value; - //! Whether or not the sequence cycles - bool cycle; - -public: - unique_ptr Copy() const override { - auto result = make_unique(); - CopyProperties(*result); - result->name = name; - result->schema = schema; - result->usage_count = usage_count; - result->increment = increment; - result->min_value = min_value; - result->max_value = max_value; - result->start_value = start_value; - result->cycle = cycle; - return move(result); - } -}; - -} // namespace duckdb - - - -namespace duckdb { -class Serializer; -class Deserializer; - -struct SequenceValue { - SequenceValue() : usage_count(0), counter(-1) { - } - SequenceValue(uint64_t usage_count, int64_t counter) : usage_count(usage_count), counter(counter) { - } - - uint64_t usage_count; - int64_t counter; -}; - -//! A sequence catalog entry -class SequenceCatalogEntry : public StandardEntry { -public: - //! Create a real TableCatalogEntry and initialize storage for it - SequenceCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateSequenceInfo *info); - - //! Lock for getting a value on the sequence - mutex lock; - //! The amount of times the sequence has been used - uint64_t usage_count; - //! The sequence counter - int64_t counter; - //! The most recently returned value - int64_t last_value; - //! The increment value - int64_t increment; - //! The minimum value of the sequence - int64_t start_value; - //! The minimum value of the sequence - int64_t min_value; - //! The maximum value of the sequence - int64_t max_value; - //! Whether or not the sequence cycles - bool cycle; - -public: - //! Serialize the meta information of the SequenceCatalogEntry a serializer - virtual void Serialize(Serializer &serializer); - //! Deserializes to a CreateTableInfo - static unique_ptr Deserialize(Deserializer &source); - - string ToSQL() override; -}; -} // namespace duckdb @@ -1982,128 +695,6 @@ class SequenceCatalogEntry : public StandardEntry { -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/statement/select_statement.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/query_node.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/common_table_expression_info.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -namespace duckdb { - -class SelectStatement; - -struct CommonTableExpressionInfo { - vector aliases; - unique_ptr query; -}; - -} // namespace duckdb - - -namespace duckdb { - -enum QueryNodeType : uint8_t { - SELECT_NODE = 1, - SET_OPERATION_NODE = 2, - BOUND_SUBQUERY_NODE = 3, - RECURSIVE_CTE_NODE = 4 -}; - -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) - unordered_map> cte_map; - - virtual const vector> &GetSelectList() const = 0; - -public: - virtual bool Equals(const QueryNode *other) const; - - //! Create a copy of this QueryNode - virtual unique_ptr Copy() = 0; - //! Serializes a QueryNode to a stand-alone binary blob - virtual void Serialize(Serializer &serializer); - //! Deserializes a blob back into a QueryNode, returns nullptr if - //! deserialization is not possible - static unique_ptr Deserialize(Deserializer &source); - -protected: - //! Copy base QueryNode properties from another expression to this one, - //! used in Copy method - void CopyProperties(QueryNode &other) const; -}; - -} // namespace duckdb - - - - -namespace duckdb { - -class QueryNode; - -//! SelectStatement is a typical SELECT clause -class SelectStatement : public SQLStatement { -public: - SelectStatement() : SQLStatement(StatementType::SELECT_STATEMENT) { - } - - //! The main query node - unique_ptr node; - -public: - //! Create a copy of this SelectStatement - unique_ptr Copy() const override; - //! Serializes a SelectStatement to a stand-alone binary blob - void Serialize(Serializer &serializer); - //! 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 @@ -2201,7 +792,12 @@ class DefaultSchemaGenerator : public DefaultGenerator { namespace duckdb { class CatalogEntry; -enum class DependencyType { DEPENDENCY_REGULAR = 0, DEPENDENCY_AUTOMATIC = 1 }; +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) @@ -2252,18 +848,20 @@ class DependencyManager { //! 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 wel + //! 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, set_lock_map_t &lock_set); + void DropObject(ClientContext &context, CatalogEntry *object, bool cascade); void AlterObject(ClientContext &context, CatalogEntry *old_obj, CatalogEntry *new_obj); void EraseObjectInternal(CatalogEntry *object); }; @@ -2320,251 +918,11 @@ class FunctionExpression : public ParsedExpression { static bool Equals(const FunctionExpression *a, const FunctionExpression *b); hash_t Hash() const override; - //! Serializes a FunctionExpression to a stand-alone binary blob - void Serialize(Serializer &serializer) override; - //! Deserializes a blob back into an FunctionExpression - static unique_ptr Deserialize(ExpressionType type, Deserializer &source); + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(ExpressionType type, FieldReader &source); }; } // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/parsed_data/alter_table_info.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - - -namespace duckdb { - -enum class AlterType : uint8_t { INVALID = 0, ALTER_TABLE = 1, ALTER_VIEW = 2 }; - -struct AlterInfo : public ParseInfo { - AlterInfo(AlterType type, string schema, string name) : type(type), schema(schema), name(name) { - } - ~AlterInfo() override { - } - - AlterType type; - //! Schema name to alter - string schema; - //! Entry name to alter - string name; - -public: - virtual CatalogType GetCatalogType() = 0; - virtual unique_ptr Copy() const = 0; - virtual void Serialize(Serializer &serializer); - static unique_ptr Deserialize(Deserializer &source); -}; - -//===--------------------------------------------------------------------===// -// Alter Table -//===--------------------------------------------------------------------===// -enum class AlterTableType : uint8_t { - INVALID = 0, - RENAME_COLUMN = 1, - RENAME_TABLE = 2, - ADD_COLUMN = 3, - REMOVE_COLUMN = 4, - ALTER_COLUMN_TYPE = 5, - SET_DEFAULT = 6 -}; - -struct AlterTableInfo : public AlterInfo { - AlterTableInfo(AlterTableType type, string schema, string table) - : AlterInfo(AlterType::ALTER_TABLE, schema, table), alter_table_type(type) { - } - ~AlterTableInfo() override { - } - - AlterTableType alter_table_type; - -public: - CatalogType GetCatalogType() override { - return CatalogType::TABLE_ENTRY; - } - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(Deserializer &source); -}; - -//===--------------------------------------------------------------------===// -// RenameColumnInfo -//===--------------------------------------------------------------------===// -struct RenameColumnInfo : public AlterTableInfo { - RenameColumnInfo(string schema, string table, string old_name_p, string new_name_p) - : AlterTableInfo(AlterTableType::RENAME_COLUMN, move(schema), move(table)), old_name(move(old_name_p)), - new_name(move(new_name_p)) { - } - ~RenameColumnInfo() override { - } - - //! Column old name - string old_name; - //! Column new name - string new_name; - -public: - unique_ptr Copy() const override; - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(Deserializer &source, string schema, string table); -}; - -//===--------------------------------------------------------------------===// -// RenameTableInfo -//===--------------------------------------------------------------------===// -struct RenameTableInfo : public AlterTableInfo { - RenameTableInfo(string schema, string table, string new_name) - : AlterTableInfo(AlterTableType::RENAME_TABLE, schema, table), new_table_name(new_name) { - } - ~RenameTableInfo() override { - } - - //! Relation new name - string new_table_name; - -public: - unique_ptr Copy() const override; - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(Deserializer &source, string schema, string table); -}; - -//===--------------------------------------------------------------------===// -// AddColumnInfo -//===--------------------------------------------------------------------===// -struct AddColumnInfo : public AlterTableInfo { - AddColumnInfo(string schema, string table, ColumnDefinition new_column) - : AlterTableInfo(AlterTableType::ADD_COLUMN, schema, table), new_column(move(new_column)) { - } - ~AddColumnInfo() override { - } - - //! New column - ColumnDefinition new_column; - -public: - unique_ptr Copy() const override; - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(Deserializer &source, string schema, string table); -}; - -//===--------------------------------------------------------------------===// -// RemoveColumnInfo -//===--------------------------------------------------------------------===// -struct RemoveColumnInfo : public AlterTableInfo { - RemoveColumnInfo(string schema, string table, string removed_column, bool if_exists) - : AlterTableInfo(AlterTableType::REMOVE_COLUMN, schema, table), removed_column(move(removed_column)), - if_exists(if_exists) { - } - ~RemoveColumnInfo() override { - } - - //! The column to remove - string removed_column; - //! Whether or not an error should be thrown if the column does not exist - bool if_exists; - -public: - unique_ptr Copy() const override; - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(Deserializer &source, string schema, string table); -}; - -//===--------------------------------------------------------------------===// -// ChangeColumnTypeInfo -//===--------------------------------------------------------------------===// -struct ChangeColumnTypeInfo : public AlterTableInfo { - ChangeColumnTypeInfo(string schema, string table, string column_name, LogicalType target_type, - unique_ptr expression) - : AlterTableInfo(AlterTableType::ALTER_COLUMN_TYPE, schema, table), column_name(move(column_name)), - target_type(move(target_type)), expression(move(expression)) { - } - ~ChangeColumnTypeInfo() override { - } - - //! The column name to alter - string column_name; - //! The target type of the column - LogicalType target_type; - //! The expression used for data conversion - unique_ptr expression; - -public: - unique_ptr Copy() const override; - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(Deserializer &source, string schema, string table); -}; - -//===--------------------------------------------------------------------===// -// SetDefaultInfo -//===--------------------------------------------------------------------===// -struct SetDefaultInfo : public AlterTableInfo { - SetDefaultInfo(string schema, string table, string column_name, unique_ptr new_default) - : AlterTableInfo(AlterTableType::SET_DEFAULT, schema, table), column_name(move(column_name)), - expression(move(new_default)) { - } - ~SetDefaultInfo() override { - } - - //! The column name to alter - string column_name; - //! The expression used for data conversion - unique_ptr expression; - -public: - unique_ptr Copy() const override; - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(Deserializer &source, string schema, string table); -}; - -//===--------------------------------------------------------------------===// -// Alter View -//===--------------------------------------------------------------------===// -enum class AlterViewType : uint8_t { INVALID = 0, RENAME_VIEW = 1 }; - -struct AlterViewInfo : public AlterInfo { - AlterViewInfo(AlterViewType type, string schema, string view) - : AlterInfo(AlterType::ALTER_VIEW, schema, view), alter_view_type(type) { - } - ~AlterViewInfo() override { - } - - AlterViewType alter_view_type; - -public: - CatalogType GetCatalogType() override { - return CatalogType::VIEW_ENTRY; - } - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(Deserializer &source); -}; - -//===--------------------------------------------------------------------===// -// RenameViewInfo -//===--------------------------------------------------------------------===// -struct RenameViewInfo : public AlterViewInfo { - RenameViewInfo(string schema, string view, string new_name) - : AlterViewInfo(AlterViewType::RENAME_VIEW, schema, view), new_view_name(new_name) { - } - ~RenameViewInfo() override { - } - - //! Relation new name - string new_view_name; - -public: - unique_ptr Copy() const override; - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(Deserializer &source, string schema, string table); -}; - -} // namespace duckdb @@ -2666,15 +1024,15 @@ struct CreateTypeInfo : public CreateInfo { //! Name of the Type string name; - //! Shared Pointer of Logical Type - unique_ptr type; + //! Logical Type + LogicalType type; public: unique_ptr Copy() const override { auto result = make_unique(); CopyProperties(*result); result->name = name; - result->type = make_unique(*type); + result->type = type; return move(result); } }; @@ -2858,58 +1216,6 @@ struct CreateTableInfo : public CreateInfo { -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/storage/storage_lock.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - - -namespace duckdb { -class StorageLock; - -enum class StorageLockType { SHARED = 0, EXCLUSIVE = 1 }; - -class StorageLockKey { -public: - StorageLockKey(StorageLock &lock, StorageLockType type); - ~StorageLockKey(); - -private: - StorageLock &lock; - StorageLockType type; -}; - -class StorageLock { - friend class StorageLockKey; - -public: - StorageLock(); - - //! Get an exclusive lock - unique_ptr GetExclusiveLock(); - //! Get a shared lock - unique_ptr GetSharedLock(); - -private: - mutex exclusive_lock; - atomic read_count; - -private: - //! Release an exclusive lock - void ReleaseExclusiveLock(); - //! Release a shared lock - void ReleaseSharedLock(); -}; - -} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB @@ -2999,73 +1305,6 @@ class SegmentTree { -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/storage/storage_info.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -namespace duckdb { -class Serializer; -class Deserializer; -struct FileHandle; - -//! The version number of the database storage format -extern const uint64_t VERSION_NUMBER; - -using block_id_t = int64_t; - -#define INVALID_BLOCK (-1) - -// maximum block id, 2^62 -#define MAXIMUM_BLOCK 4611686018427388000LL - -//! The MainHeader is the first header in the storage file. The MainHeader is typically written only once for a database -//! file. -struct MainHeader { - static constexpr idx_t MAGIC_BYTE_SIZE = 4; - static constexpr idx_t MAGIC_BYTE_OFFSET = sizeof(uint64_t); - static constexpr idx_t FLAG_COUNT = 4; - // the magic bytes in front of the file - // should be "DUCK" - static const char MAGIC_BYTES[]; - //! The version of the database - uint64_t version_number; - //! The set of flags used by the database - uint64_t flags[FLAG_COUNT]; - - static void CheckMagicBytes(FileHandle &handle); - - void Serialize(Serializer &ser); - static MainHeader Deserialize(Deserializer &source); -}; - -//! The DatabaseHeader contains information about the current state of the database. Every storage file has two -//! DatabaseHeaders. On startup, the DatabaseHeader with the highest iteration count is used as the active header. When -//! a checkpoint is performed, the active DatabaseHeader is switched by increasing the iteration count of the -//! DatabaseHeader. -struct DatabaseHeader { - //! The iteration count, increases by 1 every time the storage is checkpointed. - uint64_t iteration; - //! A pointer to the initial meta block - block_id_t meta_block; - //! A pointer to the block containing the free list - block_id_t free_list; - //! The number of blocks that is in the file as of this database header. If the file is larger than BLOCK_SIZE * - //! block_count any blocks appearing AFTER block_count are implicitly part of the free_list. - uint64_t block_count; - - void Serialize(Serializer &ser); - static DatabaseHeader Deserialize(Deserializer &source); -}; - -} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB @@ -3229,35 +1468,6 @@ class ChunkVectorInfo : public ChunkInfo { -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/storage/buffer/buffer_handle.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -namespace duckdb { -class BlockHandle; -class FileBuffer; - -class BufferHandle { -public: - BufferHandle(shared_ptr handle, FileBuffer *node); - ~BufferHandle(); - - //! The block handle - shared_ptr handle; - //! The managed buffer node - FileBuffer *node; - data_ptr_t Ptr(); -}; - -} // namespace duckdb @@ -3310,82 +1520,43 @@ struct TableAppendState { } // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/storage/table/scan_state.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/execution/adaptive_filter.hpp +// duckdb/storage/statistics/segment_statistics.hpp // // //===----------------------------------------------------------------------===// -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/expression/bound_aggregate_expression.hpp -// -// -//===----------------------------------------------------------------------===// - - -#include namespace duckdb { -class BoundAggregateExpression : public Expression { + +class SegmentStatistics { public: - BoundAggregateExpression(AggregateFunction function, vector> children, - unique_ptr filter, unique_ptr bind_info, bool distinct); + SegmentStatistics(LogicalType type); + SegmentStatistics(LogicalType type, unique_ptr statistics); - //! The bound function expression - AggregateFunction function; - //! List of arguments to the function - vector> children; - //! The bound function data (if any) - unique_ptr bind_info; - //! True to aggregate on distinct values - bool distinct; + LogicalType type; - //! Filter for this aggregate - unique_ptr filter; + //! Type-specific statistics of the segment + unique_ptr statistics; public: - bool IsAggregate() const override { - return true; - } - bool IsFoldable() const override { - return false; - } - - string ToString() const override; - - hash_t Hash() const override; - bool Equals(const BaseExpression *other) const override; - unique_ptr Copy() override; + void Reset(); }; + } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/planner/expression/bound_between_expression.hpp +// duckdb/common/enums/scan_options.hpp // // //===----------------------------------------------------------------------===// @@ -3396,938 +1567,60 @@ class BoundAggregateExpression : public Expression { namespace duckdb { -class BoundBetweenExpression : public Expression { -public: - BoundBetweenExpression(unique_ptr input, unique_ptr lower, unique_ptr upper, - bool lower_inclusive, bool upper_inclusive); - - unique_ptr input; - unique_ptr lower; - unique_ptr upper; - bool lower_inclusive; - bool upper_inclusive; - -public: - string ToString() const override; - - bool Equals(const BaseExpression *other) const override; - - unique_ptr Copy() override; - -public: - ExpressionType LowerComparisonType() { - return lower_inclusive ? ExpressionType::COMPARE_GREATERTHANOREQUALTO : ExpressionType::COMPARE_GREATERTHAN; - } - ExpressionType UpperComparisonType() { - return upper_inclusive ? ExpressionType::COMPARE_LESSTHANOREQUALTO : ExpressionType::COMPARE_LESSTHAN; - } +enum class TableScanType : uint8_t { + //! Regular table scan: scan all tuples that are relevant for the current transaction + TABLE_SCAN_REGULAR = 0, + //! Scan all rows, including any deleted rows. Committed updates are merged in. + TABLE_SCAN_COMMITTED_ROWS = 1, + //! Scan all rows, including any deleted rows. Throws an exception if there are any uncommitted updates. + TABLE_SCAN_COMMITTED_ROWS_DISALLOW_UPDATES = 2, + //! Scan all rows, excluding any permanently deleted rows. + //! Permanently deleted rows are rows which no transaction will ever need again. + TABLE_SCAN_COMMITTED_ROWS_OMIT_PERMANENTLY_DELETED = 3 }; -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/expression/bound_case_expression.hpp -// -// -//===----------------------------------------------------------------------===// - +} // namespace duckdb namespace duckdb { +class ColumnData; +class DatabaseInstance; +class DataTable; +struct DataTableInfo; +class ExpressionExecutor; +class TableDataWriter; +class UpdateSegment; +class Vector; +struct RowGroupPointer; +struct VersionNode; -struct BoundCaseCheck { - unique_ptr when_expr; - unique_ptr then_expr; -}; - -class BoundCaseExpression : public Expression { +class RowGroup : public SegmentBase { public: - BoundCaseExpression(LogicalType type); - BoundCaseExpression(unique_ptr when_expr, unique_ptr then_expr, - unique_ptr else_expr); + friend class ColumnData; + friend class VersionDeleteState; - vector case_checks; - unique_ptr else_expr; +public: + static constexpr const idx_t ROW_GROUP_VECTOR_COUNT = 120; + static constexpr const idx_t ROW_GROUP_SIZE = STANDARD_VECTOR_SIZE * ROW_GROUP_VECTOR_COUNT; public: - string ToString() const override; + RowGroup(DatabaseInstance &db, DataTableInfo &table_info, idx_t start, idx_t count); + RowGroup(DatabaseInstance &db, DataTableInfo &table_info, const vector &types, + RowGroupPointer &pointer); + ~RowGroup(); - bool Equals(const BaseExpression *other) const override; - - unique_ptr Copy() override; -}; -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/expression/bound_cast_expression.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -namespace duckdb { - -class BoundCastExpression : public Expression { -public: - BoundCastExpression(unique_ptr child, LogicalType target_type, bool try_cast = false); - - //! The child type - unique_ptr child; - //! Whether to use try_cast or not. try_cast converts cast failures into NULLs instead of throwing an error. - bool try_cast; - -public: - LogicalType source_type() { - return child->return_type; - } - - //! Cast an expression to the specified SQL type if required - static unique_ptr AddCastToType(unique_ptr expr, const LogicalType &target_type); - //! 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); - - string ToString() const override; - - bool Equals(const BaseExpression *other) const override; - - unique_ptr Copy() override; -}; -} // namespace duckdb - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/expression/bound_comparison_expression.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -namespace duckdb { - -class BoundComparisonExpression : public Expression { -public: - BoundComparisonExpression(ExpressionType type, unique_ptr left, unique_ptr right); - - unique_ptr left; - unique_ptr right; - -public: - string ToString() const override; - - bool Equals(const BaseExpression *other) const override; - - unique_ptr Copy() override; - -public: - static LogicalType BindComparison(LogicalType left_type, LogicalType right_type); -}; -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/expression/bound_conjunction_expression.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -namespace duckdb { - -class BoundConjunctionExpression : public Expression { -public: - explicit BoundConjunctionExpression(ExpressionType type); - BoundConjunctionExpression(ExpressionType type, unique_ptr left, unique_ptr right); - - vector> children; - -public: - string ToString() const override; - - bool Equals(const BaseExpression *other) const override; - - unique_ptr Copy() override; -}; -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/expression/bound_constant_expression.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - -namespace duckdb { - -class BoundConstantExpression : public Expression { -public: - explicit BoundConstantExpression(Value value); - - Value value; - -public: - string ToString() const override; - - bool Equals(const BaseExpression *other) const override; - hash_t Hash() const override; - - unique_ptr Copy() override; -}; -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/expression/bound_default_expression.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -namespace duckdb { - -class BoundDefaultExpression : public Expression { -public: - explicit BoundDefaultExpression(LogicalType type = LogicalType()) - : Expression(ExpressionType::VALUE_DEFAULT, ExpressionClass::BOUND_DEFAULT, type) { - } - -public: - bool IsScalar() const override { - return false; - } - bool IsFoldable() const override { - return false; - } - - string ToString() const override { - return "DEFAULT"; - } - - unique_ptr Copy() override { - return make_unique(return_type); - } -}; -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/expression/bound_function_expression.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - -namespace duckdb { -class ScalarFunctionCatalogEntry; - -//! Represents a function call that has been bound to a base function -class BoundFunctionExpression : public Expression { -public: - BoundFunctionExpression(LogicalType return_type, ScalarFunction bound_function, - vector> arguments, unique_ptr bind_info, - bool is_operator = false); - - // The bound function expression - ScalarFunction function; - //! List of child-expressions of the function - vector> children; - //! The bound function data (if any) - unique_ptr bind_info; - //! Whether or not the function is an operator, only used for rendering - bool is_operator; - -public: - bool HasSideEffects() const override; - bool IsFoldable() const override; - string ToString() const override; - - hash_t Hash() const override; - bool Equals(const BaseExpression *other) const override; - - unique_ptr Copy() override; -}; -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/expression/bound_operator_expression.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -namespace duckdb { - -class BoundOperatorExpression : public Expression { -public: - BoundOperatorExpression(ExpressionType type, LogicalType return_type); - - vector> children; - -public: - string ToString() const override; - - bool Equals(const BaseExpression *other) const override; - - unique_ptr Copy() override; -}; -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/expression/bound_parameter_expression.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - -namespace duckdb { - -class BoundParameterExpression : public Expression { -public: - explicit BoundParameterExpression(idx_t parameter_nr); - - idx_t parameter_nr; - Value *value; - -public: - bool IsScalar() const override; - bool HasParameter() const override; - bool IsFoldable() const override; - - string ToString() const override; - - bool Equals(const BaseExpression *other) const override; - hash_t Hash() const override; - - unique_ptr Copy() override; -}; -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/expression/bound_reference_expression.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -namespace duckdb { - -//! A BoundReferenceExpression represents a physical index into a DataChunk -class BoundReferenceExpression : public Expression { -public: - BoundReferenceExpression(string alias, LogicalType type, idx_t index); - BoundReferenceExpression(LogicalType type, idx_t index); - - //! Index used to access data in the chunks - idx_t index; - -public: - bool IsScalar() const override { - return false; - } - bool IsFoldable() const override { - return false; - } - - string ToString() const override; - - hash_t Hash() const override; - bool Equals(const BaseExpression *other) const override; - - unique_ptr Copy() override; -}; -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/expression/bound_subquery_expression.hpp -// -// -//===----------------------------------------------------------------------===// - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/enums/subquery_type.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -namespace duckdb { - -//===--------------------------------------------------------------------===// -// Subquery Types -//===--------------------------------------------------------------------===// -enum class SubqueryType : uint8_t { - INVALID = 0, - SCALAR = 1, // Regular scalar subquery - EXISTS = 2, // EXISTS (SELECT...) - NOT_EXISTS = 3, // NOT EXISTS(SELECT...) - ANY = 4, // x = ANY(SELECT...) OR x IN (SELECT...) -}; - -} // namespace duckdb - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/bound_query_node.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - - -namespace duckdb { - -//! Bound equivalent of QueryNode -class BoundQueryNode { -public: - explicit BoundQueryNode(QueryNodeType type) : type(type) { - } - virtual ~BoundQueryNode() { - } - - //! The type of the query node, either SetOperation or Select - QueryNodeType type; - //! The result modifiers that should be applied to this query node - vector> modifiers; - - //! The names returned by this QueryNode. - vector names; - //! The types returned by this QueryNode. - vector types; - -public: - virtual idx_t GetRootIndex() = 0; -}; - -} // namespace duckdb - - - -namespace duckdb { - -class BoundSubqueryExpression : public Expression { -public: - explicit BoundSubqueryExpression(LogicalType return_type); - - bool IsCorrelated() { - return binder->correlated_columns.size() > 0; - } - - //! The binder used to bind the subquery node - shared_ptr binder; - //! The bound subquery node - unique_ptr subquery; - //! The subquery type - SubqueryType subquery_type; - //! the child expression to compare with (in case of IN, ANY, ALL operators) - unique_ptr child; - //! The comparison type of the child expression with the subquery (in case of ANY, ALL operators) - ExpressionType comparison_type; - //! The LogicalType of the subquery result. Only used for ANY expressions. - LogicalType child_type; - //! The target LogicalType of the subquery result (i.e. to which type it should be casted, if child_type <> - //! child_target). Only used for ANY expressions. - LogicalType child_target; - -public: - bool HasSubquery() const override { - return true; - } - bool IsScalar() const override { - return false; - } - bool IsFoldable() const override { - return false; - } - - string ToString() const override; - - bool Equals(const BaseExpression *other) const override; - - unique_ptr Copy() override; -}; -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/expression/bound_unnest_expression.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -namespace duckdb { - -//! Represents a function call that has been bound to a base function -class BoundUnnestExpression : public Expression { -public: - explicit BoundUnnestExpression(LogicalType return_type); - - unique_ptr child; - -public: - bool IsFoldable() const override; - string ToString() const override; - - hash_t Hash() const override; - bool Equals(const BaseExpression *other) const override; - - unique_ptr Copy() override; -}; -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/expression/bound_window_expression.hpp -// -// -//===----------------------------------------------------------------------===// - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/expression/window_expression.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - -namespace duckdb { - -enum class WindowBoundary : uint8_t { - INVALID = 0, - UNBOUNDED_PRECEDING = 1, - UNBOUNDED_FOLLOWING = 2, - CURRENT_ROW_RANGE = 3, - CURRENT_ROW_ROWS = 4, - EXPR_PRECEDING_ROWS = 5, - EXPR_FOLLOWING_ROWS = 6, - EXPR_PRECEDING_RANGE = 7, - EXPR_FOLLOWING_RANGE = 8 -}; - -//! The WindowExpression represents a window function in the query. They are a special case of aggregates which is why -//! they inherit from them. -class WindowExpression : public ParsedExpression { -public: - WindowExpression(ExpressionType type, string schema_name, const string &function_name); - - //! Schema of the aggregate function - string schema; - //! Name of the aggregate function - string function_name; - //! The child expression of the main window aggregate - vector> children; - //! The set of expressions to partition by - vector> partitions; - //! The set of ordering clauses - vector orders; - //! The window boundaries - WindowBoundary start = WindowBoundary::INVALID; - WindowBoundary end = WindowBoundary::INVALID; - - unique_ptr start_expr; - unique_ptr end_expr; - //! Offset and default expressions for WINDOW_LEAD and WINDOW_LAG functions - unique_ptr offset_expr; - unique_ptr default_expr; - -public: - bool IsWindow() const override { - return true; - } - - //! Get the name of the expression - string GetName() const override; - //! Convert the Expression to a String - string ToString() const override; - - static bool Equals(const WindowExpression *a, const WindowExpression *b); - - unique_ptr Copy() const override; - - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(ExpressionType type, Deserializer &source); -}; -} // namespace duckdb - - - - - -namespace duckdb { -class AggregateFunction; - -class BoundWindowExpression : public Expression { -public: - BoundWindowExpression(ExpressionType type, LogicalType return_type, unique_ptr aggregate, - unique_ptr bind_info); - - //! The bound aggregate function - unique_ptr aggregate; - //! The bound function info - unique_ptr bind_info; - //! The child expressions of the main window aggregate - vector> children; - //! The set of expressions to partition by - vector> partitions; - //! Statistics belonging to the partitions expressions - vector> partitions_stats; - //! The set of ordering clauses - vector orders; - //! The window boundaries - WindowBoundary start = WindowBoundary::INVALID; - WindowBoundary end = WindowBoundary::INVALID; - - unique_ptr start_expr; - unique_ptr end_expr; - //! Offset and default expressions for WINDOW_LEAD and WINDOW_LAG functions - unique_ptr offset_expr; - unique_ptr default_expr; - -public: - bool IsWindow() const override { - return true; - } - bool IsFoldable() const override { - return false; - } - - string ToString() const override; - - bool KeysAreCompatible(const BoundWindowExpression *other) const; - bool Equals(const BaseExpression *other) const override; - - unique_ptr Copy() override; -}; -} // namespace duckdb - - - -#include -namespace duckdb { - -class AdaptiveFilter { -public: - explicit AdaptiveFilter(const Expression &expr); - explicit AdaptiveFilter(TableFilterSet *table_filters); - void AdaptRuntimeStatistics(double duration); - vector permutation; - -private: - //! used for adaptive expression reordering - idx_t iteration_count; - idx_t swap_idx; - idx_t right_random_border; - idx_t observe_interval; - idx_t execute_interval; - double runtime_sum; - double prev_mean; - bool observe; - bool warmup; - vector swap_likeliness; - std::default_random_engine generator; -}; -} // namespace duckdb - - -namespace duckdb { -class ColumnSegment; -class LocalTableStorage; -class Index; -class RowGroup; -class UpdateSegment; -class TableScanState; -class ColumnSegment; -class ValiditySegment; -class TableFilterSet; - -struct SegmentScanState { - virtual ~SegmentScanState() { - } -}; - -struct IndexScanState { - virtual ~IndexScanState() { - } -}; - -typedef unordered_map> buffer_handle_set_t; - -struct ColumnScanState { - //! The column segment that is currently being scanned - ColumnSegment *current; - //! The current row index of the scan - idx_t row_index; - //! The internal row index (i.e. the position of the SegmentScanState) - idx_t internal_index; - //! Segment scan state - unique_ptr scan_state; - //! Child states of the vector - vector child_states; - //! Whether or not InitializeState has been called for this segment - bool initialized = false; - //! If this segment has already been checked for skipping purposes - bool segment_checked = false; - -public: - //! Move the scan state forward by "count" rows (including all child states) - void Next(idx_t count); - //! Move ONLY this state forward by "count" rows (i.e. not the child states) - void NextInternal(idx_t count); - //! Move the scan state forward by STANDARD_VECTOR_SIZE rows - void NextVector(); -}; - -struct ColumnFetchState { - //! The set of pinned block handles for this set of fetches - buffer_handle_set_t handles; - //! Any child states of the fetch - vector> child_states; -}; - -struct LocalScanState { - ~LocalScanState(); - - void SetStorage(LocalTableStorage *storage); - LocalTableStorage *GetStorage() { - return storage; - } - - idx_t chunk_index; - idx_t max_index; - idx_t last_chunk_count; - TableFilterSet *table_filters; - -private: - LocalTableStorage *storage = nullptr; -}; - -class RowGroupScanState { -public: - RowGroupScanState(TableScanState &parent_p) : parent(parent_p), vector_index(0), max_row(0) { - } - - //! The parent scan state - TableScanState &parent; - //! The current row_group we are scanning - RowGroup *row_group; - //! The vector index within the row_group - idx_t vector_index; - //! The maximum row index of this row_group scan - idx_t max_row; - //! Child column scans - unique_ptr column_scans; - -public: - //! Move to the next vector, skipping past the current one - void NextVector(); -}; - -class TableScanState { -public: - TableScanState() : row_group_scan_state(*this), max_row(0) {}; - - //! The row_group scan state - RowGroupScanState row_group_scan_state; - //! The total maximum row index - idx_t max_row; - //! The column identifiers of the scan - vector column_ids; - //! The table filters (if any) - TableFilterSet *table_filters = nullptr; - //! Adaptive filter info (if any) - unique_ptr adaptive_filter; - //! Transaction-local scan state - LocalScanState local_state; - -public: - //! Move to the next vector - void NextVector(); -}; - -class CreateIndexScanState : public TableScanState { -public: - vector> locks; - unique_lock append_lock; - unique_lock delete_lock; -}; - -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/storage/statistics/segment_statistics.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - - -namespace duckdb { - -class SegmentStatistics { -public: - SegmentStatistics(LogicalType type); - SegmentStatistics(LogicalType type, unique_ptr statistics); - - LogicalType type; - - //! Type-specific statistics of the segment - unique_ptr statistics; - -public: - void Reset(); -}; - -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/enums/scan_options.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -namespace duckdb { - -enum class TableScanType : uint8_t { - //! Regular table scan: scan all tuples that are relevant for the current transaction - TABLE_SCAN_REGULAR = 0, - //! Scan all rows, including any deleted rows. Committed updates are merged in. - TABLE_SCAN_COMMITTED_ROWS = 1, - //! Scan all rows, including any deleted rows. Throws an exception if there are any uncommitted updates. - TABLE_SCAN_COMMITTED_ROWS_DISALLOW_UPDATES = 2, - //! Scan all rows, excluding any permanently deleted rows. - //! Permanently deleted rows are rows which no transaction will ever need again. - TABLE_SCAN_COMMITTED_ROWS_OMIT_PERMANENTLY_DELETED = 3 -}; - -} // namespace duckdb - - - -namespace duckdb { -class ColumnData; -class DatabaseInstance; -class DataTable; -struct DataTableInfo; -class ExpressionExecutor; -class TableDataWriter; -class UpdateSegment; -class Vector; -struct RowGroupPointer; -struct VersionNode; - -class RowGroup : public SegmentBase { -public: - friend class ColumnData; - friend class VersionDeleteState; - -public: - static constexpr const idx_t ROW_GROUP_VECTOR_COUNT = 120; - static constexpr const idx_t ROW_GROUP_SIZE = STANDARD_VECTOR_SIZE * ROW_GROUP_VECTOR_COUNT; - -public: - RowGroup(DatabaseInstance &db, DataTableInfo &table_info, idx_t start, idx_t count); - RowGroup(DatabaseInstance &db, DataTableInfo &table_info, const vector &types, - RowGroupPointer &pointer); - ~RowGroup(); - -private: - //! The database instance - DatabaseInstance &db; - //! The table info of this row_group - DataTableInfo &table_info; - //! The version info of the row_group (inserted and deleted tuple info) - shared_ptr version_info; - //! The column data of the row_group - vector> columns; - //! The segment statistics for each of the columns - vector> stats; +private: + //! The database instance + DatabaseInstance &db; + //! The table info of this row_group + DataTableInfo &table_info; + //! The version info of the row_group (inserted and deleted tuple info) + shared_ptr version_info; + //! The column data of the row_group + vector> columns; + //! The segment statistics for each of the columns + vector> stats; public: DatabaseInstance &GetDatabase() { @@ -4508,6 +1801,7 @@ struct BoundCreateTableInfo { } // namespace duckdb + namespace duckdb { string SimilarCatalogEntry::GetQualifiedName() const { @@ -4533,6 +1827,12 @@ CatalogEntry *Catalog::CreateTable(ClientContext &context, BoundCreateTableInfo return CreateTable(context, schema, info); } +CatalogEntry *Catalog::CreateTable(ClientContext &context, unique_ptr info) { + auto binder = Binder::CreateBinder(context); + auto bound_info = binder->BindCreateTableInfo(move(info)); + return CreateTable(context, bound_info.get()); +} + CatalogEntry *Catalog::CreateTable(ClientContext &context, SchemaCatalogEntry *schema, BoundCreateTableInfo *info) { return schema->CreateTable(context, info); } @@ -4658,6 +1958,15 @@ 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()); @@ -4760,6 +2069,19 @@ CatalogEntryLookup Catalog::LookupEntry(ClientContext &context, CatalogType type return {nullptr, nullptr}; } +CatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema, const string &name) { + vector entry_types {CatalogType::TABLE_ENTRY, CatalogType::SEQUENCE_ENTRY}; + + for (auto entry_type : entry_types) { + CatalogEntry *result = GetEntry(context, entry_type, schema, name, true); + if (result != nullptr) { + return result; + } + } + + throw CatalogException("CatalogElement \"%s.%s\" does not exist!", schema, name); +} + CatalogEntry *Catalog::GetEntry(ClientContext &context, CatalogType type, const string &schema_name, const string &name, bool if_exists, QueryErrorContext error_context) { return LookupEntry(context, type, schema_name, name, if_exists, error_context).entry; @@ -4899,51 +2221,51 @@ class ExecutionContext; //! ExpressionExecutor is responsible for executing a set of expressions and storing the result in a data chunk class ExpressionExecutor { public: - ExpressionExecutor(); - explicit ExpressionExecutor(const Expression *expression); - explicit ExpressionExecutor(const Expression &expression); - explicit ExpressionExecutor(const vector> &expressions); + DUCKDB_API ExpressionExecutor(); + DUCKDB_API explicit ExpressionExecutor(const Expression *expression); + DUCKDB_API explicit ExpressionExecutor(const Expression &expression); + DUCKDB_API explicit ExpressionExecutor(const vector> &expressions); //! Add an expression to the set of to-be-executed expressions of the executor - void AddExpression(const Expression &expr); + DUCKDB_API void AddExpression(const Expression &expr); //! Execute the set of expressions with the given input chunk and store the result in the output chunk - void Execute(DataChunk *input, DataChunk &result); - void Execute(DataChunk &input, DataChunk &result) { + DUCKDB_API void Execute(DataChunk *input, DataChunk &result); + inline void Execute(DataChunk &input, DataChunk &result) { Execute(&input, result); } - void Execute(DataChunk &result) { + inline void Execute(DataChunk &result) { Execute(nullptr, result); } //! Execute the ExpressionExecutor and put the result in the result vector; this should only be used for expression //! executors with a single expression - void ExecuteExpression(DataChunk &input, Vector &result); + DUCKDB_API void ExecuteExpression(DataChunk &input, Vector &result); //! Execute the ExpressionExecutor and put the result in the result vector; this should only be used for expression //! executors with a single expression - void ExecuteExpression(Vector &result); + DUCKDB_API void ExecuteExpression(Vector &result); //! Execute the ExpressionExecutor and generate a selection vector from all true values in the result; this should //! only be used with a single boolean expression - idx_t SelectExpression(DataChunk &input, SelectionVector &sel); + DUCKDB_API idx_t SelectExpression(DataChunk &input, SelectionVector &sel); //! Execute the expression with index `expr_idx` and store the result in the result vector - void ExecuteExpression(idx_t expr_idx, Vector &result); + DUCKDB_API void ExecuteExpression(idx_t expr_idx, Vector &result); //! Evaluate a scalar expression and fold it into a single value - static Value EvaluateScalar(const Expression &expr); + DUCKDB_API static Value EvaluateScalar(const Expression &expr); //! Try to evaluate a scalar expression and fold it into a single value, returns false if an exception is thrown - static bool TryEvaluateScalar(const Expression &expr, Value &result); + DUCKDB_API static bool TryEvaluateScalar(const Expression &expr, Value &result); //! Initialize the state of a given expression static unique_ptr InitializeState(const Expression &expr, ExpressionExecutorState &state); - void SetChunk(DataChunk *chunk) { + inline void SetChunk(DataChunk *chunk) { this->chunk = chunk; } - void SetChunk(DataChunk &chunk) { + inline void SetChunk(DataChunk &chunk) { SetChunk(&chunk); } - vector> &GetStates(); + DUCKDB_API vector> &GetStates(); //! The expressions of the executor vector expressions; @@ -5662,8 +2984,8 @@ class ColumnSegment : public SegmentBase { //! Fetch a value of the specific row id and append it to the result void FetchRow(ColumnFetchState &state, row_t row_id, Vector &result, idx_t result_idx); - static void FilterSelection(SelectionVector &sel, Vector &result, const TableFilter &filter, - idx_t &approved_tuple_count, ValidityMask &mask); + static idx_t FilterSelection(SelectionVector &sel, Vector &result, const TableFilter &filter, + idx_t &approved_tuple_count, ValidityMask &mask); //! Skip a scan forward to the row_index specified in the scan state void Skip(ColumnScanState &state); @@ -5725,110 +3047,6 @@ class ColumnSegment : public SegmentBase { } // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/transaction/local_storage.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - -namespace duckdb { -class DataTable; -class WriteAheadLog; -struct TableAppendState; - -class LocalTableStorage { -public: - explicit LocalTableStorage(DataTable &table); - ~LocalTableStorage(); - - DataTable &table; - //! The main chunk collection holding the data - ChunkCollection collection; - //! The set of unique indexes - vector> indexes; - //! The set of deleted entries - unordered_map> deleted_entries; - //! The number of deleted rows - idx_t deleted_rows; - //! The number of active scans - atomic active_scans; - -public: - void InitializeScan(LocalScanState &state, TableFilterSet *table_filters = nullptr); - idx_t EstimatedSize(); - - void Clear(); -}; - -//! The LocalStorage class holds appends that have not been committed yet -class LocalStorage { -public: - struct CommitState { - unordered_map> append_states; - }; - -public: - explicit LocalStorage(Transaction &transaction) : transaction(transaction) { - } - - //! Initialize a scan of the local storage - void InitializeScan(DataTable *table, LocalScanState &state, TableFilterSet *table_filters); - //! Scan - void Scan(LocalScanState &state, const vector &column_ids, DataChunk &result); - - //! Append a chunk to the local storage - void Append(DataTable *table, DataChunk &chunk); - //! Delete a set of rows from the local storage - idx_t Delete(DataTable *table, Vector &row_ids, idx_t count); - //! Update a set of rows in the local storage - 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, WriteAheadLog *log, - transaction_t commit_id); - - bool ChangesMade() noexcept { - return table_storage.size() > 0; - } - idx_t EstimatedSize(); - - bool Find(DataTable *table) { - return table_storage.find(table) != table_storage.end(); - } - - idx_t AddedRows(DataTable *table) { - auto entry = table_storage.find(table); - if (entry == table_storage.end()) { - return 0; - } - return entry->second->collection.Count() - entry->second->deleted_rows; - } - - void AddColumn(DataTable *old_dt, DataTable *new_dt, ColumnDefinition &new_column, Expression *default_value); - void ChangeType(DataTable *old_dt, DataTable *new_dt, idx_t changed_idx, const LogicalType &target_type, - const vector &bound_columns, Expression &cast_expr); - -private: - LocalTableStorage *GetStorage(DataTable *table); - - template - bool ScanTableStorage(DataTable &table, LocalTableStorage &storage, T &&fun); - -private: - Transaction &transaction; - unordered_map> table_storage; - - void Flush(DataTable &table, LocalTableStorage &storage); -}; - -} // namespace duckdb @@ -6097,6 +3315,262 @@ string IndexCatalogEntry::ToSQL() { } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/field_writer.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +#include + +namespace duckdb { +class BufferedSerializer; + +class FieldWriter { +public: + FieldWriter(Serializer &serializer); + ~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 WriteSerializable(const T &element) { + AddField(); + element.Serialize(*buffer); + } + + 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. + void Finalize(); + + Serializer &GetSerializer() { + return *buffer; + } + +private: + void AddField() { + field_count++; + } + + template + void Write(const T &element) { + WriteData((const_data_ptr_t)&element, sizeof(T)); + } + + void WriteData(const_data_ptr_t buffer, idx_t write_size); + +private: + Serializer &serializer; + unique_ptr buffer; + idx_t field_count; +}; + +template <> +void FieldWriter::Write(const string &val); + +class FieldDeserializer : public Deserializer { +public: + FieldDeserializer(Deserializer &root); + +public: + void ReadData(data_ptr_t buffer, idx_t read_size) override; + + void SetRemainingData(idx_t remaining_data); + idx_t RemainingData(); + +private: + Deserializer &root; + idx_t remaining_data; +}; + +class FieldReader { +public: + FieldReader(Deserializer &source); + ~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 + vector 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(); + vector result; + for (idx_t i = 0; i < result_count; i++) { + result.push_back(source.Read()); + } + return result; + } + + template + unique_ptr ReadOptional(unique_ptr 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.template ReadOptional(); + } + + 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 > + RETURN_TYPE ReadRequiredSerializable() { + if (field_count >= max_field_count) { + // field is not there, read the default value + throw SerializationException("Attempting to read mandatory field, but field is missing"); + } + // field is there, read the actual value + AddField(); + return T::Deserialize(source); + } + + template > + vector ReadRequiredSerializableList() { + if (field_count >= max_field_count) { + // field is not there, read the default value + 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)); + } + 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); + } + + //! Called after all fields have been read. Should always be called. + 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; +}; + +} // namespace duckdb namespace duckdb { @@ -6107,36 +3581,39 @@ MacroCatalogEntry::MacroCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schem this->internal = info->internal; } -void MacroCatalogEntry::Serialize(Serializer &serializer) { +void MacroCatalogEntry::Serialize(Serializer &main_serializer) { D_ASSERT(!internal); - serializer.WriteString(schema->name); - serializer.WriteString(name); - function->expression->Serialize(serializer); - serializer.Write((uint32_t)function->parameters.size()); - for (auto ¶m : function->parameters) { - param->Serialize(serializer); - } - serializer.Write((uint32_t)function->default_parameters.size()); + FieldWriter writer(main_serializer); + writer.WriteString(schema->name); + writer.WriteString(name); + writer.WriteSerializable(*function->expression); + 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 MacroCatalogEntry::Deserialize(Deserializer &source) { +unique_ptr MacroCatalogEntry::Deserialize(Deserializer &main_source) { auto info = make_unique(); - info->schema = source.Read(); - info->name = source.Read(); - info->function = make_unique(ParsedExpression::Deserialize(source)); - auto param_count = source.Read(); - for (idx_t i = 0; i < param_count; i++) { - info->function->parameters.push_back(ParsedExpression::Deserialize(source)); - } - auto default_param_count = source.Read(); + + FieldReader reader(main_source); + info->schema = reader.ReadRequired(); + info->name = reader.ReadRequired(); + auto expression = reader.ReadRequiredSerializable(); + info->function = make_unique(move(expression)); + 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; } @@ -6189,7 +3666,7 @@ class TypeCatalogEntry : public StandardEntry { //! Create a TypeCatalogEntry and initialize storage for it TypeCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateTypeInfo *info); - unique_ptr user_type; + LogicalType user_type; public: //! Serialize the meta information of the TypeCatalogEntry a serializer @@ -6274,216 +3751,6 @@ class DefaultViewGenerator : public DefaultGenerator { -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/transaction/transaction.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/transaction/undo_buffer.hpp -// -// -//===----------------------------------------------------------------------===// - - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/enums/undo_flags.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -namespace duckdb { - -enum class UndoFlags : uint32_t { // far to big but aligned (TM) - EMPTY_ENTRY = 0, - CATALOG_ENTRY = 1, - INSERT_TUPLE = 2, - DELETE_TUPLE = 3, - UPDATE_TUPLE = 4 -}; - -} // namespace duckdb - - -namespace duckdb { - -class WriteAheadLog; - -struct UndoChunk { - explicit UndoChunk(idx_t size); - ~UndoChunk(); - - data_ptr_t WriteEntry(UndoFlags type, uint32_t len); - - unique_ptr data; - idx_t current_position; - idx_t maximum_size; - unique_ptr next; - UndoChunk *prev; -}; - -//! The undo buffer of a transaction is used to hold previous versions of tuples -//! that might be required in the future (because of rollbacks or previous -//! transactions accessing them) -class UndoBuffer { -public: - struct IteratorState { - UndoChunk *current; - data_ptr_t start; - data_ptr_t end; - }; - -public: - UndoBuffer(); - - //! Reserve space for an entry of the specified type and length in the undo - //! buffer - data_ptr_t CreateEntry(UndoFlags type, idx_t len); - - bool ChangesMade(); - idx_t EstimatedSize(); - - //! Cleanup the undo buffer - void Cleanup(); - //! Commit the changes made in the UndoBuffer: should be called on commit - void Commit(UndoBuffer::IteratorState &iterator_state, WriteAheadLog *log, transaction_t commit_id); - //! Revert committed changes made in the UndoBuffer up until the currently committed state - void RevertCommit(UndoBuffer::IteratorState &iterator_state, transaction_t transaction_id); - //! Rollback the changes made in this UndoBuffer: should be called on - //! rollback - void Rollback() noexcept; - -private: - unique_ptr head; - UndoChunk *tail; - -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 - - - - -namespace duckdb { -class SequenceCatalogEntry; - -class ColumnData; -class ClientContext; -class CatalogEntry; -class DataTable; -class DatabaseInstance; -class WriteAheadLog; - -class ChunkVectorInfo; - -struct DeleteInfo; -struct UpdateInfo; - -//! The transaction object holds information about a currently running or past -//! transaction - -class Transaction { -public: - Transaction(weak_ptr context, transaction_t start_time, transaction_t transaction_id, - timestamp_t start_timestamp, idx_t catalog_version) - : context(move(context)), 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), storage(*this), is_invalidated(false) { - } - - 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; - //! The set of uncommitted appends for the transaction - LocalStorage storage; - //! Map of all sequences that were used during the transaction and the value they had in this transaction - unordered_map sequence_usage; - //! Whether or not the transaction has been invalidated - bool is_invalidated; - -public: - static Transaction &GetTransaction(ClientContext &context); - - 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 { - undo_buffer.Rollback(); - } - //! Cleanup the undo buffer - void Cleanup() { - undo_buffer.Cleanup(); - } - - void Invalidate() { - is_invalidated = true; - } - bool IsInvalidated() { - return is_invalidated; - } - bool ChangesMade(); - - timestamp_t GetCurrentTransactionStartTimestamp() { - return start_timestamp; - } - - 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); - -private: - //! The undo buffer is used to store old versions of rows that are updated - //! or deleted - UndoBuffer undo_buffer; - - Transaction(const Transaction &) = delete; -}; - -} // namespace duckdb #include @@ -6614,6 +3881,37 @@ CatalogEntry *SchemaCatalogEntry::CreateFunction(ClientContext &context, CreateF return AddEntry(context, 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); + } + + 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) { + scalar_info->functions.emplace_back(scalar); + } + break; + } + case CatalogType::AGGREGATE_FUNCTION_ENTRY: { + auto agg_info = (CreateAggregateFunctionInfo *)info; + auto &aggs = *(AggregateFunctionCatalogEntry *)entry; + for (const auto &agg : aggs.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); +} + void SchemaCatalogEntry::DropEntry(ClientContext &context, DropInfo *info) { auto &set = GetCatalogSet(info->type); @@ -6636,10 +3934,16 @@ void SchemaCatalogEntry::DropEntry(ClientContext &context, DropInfo *info) { void SchemaCatalogEntry::Alter(ClientContext &context, AlterInfo *info) { CatalogType type = info->GetCatalogType(); - string name = info->name; auto &set = GetCatalogSet(type); - if (!set.AlterEntry(context, name, info)) { - throw CatalogException("Entry with name \"%s\" does not exist!", name); + if (info->type == AlterType::CHANGE_OWNERSHIP) { + if (!set.AlterOwnership(context, (ChangeOwnershipInfo *)info)) { + throw CatalogException("Couldn't change ownership!"); + } + } else { + string name = info->name; + if (!set.AlterEntry(context, name, info)) { + throw CatalogException("Entry with name \"%s\" does not exist!", name); + } } } @@ -6655,12 +3959,18 @@ void SchemaCatalogEntry::Scan(CatalogType type, const std::function SchemaCatalogEntry::Deserialize(Deserializer &source) { auto info = make_unique(); - info->schema = source.Read(); + + FieldReader reader(source); + info->schema = reader.ReadRequired(); + reader.Finalize(); + return info; } @@ -6706,6 +4016,7 @@ CatalogSet &SchemaCatalogEntry::GetCatalogSet(CatalogType type) { + #include #include @@ -6719,28 +4030,32 @@ SequenceCatalogEntry::SequenceCatalogEntry(Catalog *catalog, SchemaCatalogEntry } void SequenceCatalogEntry::Serialize(Serializer &serializer) { - serializer.WriteString(schema->name); - serializer.WriteString(name); - // serializer.Write(counter); - serializer.Write(usage_count); - serializer.Write(increment); - serializer.Write(min_value); - serializer.Write(max_value); - serializer.Write(counter); - serializer.Write(cycle); + 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(); - info->schema = source.Read(); - info->name = source.Read(); - // info->counter = source.Read(); - info->usage_count = source.Read(); - info->increment = source.Read(); - info->min_value = source.Read(); - info->max_value = source.Read(); - info->start_value = source.Read(); - info->cycle = source.Read(); + + 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; } @@ -6755,7 +4070,6 @@ string SequenceCatalogEntry::ToSQL() { ss << " " << (cycle ? "CYCLE" : "NO CYCLE") << ";"; return ss.str(); } - } // namespace duckdb @@ -6785,20 +4099,17 @@ namespace duckdb { //! every row in a table class CheckConstraint : public Constraint { public: - explicit CheckConstraint(unique_ptr expression) - : Constraint(ConstraintType::CHECK), expression(move(expression)) {}; + DUCKDB_API explicit CheckConstraint(unique_ptr expression); unique_ptr expression; public: - string ToString() const override; + DUCKDB_API string ToString() const override; - unique_ptr Copy() override; + DUCKDB_API unique_ptr Copy() const override; - //! Serialize to a stand-alone binary blob - void Serialize(Serializer &serializer) override; - //! Deserializes a CheckConstraint - static unique_ptr Deserialize(Deserializer &source); + DUCKDB_API void Serialize(FieldWriter &writer) const override; + DUCKDB_API static unique_ptr Deserialize(FieldReader &source); }; } // namespace duckdb @@ -6819,22 +4130,21 @@ namespace duckdb { class NotNullConstraint : public Constraint { public: - explicit NotNullConstraint(column_t index) : Constraint(ConstraintType::NOT_NULL), index(index) {}; - ~NotNullConstraint() override { - } + DUCKDB_API explicit NotNullConstraint(column_t index); + DUCKDB_API ~NotNullConstraint() override; //! Column index this constraint pertains to column_t index; public: - string ToString() const override; + DUCKDB_API string ToString() const override; - unique_ptr Copy() override; + DUCKDB_API unique_ptr Copy() const override; //! Serialize to a stand-alone binary blob - void Serialize(Serializer &serializer) override; + DUCKDB_API void Serialize(FieldWriter &writer) const override; //! Deserializes a NotNullConstraint - static unique_ptr Deserialize(Deserializer &source); + DUCKDB_API static unique_ptr Deserialize(FieldReader &source); }; } // namespace duckdb @@ -6856,16 +4166,11 @@ namespace duckdb { class UniqueConstraint : public Constraint { public: - UniqueConstraint(uint64_t index, bool is_primary_key) - : Constraint(ConstraintType::UNIQUE), index(index), is_primary_key(is_primary_key) { - } - UniqueConstraint(vector columns, bool is_primary_key) - : Constraint(ConstraintType::UNIQUE), index(INVALID_INDEX), columns(move(columns)), - is_primary_key(is_primary_key) { - } + DUCKDB_API UniqueConstraint(uint64_t 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 INVALID_INDEX if not used + //! column, equal to DConstants::INVALID_INDEX if not used uint64_t index; //! The set of columns for which this constraint holds by name. Only used when the index field is not used. vector columns; @@ -6873,14 +4178,14 @@ class UniqueConstraint : public Constraint { bool is_primary_key; public: - string ToString() const override; + DUCKDB_API string ToString() const override; - unique_ptr Copy() override; + DUCKDB_API unique_ptr Copy() const override; //! Serialize to a stand-alone binary blob - void Serialize(Serializer &serializer) override; + DUCKDB_API void Serialize(FieldWriter &writer) const override; //! Deserializes a ParsedConstraint - static unique_ptr Deserialize(Deserializer &source); + DUCKDB_API static unique_ptr Deserialize(FieldReader &source); }; } // namespace duckdb @@ -7319,6 +4624,7 @@ void EncodeStringDataPrefix(data_ptr_t dataptr, string_t value, idx_t prefix_len + namespace duckdb { class Key { @@ -7335,6 +4641,11 @@ class Key { return make_unique(move(data), sizeof(element)); } + template + static unique_ptr CreateKey(const Value &element, bool is_little_endian) { + return CreateKey(element.GetValueUnsafe(), is_little_endian); + } + public: data_t &operator[](std::size_t i) { return data[i]; @@ -7347,8 +4658,6 @@ class Key { bool operator>=(const Key &k) const; bool operator==(const Key &k) const; - string ToString(bool is_little_endian, PhysicalType type); - private: template static unique_ptr CreateData(T value, bool is_little_endian) { @@ -7412,21 +4721,22 @@ class Node { unique_ptr prefix; public: - //! Get the position of a child corresponding exactly to the specific byte, returns INVALID_INDEX if not exists + //! 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) { - return INVALID_INDEX; + return DConstants::INVALID_INDEX; } - //! Get the position of the first child that is greater or equal to the specific byte, or INVALID_INDEX if there are - //! no children matching the criteria + //! Get the position of the first child that is greater or equal to the specific byte, or DConstants::INVALID_INDEX + //! if there are no children matching the criteria virtual idx_t GetChildGreaterEqual(uint8_t k, bool &equal) { throw InternalException("Unimplemented GetChildGreaterEqual for ARTNode"); } //! Get the position of the biggest element in node virtual idx_t GetMin(); - //! Get the next position in the node, or INVALID_INDEX if there is no next position. if pos == INVALID_INDEX, then - //! the first valid position in the node will be returned. + //! Get the next position 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 will be returned. virtual idx_t GetNextPos(idx_t pos) { - return INVALID_INDEX; + 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. @@ -7495,10 +4805,10 @@ class Node4 : public Node { public: //! Get position of a byte, returns -1 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 INVALID_INDEX if there are - //! no children matching the criteria + //! Get the position of the first child that is greater or equal to the specific byte, or DConstants::INVALID_INDEX + //! if there are no children matching the criteria idx_t GetChildGreaterEqual(uint8_t k, bool &equal) override; - //! Get the next position in the node, or INVALID_INDEX if there is no next position + //! 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 Node4 Child unique_ptr *GetChild(idx_t pos) override; @@ -7535,10 +4845,10 @@ class Node16 : public Node { public: //! Get position of a byte, returns -1 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 INVALID_INDEX if there are - //! no children matching the criteria + //! Get the position of the first child that is greater or equal to the specific byte, or DConstants::INVALID_INDEX + //! if there are no children matching the criteria idx_t GetChildGreaterEqual(uint8_t k, bool &equal) override; - //! Get the next position in the node, or INVALID_INDEX if there is no next position + //! 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 Node16 Child unique_ptr *GetChild(idx_t pos) override; @@ -7575,10 +4885,10 @@ class Node48 : public Node { public: //! Get position of a byte, returns -1 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 INVALID_INDEX if there are - //! no children matching the criteria + //! Get the position of the first child that is greater or equal to the specific byte, or DConstants::INVALID_INDEX + //! if there are no children matching the criteria idx_t GetChildGreaterEqual(uint8_t k, bool &equal) override; - //! Get the next position in the node, or INVALID_INDEX if there is no next position + //! 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 Node48 Child unique_ptr *GetChild(idx_t pos) override; @@ -7613,12 +4923,12 @@ class Node256 : public Node { unique_ptr child[256]; public: - //! Get position of a specific byte, returns INVALID_INDEX if not exists + //! 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 INVALID_INDEX if there are - //! no children matching the criteria + //! Get the position of the first child that is greater or equal to the specific byte, or DConstants::INVALID_INDEX + //! if there are no children matching the criteria idx_t GetChildGreaterEqual(uint8_t k, bool &equal) override; - //! Get the next position in the node, or INVALID_INDEX if there is no next position + //! 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 Node256 Child unique_ptr *GetChild(idx_t pos) override; @@ -7765,6 +5075,7 @@ class ART : public Index { + #include namespace duckdb { @@ -7776,6 +5087,11 @@ class ParsedExpressionIterator { 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); }; } // namespace duckdb @@ -7845,6 +5161,7 @@ class KeywordHelper { } // namespace duckdb + #include #include @@ -7857,7 +5174,7 @@ idx_t TableCatalogEntry::GetColumnIndex(string &column_name, bool if_exists) { entry = name_map.find(StringUtil::Lower(column_name)); if (entry == name_map.end()) { if (if_exists) { - return INVALID_INDEX; + return DConstants::INVALID_INDEX; } throw BinderException("Table \"%s\" does not have a column with name \"%s\"", name, column_name); } @@ -7962,8 +5279,8 @@ unique_ptr TableCatalogEntry::AlterEntry(ClientContext &context, A static void RenameExpression(ParsedExpression &expr, RenameColumnInfo &info) { if (expr.type == ExpressionType::COLUMN_REF) { auto &colref = (ColumnRefExpression &)expr; - if (colref.column_name == info.old_name) { - colref.column_name = info.new_name; + if (colref.column_names[0] == info.old_name) { + colref.column_names[0] = info.new_name; } } ParsedExpressionIterator::EnumerateChildren( @@ -8036,7 +5353,7 @@ unique_ptr TableCatalogEntry::RemoveColumn(ClientContext &context, auto create_info = make_unique(schema->name, name); create_info->temporary = temporary; idx_t removed_index = GetColumnIndex(info.removed_column, info.if_exists); - if (removed_index == INVALID_INDEX) { + if (removed_index == DConstants::INVALID_INDEX) { return nullptr; } for (idx_t i = 0; i < columns.size(); i++) { @@ -8088,7 +5405,7 @@ unique_ptr TableCatalogEntry::RemoveColumn(ClientContext &context, case ConstraintType::UNIQUE: { auto copy = constraint->Copy(); auto &unique = (UniqueConstraint &)*copy; - if (unique.index != INVALID_INDEX) { + if (unique.index != DConstants::INVALID_INDEX) { if (unique.index == removed_index) { throw CatalogException( "Cannot drop column \"%s\" because there is a UNIQUE constraint that depends on it", @@ -8207,18 +5524,26 @@ vector TableCatalogEntry::GetTypes() { void TableCatalogEntry::Serialize(Serializer &serializer) { D_ASSERT(!internal); - serializer.WriteString(schema->name); - serializer.WriteString(name); - D_ASSERT(columns.size() <= NumericLimits::Maximum()); - serializer.Write((uint32_t)columns.size()); - for (auto &column : columns) { - column.Serialize(serializer); - } - D_ASSERT(constraints.size() <= NumericLimits::Maximum()); - serializer.Write((uint32_t)constraints.size()); - for (auto &constraint : constraints) { - constraint->Serialize(serializer); - } + + FieldWriter writer(serializer); + writer.WriteString(schema->name); + writer.WriteString(name); + writer.WriteRegularSerializableList(columns); + writer.WriteSerializableList(constraints); + writer.Finalize(); +} + +unique_ptr TableCatalogEntry::Deserialize(Deserializer &source) { + auto info = make_unique(); + + FieldReader reader(source); + info->schema = reader.ReadRequired(); + info->table = reader.ReadRequired(); + info->columns = reader.ReadRequiredSerializableList(); + info->constraints = reader.ReadRequiredSerializableList(); + reader.Finalize(); + + return info; } string TableCatalogEntry::ToSQL() { @@ -8245,7 +5570,7 @@ string TableCatalogEntry::ToSQL() { } else if (constraint->type == ConstraintType::UNIQUE) { auto &pk = (UniqueConstraint &)*constraint; vector constraint_columns = pk.columns; - if (pk.index != INVALID_INDEX) { + if (pk.index != DConstants::INVALID_INDEX) { // no columns specified: single column constraint if (pk.is_primary_key) { pk_columns.insert(pk.index); @@ -8272,7 +5597,15 @@ string TableCatalogEntry::ToSQL() { ss << ", "; } auto &column = columns[i]; - ss << KeywordHelper::WriteOptionallyQuoted(column.name) << " " << column.type.ToString(); + ss << KeywordHelper::WriteOptionallyQuoted(column.name) << " "; + switch (column.type.id()) { + case LogicalTypeId::ENUM: + ss << KeywordHelper::WriteOptionallyQuoted(column.type.ToString()); + break; + default: + ss << column.type.ToString(); + break; + } bool not_null = not_null_columns.find(column.oid) != not_null_columns.end(); bool is_single_key_pk = pk_columns.find(column.oid) != pk_columns.end(); bool is_multi_key_pk = multi_key_pks.find(column.name) != multi_key_pks.end(); @@ -8303,26 +5636,6 @@ string TableCatalogEntry::ToSQL() { return ss.str(); } -unique_ptr TableCatalogEntry::Deserialize(Deserializer &source) { - auto info = make_unique(); - - info->schema = source.Read(); - info->table = source.Read(); - auto column_count = source.Read(); - - for (uint32_t i = 0; i < column_count; i++) { - auto column = ColumnDefinition::Deserialize(source); - info->columns.push_back(move(column)); - } - auto constraint_count = source.Read(); - - for (uint32_t i = 0; i < constraint_count; i++) { - auto constraint = Constraint::Deserialize(source); - info->constraints.push_back(move(constraint)); - } - return info; -} - unique_ptr TableCatalogEntry::Copy(ClientContext &context) { auto create_info = make_unique(schema->name, name); for (idx_t i = 0; i < columns.size(); i++) { @@ -8364,14 +5677,14 @@ void TableCatalogEntry::CommitAlter(AlterInfo &info) { if (column_name.empty()) { return; } - idx_t removed_index = INVALID_INDEX; + idx_t removed_index = DConstants::INVALID_INDEX; for (idx_t i = 0; i < columns.size(); i++) { if (columns[i].name == column_name) { removed_index = i; break; } } - D_ASSERT(removed_index != INVALID_INDEX); + D_ASSERT(removed_index != DConstants::INVALID_INDEX); storage->CommitDropColumn(removed_index); } @@ -8400,42 +5713,49 @@ TableFunctionCatalogEntry::TableFunctionCatalogEntry(Catalog *catalog, SchemaCat + #include #include namespace duckdb { TypeCatalogEntry::TypeCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateTypeInfo *info) - : StandardEntry(CatalogType::TYPE_ENTRY, schema, catalog, info->name) { - user_type = make_unique(*info->type); + : StandardEntry(CatalogType::TYPE_ENTRY, schema, catalog, info->name), user_type(info->type) { } void TypeCatalogEntry::Serialize(Serializer &serializer) { - serializer.WriteString(schema->name); - serializer.WriteString(name); - user_type->Serialize(serializer); + FieldWriter writer(serializer); + writer.WriteString(schema->name); + writer.WriteString(name); + writer.WriteSerializable(user_type); + writer.Finalize(); } unique_ptr TypeCatalogEntry::Deserialize(Deserializer &source) { auto info = make_unique(); - info->schema = source.Read(); - info->name = source.Read(); - info->type = make_unique(LogicalType::Deserialize(source)); + + FieldReader reader(source); + info->schema = reader.ReadRequired(); + info->name = reader.ReadRequired(); + info->type = reader.ReadRequiredSerializable(); + reader.Finalize(); + return info; } string TypeCatalogEntry::ToSQL() { std::stringstream ss; - switch (user_type->id()) { + switch (user_type.id()) { case (LogicalTypeId::ENUM): { - auto values_insert_order = EnumType::GetValuesInsertOrder(*user_type); + Vector values_insert_order(EnumType::GetValuesInsertOrder(user_type)); + idx_t size = EnumType::GetSize(user_type); ss << "CREATE TYPE "; - ss << name; + ss << KeywordHelper::WriteOptionallyQuoted(name); ss << " AS ENUM ( "; - for (idx_t i = 0; i < values_insert_order.size(); i++) { - ss << "'" << values_insert_order[i] << "'"; - if (i != values_insert_order.size() - 1) { + for (idx_t i = 0; i < size; i++) { + ss << "'" << values_insert_order.GetValue(i).ToString() << "'"; + if (i != size - 1) { ss << ", "; } } @@ -8497,35 +5817,28 @@ unique_ptr ViewCatalogEntry::AlterEntry(ClientContext &context, Al void ViewCatalogEntry::Serialize(Serializer &serializer) { D_ASSERT(!internal); - serializer.WriteString(schema->name); - serializer.WriteString(name); - serializer.WriteString(sql); - query->Serialize(serializer); - D_ASSERT(aliases.size() <= NumericLimits::Maximum()); - serializer.Write((uint32_t)aliases.size()); - for (auto &alias : aliases) { - serializer.WriteString(alias); - } - serializer.Write((uint32_t)types.size()); - for (auto &sql_type : types) { - sql_type.Serialize(serializer); - } + FieldWriter writer(serializer); + writer.WriteString(schema->name); + writer.WriteString(name); + writer.WriteString(sql); + writer.WriteSerializable(*query); + writer.WriteList(aliases); + writer.WriteRegularSerializableList(types); + writer.Finalize(); } unique_ptr ViewCatalogEntry::Deserialize(Deserializer &source) { auto info = make_unique(); - info->schema = source.Read(); - info->view_name = source.Read(); - info->sql = source.Read(); - info->query = SelectStatement::Deserialize(source); - auto alias_count = source.Read(); - for (uint32_t i = 0; i < alias_count; i++) { - info->aliases.push_back(source.Read()); - } - auto type_count = source.Read(); - for (uint32_t i = 0; i < type_count; i++) { - info->types.push_back(LogicalType::Deserialize(source)); - } + + FieldReader reader(source); + info->schema = reader.ReadRequired(); + info->view_name = reader.ReadRequired(); + info->sql = reader.ReadRequired(); + info->query = reader.ReadRequiredSerializable(); + info->aliases = reader.ReadRequiredList(); + info->types = reader.ReadRequiredSerializableList(); + reader.Finalize(); + return info; } @@ -8593,19 +5906,29 @@ string CatalogEntry::ToSQL() { + namespace duckdb { -CatalogSearchPath::CatalogSearchPath(ClientContext &context_p) : context(context_p), paths(ParsePaths("")) { +CatalogSearchPath::CatalogSearchPath(ClientContext &context_p) : context(context_p) { + SetPaths(ParsePaths("")); } -const vector &CatalogSearchPath::Get() { - Value value; - context.TryGetCurrentSetting("search_path", value); - if (value.str_value != last_value) { - paths = ParsePaths(value.str_value); - last_value = value.str_value; +void CatalogSearchPath::Set(const string &new_value, bool is_set_schema) { + auto new_paths = ParsePaths(new_value); + 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); + } } + this->set_paths = move(new_paths); + SetPaths(set_paths); +} +const vector &CatalogSearchPath::Get() { return paths; } @@ -8620,18 +5943,19 @@ const string &CatalogSearchPath::GetDefault() { return paths[1]; } -vector CatalogSearchPath::ParsePaths(const string &value) { - vector paths; +void CatalogSearchPath::SetPaths(vector new_paths) { + paths.clear(); + paths.reserve(new_paths.size() + 3); paths.emplace_back(TEMP_SCHEMA); - - auto given_paths = StringUtil::SplitWithQuote(value); - for (const auto &p : given_paths) { - paths.emplace_back(StringUtil::Lower(p)); + for (auto &path : new_paths) { + paths.push_back(move(path)); } - paths.emplace_back(DEFAULT_SCHEMA); paths.emplace_back("pg_catalog"); - return paths; +} + +vector CatalogSearchPath::ParsePaths(const string &value) { + return StringUtil::SplitWithQuote(StringUtil::Lower(value)); } } // namespace duckdb @@ -8742,9 +6066,74 @@ class TransactionManager { +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/expression/constant_expression.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { + +//! ConstantExpression represents a constant value in the query +class ConstantExpression : public ParsedExpression { +public: + explicit ConstantExpression(Value val); + + //! The constant value referenced + Value value; + +public: + string ToString() const override; + + static bool Equals(const ConstantExpression *a, const ConstantExpression *b); + hash_t Hash() const override; + + unique_ptr Copy() const override; + + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(ExpressionType type, FieldReader &source); +}; + +} // namespace duckdb + namespace duckdb { +//! Class responsible to keep track of state when removing entries from the catalog. +//! When deleting, many types of errors can be thrown, since we want to avoid try/catch blocks +//! this class makes sure that whatever elements were modified are returned to a correct state +//! when exceptions are thrown. +//! The idea here is to use RAII (Resource acquisition is initialization) to mimic a try/catch/finally block. +//! If any exception is raised when this object exists, then its destructor will be called +//! and the entry will return to its previous state during deconstruction. +class EntryDropper { +public: + //! Both constructor and destructor are privates because they should only be called by DropEntryDependencies + explicit EntryDropper(CatalogSet &catalog_set, idx_t entry_index) + : catalog_set(catalog_set), entry_index(entry_index) { + old_deleted = catalog_set.entries[entry_index].get()->deleted; + } + + ~EntryDropper() { + catalog_set.entries[entry_index].get()->deleted = old_deleted; + } + +private: + //! The current catalog_set + CatalogSet &catalog_set; + //! Keeps track of the state of the entry before starting the delete + bool old_deleted; + //! Index of entry to be deleted + idx_t entry_index; +}; + CatalogSet::CatalogSet(Catalog &catalog, unique_ptr defaults) : catalog(catalog), defaults(move(defaults)) { } @@ -8834,6 +6223,23 @@ bool CatalogSet::GetEntryInternal(ClientContext &context, const string &name, id return GetEntryInternal(context, entry_index, catalog_entry); } +bool CatalogSet::AlterOwnership(ClientContext &context, ChangeOwnershipInfo *info) { + idx_t entry_index; + CatalogEntry *entry; + if (!GetEntryInternal(context, info->name, entry_index, entry)) { + return false; + } + + auto owner_entry = catalog.GetEntry(context, info->owner_schema, info->owner_name); + if (!owner_entry) { + return false; + } + + catalog.dependency_manager->AddOwnership(context, owner_entry, entry); + + return true; +} + bool CatalogSet::AlterEntry(ClientContext &context, const string &name, AlterInfo *alter_info) { auto &transaction = Transaction::GetTransaction(context); // lock the catalog for writing @@ -8861,6 +6267,7 @@ bool CatalogSet::AlterEntry(ClientContext &context, const string &name, AlterInf // alter failed, but did not result in an error return true; } + if (value->name != original_name) { auto mapping_value = GetMapping(context, value->name); if (mapping_value && !mapping_value->deleted) { @@ -8894,16 +6301,26 @@ bool CatalogSet::AlterEntry(ClientContext &context, const string &name, AlterInf return true; } -void CatalogSet::DropEntryInternal(ClientContext &context, idx_t entry_index, CatalogEntry &entry, bool cascade, - set_lock_map_t &lock_set) { - auto &transaction = Transaction::GetTransaction(context); +void CatalogSet::DropEntryDependencies(ClientContext &context, idx_t entry_index, CatalogEntry &entry, bool cascade) { + + // Stores the deleted value of the entry before starting the process + EntryDropper dropper(*this, entry_index); + + // To correctly delete the object and its dependencies, it temporarily is set to deleted. + entries[entry_index].get()->deleted = true; + // check any dependencies of this object - entry.catalog->dependency_manager->DropObject(context, &entry, cascade, lock_set); + entry.catalog->dependency_manager->DropObject(context, &entry, cascade); - // add this catalog to the lock set, if it is not there yet - if (lock_set.find(this) == lock_set.end()) { - lock_set.insert(make_pair(this, unique_lock(catalog_lock))); - } + // dropper destructor is called here + // the destructor makes sure to return the value to the previous state + // dropper.~EntryDropper() +} + +void CatalogSet::DropEntryInternal(ClientContext &context, idx_t entry_index, CatalogEntry &entry, bool cascade) { + auto &transaction = Transaction::GetTransaction(context); + + DropEntryDependencies(context, entry_index, entry, cascade); // create a new entry and replace the currently stored one // set the timestamp to the timestamp of the current transaction @@ -8934,9 +6351,7 @@ bool CatalogSet::DropEntry(ClientContext &context, const string &name, bool casc throw CatalogException("Cannot drop entry \"%s\" because it is an internal system entry", entry->name); } - // create the lock set for this delete operation - set_lock_map_t lock_set; - DropEntryInternal(context, entry_index, *entry, cascade, lock_set); + DropEntryInternal(context, entry_index, *entry, cascade); return true; } @@ -9149,9 +6564,10 @@ void CatalogSet::AdjustDependency(CatalogEntry *entry, TableCatalogEntry *table, } } } + void CatalogSet::AdjustTableDependencies(CatalogEntry *entry) { if (entry->type == CatalogType::TABLE_ENTRY && entry->parent->type == CatalogType::TABLE_ENTRY) { - // If its a table entry we have to check for possibly removing or adding user type dependencies + // If it's a table entry we have to check for possibly removing or adding user type dependencies auto old_table = (TableCatalogEntry *)entry->parent; auto new_table = (TableCatalogEntry *)entry; @@ -9258,7 +6674,6 @@ void CatalogSet::Scan(const std::function &callback) { } } } - } // namespace duckdb //===----------------------------------------------------------------------===// @@ -9305,6 +6720,13 @@ struct SimplifiedToken { idx_t start; }; +enum class KeywordCategory : uint8_t { KEYWORD_RESERVED, KEYWORD_UNRESERVED, KEYWORD_TYPE_FUNC, KEYWORD_COL_NAME }; + +struct ParserKeyword { + string name; + KeywordCategory category; +}; + } // namespace duckdb @@ -9315,13 +6737,21 @@ struct PGList; namespace duckdb { +struct ParserOptions { + bool preserve_identifier_case = true; +}; + //! The parser is responsible for parsing the query and converting it into a set //! of parsed statements. The parsed statements can then be converted into a //! plan and executed. class Parser { public: - Parser(); + Parser(ParserOptions options = ParserOptions()); + //! The parsed SQL statements from an invocation to ParseQuery. + vector> statements; + +public: //! Attempts to parse a query into a series of SQL statements. Returns //! whether or not the parsing was successful. If the parsing was //! successful, the parsed statements will be stored in the statements @@ -9333,27 +6763,26 @@ class Parser { //! Returns true if the given text matches a keyword of the parser static bool IsKeyword(const string &text); + //! Returns a list of all keywords in the parser + static vector KeywordList(); //! Parses a list of expressions (i.e. the list found in a SELECT clause) - static vector> ParseExpressionList(const string &select_list); + static vector> ParseExpressionList(const string &select_list, + ParserOptions options = ParserOptions()); //! Parses a list as found in an ORDER BY expression (i.e. including optional ASCENDING/DESCENDING modifiers) - static vector ParseOrderList(const string &select_list); + static vector ParseOrderList(const string &select_list, ParserOptions options = ParserOptions()); //! Parses an update list (i.e. the list found in the SET clause of an UPDATE statement) static void ParseUpdateList(const string &update_list, vector &update_columns, - vector> &expressions); + vector> &expressions, + ParserOptions options = ParserOptions()); //! Parses a VALUES list (i.e. the list of expressions after a VALUES clause) - static vector>> ParseValuesList(const string &value_list); + static vector>> ParseValuesList(const string &value_list, + ParserOptions options = ParserOptions()); //! Parses a column list (i.e. as found in a CREATE TABLE statement) - static vector ParseColumnList(const string &column_list); - - //! The parsed SQL statements from an invocation to ParseQuery. - vector> statements; + static vector ParseColumnList(const string &column_list, ParserOptions options = ParserOptions()); private: - //! Transform a Postgres parse tree into a set of SQL Statements - bool TransformList(duckdb_libpgquery::PGList *tree); - //! Transform a single Postgres parse node into a SQL Statement. - unique_ptr TransformNode(duckdb_libpgquery::PGNode *stmt); + ParserOptions options; }; } // namespace duckdb @@ -9447,6 +6876,7 @@ static DefaultMacro internal_macros[] = { {DEFAULT_SCHEMA, "array_append", {"arr", "el", nullptr}, "list_append(arr, el)"}, {DEFAULT_SCHEMA, "list_prepend", {"e", "l", nullptr}, "list_concat(list_value(e), l)"}, {DEFAULT_SCHEMA, "array_prepend", {"el", "arr", nullptr}, "list_prepend(el, arr)"}, + {DEFAULT_SCHEMA, "generate_subscripts", {"arr", "dim", nullptr}, "unnest(generate_series(1, array_length(arr, dim)))"}, {nullptr, nullptr, {nullptr}, nullptr}}; static unique_ptr GetDefaultFunction(const string &schema, const string &name) { @@ -9642,6 +7072,7 @@ vector DefaultViewGenerator::GetDefaultEntries() { + namespace duckdb { DependencyManager::DependencyManager(Catalog &catalog) : catalog(catalog) { @@ -9669,8 +7100,7 @@ void DependencyManager::AddObject(ClientContext &context, CatalogEntry *object, dependencies_map[object] = dependencies; } -void DependencyManager::DropObject(ClientContext &context, CatalogEntry *object, bool cascade, - set_lock_map_t &lock_set) { +void DependencyManager::DropObject(ClientContext &context, CatalogEntry *object, bool cascade) { D_ASSERT(dependents_map.find(object) != dependents_map.end()); // first check the objects that depend on this object @@ -9690,9 +7120,10 @@ void DependencyManager::DropObject(ClientContext &context, CatalogEntry *object, continue; } // conflict: attempting to delete this object but the dependent object still exists - if (cascade || dep.dependency_type == DependencyType::DEPENDENCY_AUTOMATIC) { + if (cascade || dep.dependency_type == DependencyType::DEPENDENCY_AUTOMATIC || + dep.dependency_type == DependencyType::DEPENDENCY_OWNS) { // cascade: drop the dependent object - catalog_set.DropEntryInternal(context, entry_index, *dependency_entry, cascade, lock_set); + catalog_set.DropEntryInternal(context, entry_index, *dependency_entry, cascade); } else { // no cascade and there are objects that depend on this object: throw error throw CatalogException("Cannot drop entry \"%s\" because there are entries that " @@ -9707,6 +7138,7 @@ void DependencyManager::AlterObject(ClientContext &context, CatalogEntry *old_ob D_ASSERT(dependencies_map.find(old_obj) != dependencies_map.end()); // first check the objects that depend on this object + vector owned_objects_to_add; auto &dependent_objects = dependents_map[old_obj]; for (auto &dep : dependent_objects) { // look up the entry in the catalog set @@ -9717,6 +7149,11 @@ void DependencyManager::AlterObject(ClientContext &context, CatalogEntry *old_ob // the dependent object was already deleted, no conflict continue; } + if (dep.dependency_type == DependencyType::DEPENDENCY_OWNS) { + // the dependent object is owned by the current object + owned_objects_to_add.push_back(dep.entry); + continue; + } // conflict: attempting to alter this object but the dependent object still exists // no cascade and there are objects that depend on this object: throw error throw CatalogException("Cannot alter entry \"%s\" because there are entries that " @@ -9732,7 +7169,7 @@ void DependencyManager::AlterObject(ClientContext &context, CatalogEntry *old_ob auto table = (TableCatalogEntry *)new_obj; bool deleted_dependency = true; for (auto &column : table->columns) { - if (column.type == *user_type->user_type) { + if (column.type == user_type->user_type) { deleted_dependency = false; break; } @@ -9770,6 +7207,12 @@ void DependencyManager::AlterObject(ClientContext &context, CatalogEntry *old_ob dependencies_map[new_obj].insert(dependency); dependents_map[dependency].insert(new_obj); } + + for (auto &dependency : owned_objects_to_add) { + dependents_map[new_obj].insert(Dependency(dependency, DependencyType::DEPENDENCY_OWNS)); + dependents_map[dependency].insert(Dependency(new_obj, DependencyType::DEPENDENCY_OWNED_BY)); + dependencies_map[new_obj].insert(dependency); + } } void DependencyManager::EraseObject(CatalogEntry *object) { @@ -9806,6 +7249,38 @@ void DependencyManager::Scan(const std::function write_lock(catalog.write_lock); + + // If the owner is already owned by something else, throw an error + for (auto &dep : dependents_map[owner]) { + if (dep.dependency_type == DependencyType::DEPENDENCY_OWNED_BY) { + throw CatalogException(owner->name + " already owned by " + dep.entry->name); + } + } + + // If the entry is already owned, throw an error + for (auto &dep : dependents_map[entry]) { + // if the entry is already owned, throw error + if (dep.entry != owner) { + throw CatalogException(entry->name + " already depends on " + dep.entry->name); + } + // if the entry owns the owner, throw error + if (dep.entry == owner && dep.dependency_type == DependencyType::DEPENDENCY_OWNS) { + throw CatalogException(entry->name + " already owns " + owner->name + + ". Cannot have circular dependencies"); + } + } + + // Emplace guarantees that the same object cannot be inserted twice in the unordered_set + // In the case AddOwnership is called twice, because of emplace, the object will not be repeated in the set. + // We use an automatic dependency because if the Owner gets deleted, then the owned objects are also deleted + dependents_map[owner].emplace(Dependency(entry, DependencyType::DEPENDENCY_OWNS)); + dependents_map[entry].emplace(Dependency(owner, DependencyType::DEPENDENCY_OWNED_BY)); + dependencies_map[owner].emplace(entry); +} + } // namespace duckdb @@ -9856,57 +7331,27 @@ data_ptr_t Allocator::ReallocateData(data_ptr_t pointer, idx_t size) { } } // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/arrow_wrapper.hpp -// -// -//===----------------------------------------------------------------------===// -//! Here we have the internal duckdb classes that interact with Arrow's Internal Header (i.e., duckdb/commons/arrow.hpp) -namespace duckdb { -class ArrowSchemaWrapper { -public: - ArrowSchema arrow_schema; - ArrowSchemaWrapper() { - arrow_schema.release = nullptr; - } +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/result_arrow_wrapper.hpp +// +// +//===----------------------------------------------------------------------===// - ~ArrowSchemaWrapper(); -}; -class ArrowArrayWrapper { -public: - ArrowArray arrow_array; - ArrowArrayWrapper() { - arrow_array.length = 0; - arrow_array.release = nullptr; - } - ~ArrowArrayWrapper(); -}; -class ArrowArrayStreamWrapper { -public: - ArrowArrayStream arrow_array_stream; - int64_t number_of_rows; - void GetSchema(ArrowSchemaWrapper &schema); - unique_ptr GetNextChunk(); - const char *GetError(); - ~ArrowArrayStreamWrapper(); - ArrowArrayStreamWrapper() { - arrow_array_stream.release = nullptr; - } -}; +namespace duckdb { class ResultArrowArrayStreamWrapper { public: explicit ResultArrowArrayStreamWrapper(unique_ptr result, idx_t approx_batch_size); @@ -9921,14 +7366,8 @@ class ResultArrowArrayStreamWrapper { static void MyStreamRelease(struct ArrowArrayStream *stream); static const char *MyStreamGetLastError(struct ArrowArrayStream *stream); }; - } // namespace duckdb - - - - - namespace duckdb { ArrowSchemaWrapper::~ArrowSchemaWrapper() { @@ -9979,8 +7418,8 @@ void ArrowArrayStreamWrapper::GetSchema(ArrowSchemaWrapper &schema) { // LCOV_EXCL_STOP } -unique_ptr ArrowArrayStreamWrapper::GetNextChunk() { - auto current_chunk = make_unique(); +shared_ptr ArrowArrayStreamWrapper::GetNextChunk() { + auto current_chunk = make_shared(); if (arrow_array_stream.get_next(&arrow_array_stream, ¤t_chunk->arrow_array)) { // LCOV_EXCL_START throw InvalidInputException("arrow_scan: get_next failed(): %s", string(GetError())); } // LCOV_EXCL_STOP @@ -10004,7 +7443,7 @@ int ResultArrowArrayStreamWrapper::MyStreamGetSchema(struct ArrowArrayStream *st } if (result.type == QueryResultType::STREAM_RESULT) { auto &stream_result = (StreamQueryResult &)result; - if (!stream_result.is_open) { + if (!stream_result.IsOpen()) { my_stream->last_error = "Query Stream is closed"; return -1; } @@ -10025,9 +7464,10 @@ int ResultArrowArrayStreamWrapper::MyStreamGetNext(struct ArrowArrayStream *stre } if (result.type == QueryResultType::STREAM_RESULT) { auto &stream_result = (StreamQueryResult &)result; - if (!stream_result.is_open) { - my_stream->last_error = "Query Stream is closed"; - return -1; + if (!stream_result.IsOpen()) { + // Nothing to output + out->release = nullptr; + return 0; } } unique_ptr chunk_result = result.Fetch(); @@ -10132,13 +7572,224 @@ uint64_t Checksum(uint8_t *buffer, size_t size) { } } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/compressed_file_system.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { +class CompressedFile; + +struct StreamData { + // various buffers & pointers + bool write = false; + unique_ptr in_buff; + unique_ptr out_buff; + data_ptr_t out_buff_start = nullptr; + data_ptr_t out_buff_end = nullptr; + data_ptr_t in_buff_start = nullptr; + data_ptr_t in_buff_end = nullptr; + + idx_t in_buf_size = 0; + idx_t out_buf_size = 0; +}; + +struct StreamWrapper { + DUCKDB_API virtual ~StreamWrapper(); + + DUCKDB_API virtual void Initialize(CompressedFile &file, bool write) = 0; + DUCKDB_API virtual bool Read(StreamData &stream_data) = 0; + DUCKDB_API virtual void Write(CompressedFile &file, StreamData &stream_data, data_ptr_t buffer, + int64_t nr_bytes) = 0; + DUCKDB_API virtual void Close() = 0; +}; + +class CompressedFileSystem : public FileSystem { +public: + DUCKDB_API int64_t Read(FileHandle &handle, void *buffer, int64_t nr_bytes) override; + DUCKDB_API int64_t Write(FileHandle &handle, void *buffer, int64_t nr_bytes) override; + + DUCKDB_API void Reset(FileHandle &handle) override; + + DUCKDB_API int64_t GetFileSize(FileHandle &handle) override; + + DUCKDB_API bool OnDiskFile(FileHandle &handle) override; + DUCKDB_API bool CanSeek() override; + + DUCKDB_API virtual unique_ptr CreateStream() = 0; + DUCKDB_API virtual idx_t InBufferSize() = 0; + DUCKDB_API virtual idx_t OutBufferSize() = 0; +}; + +class CompressedFile : public FileHandle { +public: + DUCKDB_API CompressedFile(CompressedFileSystem &fs, unique_ptr child_handle_p, const string &path); + DUCKDB_API virtual ~CompressedFile() override; + + CompressedFileSystem &compressed_fs; + unique_ptr child_handle; + //! Whether the file is opened for reading or for writing + bool write = false; + StreamData stream_data; + +public: + DUCKDB_API void Initialize(bool write); + DUCKDB_API int64_t ReadData(void *buffer, int64_t nr_bytes); + DUCKDB_API int64_t WriteData(data_ptr_t buffer, int64_t nr_bytes); + DUCKDB_API void Close() override; + +private: + unique_ptr stream_wrapper; +}; + +} // namespace duckdb + + +namespace duckdb { + +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)) { +} + +CompressedFile::~CompressedFile() { + Close(); +} + +void CompressedFile::Initialize(bool write) { + Close(); + + this->write = write; + stream_data.in_buf_size = compressed_fs.InBufferSize(); + stream_data.out_buf_size = compressed_fs.OutBufferSize(); + stream_data.in_buff = unique_ptr(new data_t[stream_data.in_buf_size]); + stream_data.in_buff_start = stream_data.in_buff.get(); + stream_data.in_buff_end = stream_data.in_buff.get(); + stream_data.out_buff = unique_ptr(new data_t[stream_data.out_buf_size]); + stream_data.out_buff_start = stream_data.out_buff.get(); + stream_data.out_buff_end = stream_data.out_buff.get(); + + stream_wrapper = compressed_fs.CreateStream(); + stream_wrapper->Initialize(*this, write); +} + +int64_t CompressedFile::ReadData(void *buffer, int64_t remaining) { + idx_t total_read = 0; + while (true) { + // first check if there are input bytes available in the output buffers + if (stream_data.out_buff_start != stream_data.out_buff_end) { + // there is! copy it into the output buffer + idx_t available = MinValue(remaining, stream_data.out_buff_end - stream_data.out_buff_start); + memcpy(data_ptr_t(buffer) + total_read, stream_data.out_buff_start, available); + + // increment the total read variables as required + stream_data.out_buff_start += available; + total_read += available; + remaining -= available; + if (remaining == 0) { + // done! read enough + return total_read; + } + } + if (!stream_wrapper) { + return total_read; + } + + // ran out of buffer: read more data from the child stream + stream_data.out_buff_start = stream_data.out_buff.get(); + stream_data.out_buff_end = stream_data.out_buff.get(); + D_ASSERT(stream_data.in_buff_start <= stream_data.in_buff_end); + D_ASSERT(stream_data.in_buff_end <= stream_data.in_buff_start + stream_data.in_buf_size); + + // read more input if none available + if (stream_data.in_buff_start == stream_data.in_buff_end) { + // empty input buffer: refill from the start + stream_data.in_buff_start = stream_data.in_buff.get(); + stream_data.in_buff_end = stream_data.in_buff_start; + auto sz = child_handle->Read(stream_data.in_buff.get(), stream_data.in_buf_size); + if (sz <= 0) { + stream_wrapper.reset(); + break; + } + stream_data.in_buff_end = stream_data.in_buff_start + sz; + } + + auto finished = stream_wrapper->Read(stream_data); + if (finished) { + stream_wrapper.reset(); + } + } + return total_read; +} + +int64_t CompressedFile::WriteData(data_ptr_t buffer, int64_t nr_bytes) { + stream_wrapper->Write(*this, stream_data, buffer, nr_bytes); + return nr_bytes; +} + +void CompressedFile::Close() { + if (stream_wrapper) { + stream_wrapper->Close(); + stream_wrapper.reset(); + } + stream_data.in_buff.reset(); + stream_data.out_buff.reset(); + stream_data.out_buff_start = nullptr; + stream_data.out_buff_end = nullptr; + stream_data.in_buff_start = nullptr; + stream_data.in_buff_end = nullptr; + stream_data.in_buf_size = 0; + stream_data.out_buf_size = 0; +} + +int64_t CompressedFileSystem::Read(FileHandle &handle, void *buffer, int64_t nr_bytes) { + auto &compressed_file = (CompressedFile &)handle; + return compressed_file.ReadData(buffer, nr_bytes); +} + +int64_t CompressedFileSystem::Write(FileHandle &handle, void *buffer, int64_t nr_bytes) { + auto &compressed_file = (CompressedFile &)handle; + return compressed_file.WriteData((data_ptr_t)buffer, nr_bytes); +} + +void CompressedFileSystem::Reset(FileHandle &handle) { + auto &compressed_file = (CompressedFile &)handle; + compressed_file.child_handle->Reset(); + compressed_file.Initialize(compressed_file.write); +} + +int64_t CompressedFileSystem::GetFileSize(FileHandle &handle) { + auto &compressed_file = (CompressedFile &)handle; + return compressed_file.child_handle->GetFileSize(); +} + +bool CompressedFileSystem::OnDiskFile(FileHandle &handle) { + auto &compressed_file = (CompressedFile &)handle; + return compressed_file.child_handle->OnDiskFile(); +} + +bool CompressedFileSystem::CanSeek() { + return false; +} + +} // namespace duckdb namespace duckdb { -const idx_t INVALID_INDEX = (idx_t)-1; +constexpr const idx_t DConstants::INVALID_INDEX; const row_t MAX_ROW_ID = 4611686018427388000ULL; // 2^62 const column_t COLUMN_IDENTIFIER_ROW_ID = (column_t)-1; const sel_t ZERO_VECTOR[STANDARD_VECTOR_SIZE] = {0}; @@ -10876,6 +8527,27 @@ ExpressionType FlipComparisionExpression(ExpressionType type) { } // namespace duckdb + +namespace duckdb { + +FileCompressionType FileCompressionTypeFromString(const string &input) { + auto parameter = StringUtil::Lower(input); + if (parameter == "infer" || parameter == "auto") { + return FileCompressionType::AUTO_DETECT; + } else if (parameter == "gzip") { + return FileCompressionType::GZIP; + } else if (parameter == "zstd") { + return FileCompressionType::ZSTD; + } else if (parameter == "uncompressed" || parameter == "none" || parameter.empty()) { + return FileCompressionType::UNCOMPRESSED; + } else { + throw ParserException("Unrecognized file compression type \"%s\"", input); + } +} + +} // namespace duckdb + + namespace duckdb { string JoinTypeToString(JoinType type) { @@ -10955,6 +8627,8 @@ string LogicalOperatorToString(LogicalOperatorType type) { return "TOP_N"; case LogicalOperatorType::LOGICAL_SAMPLE: return "SAMPLE"; + case LogicalOperatorType::LOGICAL_LIMIT_PERCENT: + return "LIMIT_PERCENT"; case LogicalOperatorType::LOGICAL_COPY_TO_FILE: return "COPY_TO_FILE"; case LogicalOperatorType::LOGICAL_JOIN: @@ -11031,42 +8705,53 @@ string LogicalOperatorToString(LogicalOperatorType type) { + namespace duckdb { +struct DefaultOptimizerType { + const char *name; + OptimizerType type; +}; + +static DefaultOptimizerType internal_optimizer_types[] = { + {"expression_rewriter", OptimizerType::EXPRESSION_REWRITER}, + {"filter_pullup", OptimizerType::FILTER_PULLUP}, + {"filter_pushdown", OptimizerType::FILTER_PUSHDOWN}, + {"regex_range", OptimizerType::REGEX_RANGE}, + {"in_clause", OptimizerType::IN_CLAUSE}, + {"join_order", OptimizerType::JOIN_ORDER}, + {"deliminator", OptimizerType::DELIMINATOR}, + {"unused_columns", OptimizerType::UNUSED_COLUMNS}, + {"statistics_propagation", OptimizerType::STATISTICS_PROPAGATION}, + {"common_subexpressions", OptimizerType::COMMON_SUBEXPRESSIONS}, + {"common_aggregate", OptimizerType::COMMON_AGGREGATE}, + {"column_lifetime", OptimizerType::COLUMN_LIFETIME}, + {"top_n", OptimizerType::TOP_N}, + {"reorder_filter", OptimizerType::REORDER_FILTER}, + {nullptr, OptimizerType::INVALID}}; + string OptimizerTypeToString(OptimizerType type) { - switch (type) { - case OptimizerType::EXPRESSION_REWRITER: - return "expression_rewriter"; - case OptimizerType::FILTER_PULLUP: - return "filter_pullup"; - case OptimizerType::FILTER_PUSHDOWN: - return "filter_pushdown"; - case OptimizerType::REGEX_RANGE: - return "regex_range"; - case OptimizerType::IN_CLAUSE: - return "in_clause"; - case OptimizerType::JOIN_ORDER: - return "join_order"; - case OptimizerType::DELIMINATOR: - return "deliminator"; - case OptimizerType::UNUSED_COLUMNS: - return "unused_columns"; - case OptimizerType::STATISTICS_PROPAGATION: - return "statistics_propagation"; - case OptimizerType::COMMON_SUBEXPRESSIONS: - return "common_subexpressions"; - case OptimizerType::COMMON_AGGREGATE: - return "common_aggregate"; - case OptimizerType::COLUMN_LIFETIME: - return "column_lifetime"; - case OptimizerType::TOP_N: - return "top_n"; - case OptimizerType::REORDER_FILTER: - return "reorder_filter"; - case OptimizerType::INVALID: // LCOV_EXCL_START - break; + for (idx_t i = 0; internal_optimizer_types[i].name; i++) { + if (internal_optimizer_types[i].type == type) { + return internal_optimizer_types[i].name; + } } - return "INVALID"; // LCOV_EXCL_STOP + throw InternalException("Invalid optimizer type"); +} + +OptimizerType OptimizerTypeFromString(const string &str) { + for (idx_t i = 0; internal_optimizer_types[i].name; i++) { + if (internal_optimizer_types[i].name == str) { + return internal_optimizer_types[i].type; + } + } + // optimizer not found, construct candidate list + vector optimizer_names; + for (idx_t i = 0; internal_optimizer_types[i].name; i++) { + optimizer_names.emplace_back(internal_optimizer_types[i].name); + } + throw ParserException("Optimizer type \"%s\" not recognized\n%s", str, + StringUtil::CandidatesErrorMessage(optimizer_names, str, "Candidate optimizers")); } } // namespace duckdb @@ -11089,6 +8774,8 @@ string PhysicalOperatorToString(PhysicalOperatorType type) { return "ORDER_BY"; case PhysicalOperatorType::LIMIT: return "LIMIT"; + case PhysicalOperatorType::LIMIT_PERCENT: + return "LIMIT_PERCENT"; case PhysicalOperatorType::RESERVOIR_SAMPLE: return "RESERVOIR_SAMPLE"; case PhysicalOperatorType::STREAMING_SAMPLE: @@ -11097,6 +8784,8 @@ string PhysicalOperatorToString(PhysicalOperatorType type) { return "TOP_N"; case PhysicalOperatorType::WINDOW: return "WINDOW"; + case PhysicalOperatorType::STREAMING_WINDOW: + return "STREAMING_WINDOW"; case PhysicalOperatorType::UNNEST: return "UNNEST"; case PhysicalOperatorType::SIMPLE_AGGREGATE: @@ -11143,6 +8832,8 @@ string PhysicalOperatorToString(PhysicalOperatorType type) { return "CREATE_INDEX"; case PhysicalOperatorType::EXPLAIN: return "EXPLAIN"; + case PhysicalOperatorType::EXPLAIN_ANALYZE: + return "EXPLAIN_ANALYZE"; case PhysicalOperatorType::EXECUTE: return "EXECUTE"; case PhysicalOperatorType::VACUUM: @@ -11344,6 +9035,14 @@ const char *Exception::what() const noexcept { return exception_message_.c_str(); } +bool Exception::UncaughtException() { +#if __cplusplus >= 201703L + return std::uncaught_exceptions() > 0; +#else + return std::uncaught_exception(); +#endif +} + string Exception::ConstructMessageRecursive(const string &msg, vector &values) { return ExceptionFormatValue::Format(msg, values); } @@ -11416,11 +9115,17 @@ string Exception::ExceptionTypeToString(ExceptionType type) { return "Invalid Input"; case ExceptionType::OUT_OF_MEMORY: return "Out of Memory"; + case ExceptionType::PERMISSION: + return "Permission"; default: return "Unknown"; } } +StandardException::StandardException(ExceptionType exception_type, const string &message) + : Exception(exception_type, message) { +} + CastException::CastException(const PhysicalType orig_type, const PhysicalType new_type) : Exception(ExceptionType::CONVERSION, "Type " + TypeIdToString(orig_type) + " can't be cast as " + TypeIdToString(new_type)) { @@ -11497,6 +9202,9 @@ CatalogException::CatalogException(const string &msg) : StandardException(Except ParserException::ParserException(const string &msg) : StandardException(ExceptionType::PARSER, msg) { } +PermissionException::PermissionException(const string &msg) : StandardException(ExceptionType::PERMISSION, msg) { +} + SyntaxException::SyntaxException(const string &msg) : Exception(ExceptionType::SYNTAX, msg) { } @@ -17237,6 +14945,16 @@ FMT_END_NAMESPACE namespace duckdb { +ExceptionFormatValue::ExceptionFormatValue(double dbl_val) + : type(ExceptionFormatValueType::FORMAT_VALUE_TYPE_DOUBLE), dbl_val(dbl_val) { +} +ExceptionFormatValue::ExceptionFormatValue(int64_t int_val) + : type(ExceptionFormatValueType::FORMAT_VALUE_TYPE_INTEGER), int_val(int_val) { +} +ExceptionFormatValue::ExceptionFormatValue(string str_val) + : type(ExceptionFormatValueType::FORMAT_VALUE_TYPE_STRING), str_val(move(str_val)) { +} + template <> ExceptionFormatValue ExceptionFormatValue::CreateFormatValue(PhysicalType value) { return ExceptionFormatValue(TypeIdToString(value)); @@ -17289,6 +15007,92 @@ string ExceptionFormatValue::Format(const string &msg, vector()), field_count(0) { +} + +FieldWriter::~FieldWriter() { + if (Exception::UncaughtException()) { + return; + } + // finalize should always have been called, unless this is destroyed as part of stack unwinding + D_ASSERT(!buffer); +} + +void FieldWriter::WriteData(const_data_ptr_t buffer_ptr, idx_t write_size) { + D_ASSERT(buffer); + buffer->WriteData(buffer_ptr, write_size); +} + +template <> +void FieldWriter::Write(const string &val) { + Write((uint32_t)val.size()); + if (!val.empty()) { + WriteData((const_data_ptr_t)val.c_str(), val.size()); + } +} + +void FieldWriter::Finalize() { + D_ASSERT(buffer); + + serializer.Write(field_count); + serializer.Write(buffer->blob.size); + serializer.WriteData(buffer->blob.data.get(), buffer->blob.size); + + buffer.reset(); +} + +//===--------------------------------------------------------------------===// +// Field Deserializer +//===--------------------------------------------------------------------===// +FieldDeserializer::FieldDeserializer(Deserializer &root) : root(root), remaining_data(idx_t(-1)) { +} + +void FieldDeserializer::ReadData(data_ptr_t buffer, idx_t read_size) { + D_ASSERT(remaining_data != idx_t(-1)); + D_ASSERT(read_size <= remaining_data); + root.ReadData(buffer, read_size); + remaining_data -= read_size; +} + +idx_t FieldDeserializer::RemainingData() { + return remaining_data; +} + +void FieldDeserializer::SetRemainingData(idx_t remaining_data) { + this->remaining_data = remaining_data; +} + +//===--------------------------------------------------------------------===// +// Field Reader +//===--------------------------------------------------------------------===// +FieldReader::FieldReader(Deserializer &source_p) : source(source_p), field_count(0) { + max_field_count = source_p.Read(); + total_size = source_p.Read(); + D_ASSERT(max_field_count > 0); + source.SetRemainingData(total_size); +} + +FieldReader::~FieldReader() { +} + +void FieldReader::Finalize() { + if (field_count < max_field_count) { + // we can handle this case by calling source.ReadData(buffer, source.RemainingData()) + throw SerializationException("Not all fields were read. This file might have been written with a newer version " + "of DuckDB and is incompatible with this version of DuckDB."); + } + D_ASSERT(source.RemainingData() == 0); +} + +} // namespace duckdb + + @@ -17428,6 +15232,10 @@ void FileBuffer::Clear() { #define NOMINMAX #endif +#ifndef _WINSOCKAPI_ +#define _WINSOCKAPI_ +#endif + #include #undef CreateDirectory @@ -18315,7 +16123,7 @@ struct RegexpFun { struct SubstringFun { static void RegisterFunction(BuiltinFunctions &set); - static string_t SubstringScalarFunction(Vector &result, string_t input, int32_t offset, int32_t length); + static string_t SubstringScalarFunction(Vector &result, string_t input, int64_t offset, int64_t length); }; struct PrintfFun { @@ -18416,6 +16224,9 @@ extern "C" WINBASEAPI BOOL WINAPI GetPhysicallyInstalledSystemMemory(PULONGLONG) namespace duckdb { +FileSystem::~FileSystem() { +} + FileSystem &FileSystem::GetFileSystem(ClientContext &context) { return *context.db->config.file_system; } @@ -18510,17 +16321,22 @@ string FileSystem::ConvertSeparators(const string &path) { } string FileSystem::ExtractBaseName(const string &path) { + auto normalized_path = ConvertSeparators(path); auto sep = PathSeparator(); - auto vec = StringUtil::Split(StringUtil::Split(path, sep).back(), "."); + auto vec = StringUtil::Split(StringUtil::Split(normalized_path, sep).back(), "."); return vec[0]; } string FileSystem::GetHomeDirectory() { +#ifdef DUCKDB_WINDOWS + const char *homedir = getenv("USERPROFILE"); +#else const char *homedir = getenv("HOME"); - if (!homedir) { - return string(); +#endif + if (homedir) { + return homedir; } - return homedir; + return string(); } // LCOV_EXCL_START @@ -18601,6 +16417,10 @@ void FileSystem::RegisterSubSystem(unique_ptr sub_fs) { throw NotImplementedException("%s: Can't register a sub system on a non-virtual file system", GetName()); } +void FileSystem::RegisterSubSystem(FileCompressionType compression_type, unique_ptr sub_fs) { + throw NotImplementedException("%s: Can't register a sub system on a non-virtual file system", GetName()); +} + bool FileSystem::CanHandleFile(const string &fpath) { throw NotImplementedException("%s: CanHandleFile is not implemented!", GetName()); } @@ -18621,11 +16441,21 @@ bool FileSystem::CanSeek() { throw NotImplementedException("%s: CanSeek is not implemented!", GetName()); } +unique_ptr FileSystem::OpenCompressedFile(unique_ptr handle, bool write) { + throw NotImplementedException("%s: OpenCompressedFile is not implemented!", GetName()); +} + bool FileSystem::OnDiskFile(FileHandle &handle) { throw NotImplementedException("%s: OnDiskFile is not implemented!", GetName()); } // LCOV_EXCL_STOP +FileHandle::FileHandle(FileSystem &file_system, string path_p) : file_system(file_system), path(move(path_p)) { +} + +FileHandle::~FileHandle() { +} + int64_t FileHandle::Read(void *buffer, idx_t nr_bytes) { return file_system.Read(*this, buffer, nr_bytes); } @@ -18707,26 +16537,41 @@ FileType FileHandle::GetType() { namespace duckdb { -class GZipFileSystem : public FileSystem { -public: - static unique_ptr OpenCompressedFile(unique_ptr handle); - - int64_t Read(FileHandle &handle, void *buffer, int64_t nr_bytes) override; - - void Reset(FileHandle &handle) override; - - int64_t GetFileSize(FileHandle &handle) override; +class GZipFileSystem : public CompressedFileSystem { + // 32 KB + static constexpr const idx_t BUFFER_SIZE = 1 << 15; - bool OnDiskFile(FileHandle &handle) override; - bool CanSeek() override { - return false; - } +public: + unique_ptr OpenCompressedFile(unique_ptr handle, bool write) override; std::string GetName() const override { return "GZipFileSystem"; } + + //! Verifies that a buffer contains a valid GZIP header + static void VerifyGZIPHeader(uint8_t gzip_hdr[], idx_t read_count); + //! Consumes a byte stream as a gzip string, returning the decompressed string + static string UncompressGZIPString(const string &in); + + unique_ptr CreateStream() override; + idx_t InBufferSize() override; + idx_t OutBufferSize() override; }; +static constexpr const uint8_t GZIP_COMPRESSION_DEFLATE = 0x08; + +static constexpr const uint8_t GZIP_FLAG_ASCII = 0x1; +static constexpr const uint8_t GZIP_FLAG_MULTIPART = 0x2; +static constexpr const uint8_t GZIP_FLAG_EXTRA = 0x4; +static constexpr const uint8_t GZIP_FLAG_NAME = 0x8; +static constexpr const uint8_t GZIP_FLAG_COMMENT = 0x10; +static constexpr const uint8_t GZIP_FLAG_ENCRYPT = 0x20; + +static constexpr const uint8_t GZIP_HEADER_MINSIZE = 10; + +static constexpr const unsigned char GZIP_FLAG_UNSUPPORTED = + GZIP_FLAG_ASCII | GZIP_FLAG_MULTIPART | GZIP_FLAG_EXTRA | GZIP_FLAG_COMMENT | GZIP_FLAG_ENCRYPT; + } // namespace duckdb @@ -20032,6 +17877,155 @@ void *mz_zip_extract_archive_file_to_heap_v2(const char *pZip_filename, const ch +// LICENSE_CHANGE_BEGIN +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #3 +// See the end of this file for a list + +//===----------------------------------------------------------------------===// +// DuckDB +// +// miniz_wrapper.hpp +// +// +//===----------------------------------------------------------------------===// + + + + +#include +#include + +namespace duckdb { + +enum class MiniZStreamType { + MINIZ_TYPE_NONE, + MINIZ_TYPE_INFLATE, + MINIZ_TYPE_DEFLATE +}; + +struct MiniZStream { + static constexpr uint8_t GZIP_HEADER_MINSIZE = 10; + static constexpr uint8_t GZIP_FOOTER_SIZE = 8; + static constexpr uint8_t GZIP_COMPRESSION_DEFLATE = 0x08; + static constexpr unsigned char GZIP_FLAG_UNSUPPORTED = 0x1 | 0x2 | 0x4 | 0x10 | 0x20; + +public: + MiniZStream() : type(MiniZStreamType::MINIZ_TYPE_NONE) { + memset(&stream, 0, sizeof(duckdb_miniz::mz_stream)); + } + ~MiniZStream() { + switch(type) { + case MiniZStreamType::MINIZ_TYPE_INFLATE: + duckdb_miniz::mz_inflateEnd(&stream); + break; + case MiniZStreamType::MINIZ_TYPE_DEFLATE: + duckdb_miniz::mz_deflateEnd(&stream); + break; + default: + break; + } + } + void FormatException(std::string error_msg) { + throw std::runtime_error(error_msg); + } + void FormatException(const char *error_msg, int mz_ret) { + auto err = duckdb_miniz::mz_error(mz_ret); + FormatException(error_msg + std::string(": ") + (err ? err : "Unknown error code")); + } + void Decompress(const char *compressed_data, size_t compressed_size, char *out_data, size_t out_size) { + auto mz_ret = mz_inflateInit2(&stream, -MZ_DEFAULT_WINDOW_BITS); + if (mz_ret != duckdb_miniz::MZ_OK) { + FormatException("Failed to initialize miniz", mz_ret); + } + type = MiniZStreamType::MINIZ_TYPE_INFLATE; + + if (compressed_size < GZIP_HEADER_MINSIZE) { + FormatException("Failed to decompress GZIP block: compressed size is less than gzip header size"); + } + auto gzip_hdr = (const unsigned char *)compressed_data; + if (gzip_hdr[0] != 0x1F || gzip_hdr[1] != 0x8B || gzip_hdr[2] != GZIP_COMPRESSION_DEFLATE || + gzip_hdr[3] & GZIP_FLAG_UNSUPPORTED) { + FormatException("Input is invalid/unsupported GZIP stream"); + } + + stream.next_in = (const unsigned char *)compressed_data + GZIP_HEADER_MINSIZE; + stream.avail_in = compressed_size - GZIP_HEADER_MINSIZE; + stream.next_out = (unsigned char *)out_data; + stream.avail_out = out_size; + + mz_ret = mz_inflate(&stream, duckdb_miniz::MZ_FINISH); + if (mz_ret != duckdb_miniz::MZ_OK && mz_ret != duckdb_miniz::MZ_STREAM_END) { + FormatException("Failed to decompress GZIP block", mz_ret); + } + } + size_t MaxCompressedLength(size_t input_size) { + return duckdb_miniz::mz_compressBound(input_size) + GZIP_HEADER_MINSIZE + GZIP_FOOTER_SIZE; + } + static void InitializeGZIPHeader(unsigned char *gzip_header) { + memset(gzip_header, 0, GZIP_HEADER_MINSIZE); + gzip_header[0] = 0x1F; + gzip_header[1] = 0x8B; + gzip_header[2] = GZIP_COMPRESSION_DEFLATE; + gzip_header[3] = 0; + gzip_header[4] = 0; + gzip_header[5] = 0; + gzip_header[6] = 0; + gzip_header[7] = 0; + gzip_header[8] = 0; + gzip_header[9] = 0xFF; + } + + static void InitializeGZIPFooter(unsigned char *gzip_footer, duckdb_miniz::mz_ulong crc, idx_t uncompressed_size) { + gzip_footer[0] = crc & 0xFF; + gzip_footer[1] = (crc >> 8) & 0xFF; + gzip_footer[2] = (crc >> 16) & 0xFF; + gzip_footer[3] = (crc >> 24) & 0xFF; + gzip_footer[4] = uncompressed_size & 0xFF; + gzip_footer[5] = (uncompressed_size >> 8) & 0xFF; + gzip_footer[6] = (uncompressed_size >> 16) & 0xFF; + gzip_footer[7] = (uncompressed_size >> 24) & 0xFF; + } + + void Compress(const char *uncompressed_data, size_t uncompressed_size, char *out_data, size_t *out_size) { + auto mz_ret = mz_deflateInit2(&stream, duckdb_miniz::MZ_DEFAULT_LEVEL, MZ_DEFLATED, -MZ_DEFAULT_WINDOW_BITS, 1, 0); + if (mz_ret != duckdb_miniz::MZ_OK) { + FormatException("Failed to initialize miniz", mz_ret); + } + type = MiniZStreamType::MINIZ_TYPE_DEFLATE; + + auto gzip_header = (unsigned char*) out_data; + InitializeGZIPHeader(gzip_header); + + auto gzip_body = gzip_header + GZIP_HEADER_MINSIZE; + + stream.next_in = (const unsigned char*) uncompressed_data; + stream.avail_in = uncompressed_size; + stream.next_out = gzip_body; + stream.avail_out = *out_size - GZIP_HEADER_MINSIZE; + + mz_ret = mz_deflate(&stream, duckdb_miniz::MZ_FINISH); + if (mz_ret != duckdb_miniz::MZ_OK && mz_ret != duckdb_miniz::MZ_STREAM_END) { + FormatException("Failed to compress GZIP block", mz_ret); + } + auto gzip_footer = gzip_body + stream.total_out; + auto crc = duckdb_miniz::mz_crc32(MZ_CRC32_INIT, (const unsigned char*) uncompressed_data, uncompressed_size); + InitializeGZIPFooter(gzip_footer, crc, uncompressed_size); + + *out_size = stream.total_out + GZIP_HEADER_MINSIZE + GZIP_FOOTER_SIZE; + } + +private: + duckdb_miniz::mz_stream stream; + MiniZStreamType type; +}; + +} + + +// LICENSE_CHANGE_END + + + namespace duckdb { @@ -20090,219 +18084,275 @@ static idx_t GZipConsumeString(FileHandle &input) { return size; } -static constexpr const uint8_t GZIP_COMPRESSION_DEFLATE = 0x08; +struct MiniZStreamWrapper : public StreamWrapper { + ~MiniZStreamWrapper() override; -static constexpr const uint8_t GZIP_FLAG_ASCII = 0x1; -static constexpr const uint8_t GZIP_FLAG_MULTIPART = 0x2; -static constexpr const uint8_t GZIP_FLAG_EXTRA = 0x4; -static constexpr const uint8_t GZIP_FLAG_NAME = 0x8; -static constexpr const uint8_t GZIP_FLAG_COMMENT = 0x10; -static constexpr const uint8_t GZIP_FLAG_ENCRYPT = 0x20; + CompressedFile *file = nullptr; + duckdb_miniz::mz_stream *mz_stream_ptr = nullptr; + bool writing = false; + duckdb_miniz::mz_ulong crc; + idx_t total_size; -static constexpr const uint8_t GZIP_HEADER_MINSIZE = 10; +public: + void Initialize(CompressedFile &file, bool write) override; -static constexpr const unsigned char GZIP_FLAG_UNSUPPORTED = - GZIP_FLAG_ASCII | GZIP_FLAG_MULTIPART | GZIP_FLAG_EXTRA | GZIP_FLAG_COMMENT | GZIP_FLAG_ENCRYPT; + bool Read(StreamData &stream_data) override; + void Write(CompressedFile &file, StreamData &stream_data, data_ptr_t buffer, int64_t nr_bytes) override; -struct MiniZStreamWrapper { - ~MiniZStreamWrapper() { - Close(); - } + void Close() override; - duckdb_miniz::mz_stream *mz_stream_ptr = nullptr; + void FlushStream(); +}; -public: - void Initialize() { +MiniZStreamWrapper::~MiniZStreamWrapper() { + // avoid closing if destroyed during stack unwinding + if (Exception::UncaughtException()) { + return; + } + try { Close(); - mz_stream_ptr = new duckdb_miniz::mz_stream(); - memset(mz_stream_ptr, 0, sizeof(duckdb_miniz::mz_stream)); + } catch (...) { } +} - void Close() { - if (!mz_stream_ptr) { - return; - } - duckdb_miniz::mz_inflateEnd(mz_stream_ptr); - delete mz_stream_ptr; - mz_stream_ptr = nullptr; - } -}; +void MiniZStreamWrapper::Initialize(CompressedFile &file, bool write) { + Close(); + this->file = &file; + mz_stream_ptr = new duckdb_miniz::mz_stream(); + memset(mz_stream_ptr, 0, sizeof(duckdb_miniz::mz_stream)); + this->writing = write; -class GZipFile : public FileHandle { - static constexpr const idx_t BUFFER_SIZE = 1024; + // TODO use custom alloc/free methods in miniz to throw exceptions on OOM + uint8_t gzip_hdr[GZIP_HEADER_MINSIZE]; + if (write) { + crc = MZ_CRC32_INIT; + total_size = 0; -public: - GZipFile(unique_ptr child_handle_p, const string &path) - : FileHandle(gzip_fs, path), child_handle(move(child_handle_p)) { - Initialize(); - } - ~GZipFile() override { + MiniZStream::InitializeGZIPHeader(gzip_hdr); + file.child_handle->Write(gzip_hdr, GZIP_HEADER_MINSIZE); + + auto ret = mz_deflateInit2((duckdb_miniz::mz_streamp)mz_stream_ptr, duckdb_miniz::MZ_DEFAULT_LEVEL, MZ_DEFLATED, + -MZ_DEFAULT_WINDOW_BITS, 1, 0); + if (ret != duckdb_miniz::MZ_OK) { + throw InternalException("Failed to initialize miniz"); + } + } else { + idx_t data_start = GZIP_HEADER_MINSIZE; + auto read_count = file.child_handle->Read(gzip_hdr, GZIP_HEADER_MINSIZE); + GZipFileSystem::VerifyGZIPHeader(gzip_hdr, read_count); + + if (gzip_hdr[3] & GZIP_FLAG_NAME) { + file.child_handle->Seek(data_start); + data_start += GZipConsumeString(*file.child_handle); + } + file.child_handle->Seek(data_start); + // stream is now set to beginning of payload data + auto ret = duckdb_miniz::mz_inflateInit2((duckdb_miniz::mz_streamp)mz_stream_ptr, -MZ_DEFAULT_WINDOW_BITS); + if (ret != duckdb_miniz::MZ_OK) { + throw InternalException("Failed to initialize miniz"); + } + } +} + +bool MiniZStreamWrapper::Read(StreamData &sd) { + // actually decompress + mz_stream_ptr->next_in = (data_ptr_t)sd.in_buff_start; + D_ASSERT(sd.in_buff_end - sd.in_buff_start < NumericLimits::Maximum()); + mz_stream_ptr->avail_in = (uint32_t)(sd.in_buff_end - sd.in_buff_start); + mz_stream_ptr->next_out = (data_ptr_t)sd.out_buff_end; + mz_stream_ptr->avail_out = (uint32_t)((sd.out_buff.get() + sd.out_buf_size) - sd.out_buff_end); + auto ret = duckdb_miniz::mz_inflate(mz_stream_ptr, duckdb_miniz::MZ_NO_FLUSH); + if (ret != duckdb_miniz::MZ_OK && ret != duckdb_miniz::MZ_STREAM_END) { + throw IOException("Failed to decode gzip stream: %s", duckdb_miniz::mz_error(ret)); + } + // update pointers following inflate() + sd.in_buff_start = (data_ptr_t)mz_stream_ptr->next_in; + sd.in_buff_end = sd.in_buff_start + mz_stream_ptr->avail_in; + sd.out_buff_end = (data_ptr_t)mz_stream_ptr->next_out; + D_ASSERT(sd.out_buff_end + mz_stream_ptr->avail_out == sd.out_buff.get() + sd.out_buf_size); + // if stream ended, deallocate inflator + if (ret == duckdb_miniz::MZ_STREAM_END) { Close(); + return true; } + return false; +} - void Initialize(); - int64_t ReadData(void *buffer, int64_t nr_bytes); +void MiniZStreamWrapper::Write(CompressedFile &file, StreamData &sd, data_ptr_t uncompressed_data, + int64_t uncompressed_size) { + // update the src and the total size + crc = duckdb_miniz::mz_crc32(crc, (const unsigned char *)uncompressed_data, uncompressed_size); + total_size += uncompressed_size; - GZipFileSystem gzip_fs; - unique_ptr child_handle; + auto remaining = uncompressed_size; + while (remaining > 0) { + idx_t output_remaining = (sd.out_buff.get() + sd.out_buf_size) - sd.out_buff_start; -protected: - void Close() override { - miniz_stream.reset(); - in_buff.reset(); - out_buff.reset(); + mz_stream_ptr->next_in = (const unsigned char *)uncompressed_data; + mz_stream_ptr->avail_in = remaining; + mz_stream_ptr->next_out = sd.out_buff_start; + mz_stream_ptr->avail_out = output_remaining; + + auto res = mz_deflate(mz_stream_ptr, duckdb_miniz::MZ_NO_FLUSH); + if (res != duckdb_miniz::MZ_OK) { + D_ASSERT(res != duckdb_miniz::MZ_STREAM_END); + throw InternalException("Failed to compress GZIP block"); + } + sd.out_buff_start += output_remaining - mz_stream_ptr->avail_out; + if (mz_stream_ptr->avail_out == 0) { + // no more output buffer available: flush + file.child_handle->Write(sd.out_buff.get(), sd.out_buff_start - sd.out_buff.get()); + sd.out_buff_start = sd.out_buff.get(); + } + idx_t written = remaining - mz_stream_ptr->avail_in; + uncompressed_data += written; + remaining = mz_stream_ptr->avail_in; } +} -private: - idx_t data_start = 0; - unique_ptr miniz_stream; - // various buffers & pointers - unique_ptr in_buff; - unique_ptr out_buff; - data_ptr_t out_buff_start = nullptr; - data_ptr_t out_buff_end = nullptr; - data_ptr_t in_buff_start = nullptr; - data_ptr_t in_buff_end = nullptr; -}; +void MiniZStreamWrapper::FlushStream() { + auto &sd = file->stream_data; + mz_stream_ptr->next_in = nullptr; + mz_stream_ptr->avail_in = 0; + while (true) { + auto output_remaining = (sd.out_buff.get() + sd.out_buf_size) - sd.out_buff_start; + mz_stream_ptr->next_out = sd.out_buff_start; + mz_stream_ptr->avail_out = output_remaining; -void GZipFile::Initialize() { - Close(); + auto res = mz_deflate(mz_stream_ptr, duckdb_miniz::MZ_FINISH); + sd.out_buff_start += (output_remaining - mz_stream_ptr->avail_out); + if (sd.out_buff_start > sd.out_buff.get()) { + file->child_handle->Write(sd.out_buff.get(), sd.out_buff_start - sd.out_buff.get()); + sd.out_buff_start = sd.out_buff.get(); + } + if (res == duckdb_miniz::MZ_STREAM_END) { + break; + } + if (res != duckdb_miniz::MZ_OK) { + throw InternalException("Failed to compress GZIP block"); + } + } +} - D_ASSERT(BUFFER_SIZE >= 3); // found to work fine with 3 - uint8_t gzip_hdr[10]; - data_start = GZIP_HEADER_MINSIZE; +void MiniZStreamWrapper::Close() { + if (!mz_stream_ptr) { + return; + } + if (writing) { + // flush anything remaining in the stream + FlushStream(); - in_buff = unique_ptr(new data_t[BUFFER_SIZE]); - in_buff_start = in_buff.get(); - in_buff_end = in_buff.get(); - out_buff = unique_ptr(new data_t[BUFFER_SIZE]); - out_buff_start = out_buff.get(); - out_buff_end = out_buff.get(); + // write the footer + unsigned char gzip_footer[MiniZStream::GZIP_FOOTER_SIZE]; + MiniZStream::InitializeGZIPFooter(gzip_footer, crc, total_size); + file->child_handle->Write(gzip_footer, MiniZStream::GZIP_FOOTER_SIZE); - miniz_stream = make_unique(); - miniz_stream->Initialize(); + duckdb_miniz::mz_deflateEnd(mz_stream_ptr); + } else { + duckdb_miniz::mz_inflateEnd(mz_stream_ptr); + } + delete mz_stream_ptr; + mz_stream_ptr = nullptr; + file = nullptr; +} - auto &mz_stream_ptr = miniz_stream->mz_stream_ptr; +class GZipFile : public CompressedFile { +public: + GZipFile(unique_ptr child_handle_p, const string &path, bool write) + : CompressedFile(gzip_fs, move(child_handle_p), path) { + Initialize(write); + } - // TODO use custom alloc/free methods in miniz to throw exceptions on OOM - auto read_count = child_handle->Read(gzip_hdr, GZIP_HEADER_MINSIZE); + GZipFileSystem gzip_fs; +}; +void GZipFileSystem::VerifyGZIPHeader(uint8_t gzip_hdr[], idx_t read_count) { // check for incorrectly formatted files - // LCOV_EXCL_START if (read_count != GZIP_HEADER_MINSIZE) { - throw Exception("Input is not a GZIP stream"); + throw IOException("Input is not a GZIP stream"); } if (gzip_hdr[0] != 0x1F || gzip_hdr[1] != 0x8B) { // magic header - throw Exception("Input is not a GZIP stream"); + throw IOException("Input is not a GZIP stream"); } if (gzip_hdr[2] != GZIP_COMPRESSION_DEFLATE) { // compression method - throw Exception("Unsupported GZIP compression method"); + throw IOException("Unsupported GZIP compression method"); } if (gzip_hdr[3] & GZIP_FLAG_UNSUPPORTED) { - throw Exception("Unsupported GZIP archive"); + throw IOException("Unsupported GZIP archive"); } - // LCOV_EXCL_STOP +} + +string GZipFileSystem::UncompressGZIPString(const string &in) { + // decompress file + auto body_ptr = in.data(); + + auto mz_stream_ptr = new duckdb_miniz::mz_stream(); + memset(mz_stream_ptr, 0, sizeof(duckdb_miniz::mz_stream)); + + uint8_t gzip_hdr[GZIP_HEADER_MINSIZE]; + + // check for incorrectly formatted files + + // TODO this is mostly the same as gzip_file_system.cpp + if (in.size() < GZIP_HEADER_MINSIZE) { + throw IOException("Input is not a GZIP stream"); + } + memcpy(gzip_hdr, body_ptr, GZIP_HEADER_MINSIZE); + body_ptr += GZIP_HEADER_MINSIZE; + GZipFileSystem::VerifyGZIPHeader(gzip_hdr, GZIP_HEADER_MINSIZE); if (gzip_hdr[3] & GZIP_FLAG_NAME) { - child_handle->Seek(data_start); - data_start += GZipConsumeString(*child_handle); + char c; + do { + c = *body_ptr; + body_ptr++; + } while (c != '\0' && (idx_t)(body_ptr - in.data()) < in.size()); } - child_handle->Seek(data_start); + // stream is now set to beginning of payload data - auto ret = duckdb_miniz::mz_inflateInit2((duckdb_miniz::mz_streamp)mz_stream_ptr, -MZ_DEFAULT_WINDOW_BITS); - if (ret != duckdb_miniz::MZ_OK) { + auto status = duckdb_miniz::mz_inflateInit2(mz_stream_ptr, -MZ_DEFAULT_WINDOW_BITS); + if (status != duckdb_miniz::MZ_OK) { throw InternalException("Failed to initialize miniz"); } -} - -unique_ptr GZipFileSystem::OpenCompressedFile(unique_ptr handle) { - auto path = handle->path; - return make_unique(move(handle), path); -} - -int64_t GZipFile::ReadData(void *buffer, int64_t remaining) { - auto &mz_stream_ptr = miniz_stream->mz_stream_ptr; - idx_t total_read = 0; - while (true) { - // first check if there are input bytes available in the output buffers - if (out_buff_start != out_buff_end) { - // there is! copy it into the output buffer - idx_t available = MinValue(remaining, out_buff_end - out_buff_start); - memcpy(data_ptr_t(buffer) + total_read, out_buff_start, available); - - // increment the total read variables as required - out_buff_start += available; - total_read += available; - remaining -= available; - if (remaining == 0) { - // done! read enough - return total_read; - } - } - if (!mz_stream_ptr) { - return total_read; - } - // ran out of buffer: read more data from the child stream - out_buff_start = out_buff.get(); - out_buff_end = out_buff.get(); - D_ASSERT(in_buff_start <= in_buff_end); - D_ASSERT(in_buff_end <= in_buff_start + GZipFile::BUFFER_SIZE); + auto bytes_remaining = in.size() - (body_ptr - in.data()); + mz_stream_ptr->next_in = (unsigned char *)body_ptr; + mz_stream_ptr->avail_in = bytes_remaining; - // read more input if none available - if (in_buff_start == in_buff_end) { - // empty input buffer: refill from the start - in_buff_start = in_buff.get(); - auto sz = child_handle->Read(in_buff.get(), BUFFER_SIZE); - if (sz <= 0) { - break; - } - in_buff_end = in_buff_start + sz; - } + unsigned char decompress_buffer[BUFSIZ]; + string decompressed; - // actually decompress - mz_stream_ptr->next_in = (data_ptr_t)in_buff_start; - D_ASSERT(in_buff_end - in_buff_start < NumericLimits::Maximum()); - mz_stream_ptr->avail_in = (uint32_t)(in_buff_end - in_buff_start); - mz_stream_ptr->next_out = (data_ptr_t)out_buff_end; - D_ASSERT((out_buff.get() + BUFFER_SIZE) - out_buff_end < NumericLimits::Maximum()); - mz_stream_ptr->avail_out = (uint32_t)((out_buff.get() + BUFFER_SIZE) - out_buff_end); - auto ret = duckdb_miniz::mz_inflate(mz_stream_ptr, duckdb_miniz::MZ_NO_FLUSH); - if (ret != duckdb_miniz::MZ_OK && ret != duckdb_miniz::MZ_STREAM_END) { - throw Exception(duckdb_miniz::mz_error(ret)); - } - // update pointers following inflate() - in_buff_start = (data_ptr_t)mz_stream_ptr->next_in; - in_buff_end = in_buff_start + mz_stream_ptr->avail_in; - out_buff_end = (data_ptr_t)mz_stream_ptr->next_out; - D_ASSERT(out_buff_end + mz_stream_ptr->avail_out == out_buff.get() + BUFFER_SIZE); - // if stream ended, deallocate inflator - if (ret == duckdb_miniz::MZ_STREAM_END) { - miniz_stream->Close(); + while (status == duckdb_miniz::MZ_OK) { + mz_stream_ptr->next_out = decompress_buffer; + mz_stream_ptr->avail_out = sizeof(decompress_buffer); + status = mz_inflate(mz_stream_ptr, duckdb_miniz::MZ_NO_FLUSH); + if (status != duckdb_miniz::MZ_STREAM_END && status != duckdb_miniz::MZ_OK) { + throw IOException("Failed to uncompress"); } + decompressed.append((char *)decompress_buffer, mz_stream_ptr->total_out - decompressed.size()); } - return total_read; + duckdb_miniz::mz_inflateEnd(mz_stream_ptr); + if (decompressed.empty()) { + throw IOException("Failed to uncompress"); + } + return decompressed; } -int64_t GZipFileSystem::Read(FileHandle &handle, void *buffer, int64_t nr_bytes) { - auto &gzip_file = (GZipFile &)handle; - return gzip_file.ReadData(buffer, nr_bytes); +unique_ptr GZipFileSystem::OpenCompressedFile(unique_ptr handle, bool write) { + auto path = handle->path; + return make_unique(move(handle), path, write); } -void GZipFileSystem::Reset(FileHandle &handle) { - auto &gzip_file = (GZipFile &)handle; - gzip_file.child_handle->Reset(); - gzip_file.Initialize(); +unique_ptr GZipFileSystem::CreateStream() { + return make_unique(); } -int64_t GZipFileSystem::GetFileSize(FileHandle &handle) { - auto &gzip_file = (GZipFile &)handle; - return gzip_file.child_handle->GetFileSize(); +idx_t GZipFileSystem::InBufferSize() { + return BUFFER_SIZE; } -bool GZipFileSystem::OnDiskFile(FileHandle &handle) { - auto &gzip_file = (GZipFile &)handle; - return gzip_file.child_handle->OnDiskFile(); +idx_t GZipFileSystem::OutBufferSize() { + return BUFFER_SIZE; } } // namespace duckdb @@ -20337,6 +18387,18 @@ bool GZipFileSystem::OnDiskFile(FileHandle &handle) { #undef small #endif +#ifdef CreateDirectory +#undef CreateDirectory +#endif + +#ifdef MoveFile +#undef MoveFile +#endif + +#ifdef RemoveDirectory +#undef RemoveDirectory +#endif + #endif #include @@ -20552,6 +18614,36 @@ class LocalFileSystem : public FileSystem { #include #include #else +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/windows_util.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + + + +namespace duckdb { + +#ifdef DUCKDB_WINDOWS +class WindowsUtil { +public: + //! Windows helper functions + static std::wstring UTF8ToUnicode(const char *input); + static string UnicodeToUTF8(LPCWSTR input); + static string UTF8ToMBCS(const char *input, bool use_ansi = false); +}; +#endif + +} // namespace duckdb + #include #ifdef __MINGW32__ @@ -20598,15 +18690,14 @@ struct UnixFileHandle : public FileHandle { Close(); } -protected: + int fd; + +public: void Close() override { if (fd != -1) { close(fd); } }; - -public: - int fd; }; static FileType GetFileTypeInternal(int fd) { // LCOV_EXCL_START @@ -20974,14 +19065,13 @@ struct WindowsFileHandle : public FileHandle { Close(); } -protected: + idx_t position; + HANDLE fd; + +public: void Close() override { CloseHandle(fd); }; - -public: - idx_t position; - HANDLE fd; }; unique_ptr LocalFileSystem::OpenFile(const string &path, uint8_t flags, FileLockType lock_type, @@ -20994,7 +19084,7 @@ unique_ptr LocalFileSystem::OpenFile(const string &path, uint8_t fla DWORD desired_access; DWORD share_mode; DWORD creation_disposition = OPEN_EXISTING; - DWORD flags_and_attributes = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED; + DWORD flags_and_attributes = FILE_ATTRIBUTE_NORMAL; bool open_read = flags & FileFlags::FILE_FLAGS_READ; bool open_write = flags & FileFlags::FILE_FLAGS_WRITE; if (open_read && open_write) { @@ -21015,15 +19105,13 @@ unique_ptr LocalFileSystem::OpenFile(const string &path, uint8_t fla } else if (flags & FileFlags::FILE_FLAGS_FILE_CREATE_NEW) { creation_disposition = CREATE_ALWAYS; } - if (flags & FileFlags::FILE_FLAGS_DIRECT_IO) { - flags_and_attributes |= FILE_FLAG_WRITE_THROUGH; - } } if (flags & FileFlags::FILE_FLAGS_DIRECT_IO) { flags_and_attributes |= FILE_FLAG_NO_BUFFERING; } - HANDLE hFile = - CreateFileA(path.c_str(), desired_access, share_mode, NULL, creation_disposition, flags_and_attributes, NULL); + auto unicode_path = WindowsUtil::UTF8ToUnicode(path.c_str()); + HANDLE hFile = CreateFileW(unicode_path.c_str(), desired_access, share_mode, NULL, creation_disposition, + flags_and_attributes, NULL); if (hFile == INVALID_HANDLE_VALUE) { auto error = GetLastErrorAsString(); throw IOException("Cannot open file \"%s\": %s", path.c_str(), error); @@ -21044,21 +19132,25 @@ idx_t LocalFileSystem::GetFilePointer(FileHandle &handle) { return ((WindowsFileHandle &)handle).position; } -void LocalFileSystem::Read(FileHandle &handle, void *buffer, int64_t nr_bytes, idx_t location) { - HANDLE hFile = ((WindowsFileHandle &)handle).fd; - DWORD bytes_read; +static DWORD FSInternalRead(FileHandle &handle, HANDLE hFile, void *buffer, int64_t nr_bytes, idx_t location) { + DWORD bytes_read = 0; OVERLAPPED ov = {}; ov.Internal = 0; ov.InternalHigh = 0; ov.Offset = location & 0xFFFFFFFF; ov.OffsetHigh = location >> 32; ov.hEvent = 0; - ReadFile(hFile, buffer, (DWORD)nr_bytes, NULL, &ov); - auto rc = GetOverlappedResult(hFile, &ov, &bytes_read, true); - if (rc == 0) { + auto rc = ReadFile(hFile, buffer, (DWORD)nr_bytes, &bytes_read, &ov); + if (!rc) { auto error = GetLastErrorAsString(); - throw IOException("Could not read file \"%s\": %s", handle.path, error); + throw IOException("Could not read file \"%s\" (error in ReadFile): %s", handle.path, error); } + return bytes_read; +} + +void LocalFileSystem::Read(FileHandle &handle, void *buffer, int64_t nr_bytes, idx_t location) { + HANDLE hFile = ((WindowsFileHandle &)handle).fd; + auto bytes_read = FSInternalRead(handle, hFile, buffer, nr_bytes, location); if (bytes_read != nr_bytes) { throw IOException("Could not read all bytes from file \"%s\": wanted=%lld read=%lld", handle.path, nr_bytes, bytes_read); @@ -21067,40 +19159,32 @@ void LocalFileSystem::Read(FileHandle &handle, void *buffer, int64_t nr_bytes, i int64_t LocalFileSystem::Read(FileHandle &handle, void *buffer, int64_t nr_bytes) { HANDLE hFile = ((WindowsFileHandle &)handle).fd; - DWORD bytes_read; auto &pos = ((WindowsFileHandle &)handle).position; - OVERLAPPED ov = {}; - ov.Internal = 0; - ov.InternalHigh = 0; - ov.Offset = pos & 0xFFFFFFFF; - ov.OffsetHigh = pos >> 32; - ov.hEvent = 0; auto n = std::min(std::max(GetFileSize(handle), pos) - pos, nr_bytes); - ReadFile(hFile, buffer, (DWORD)n, NULL, &ov); - auto rc = GetOverlappedResult(hFile, &ov, &bytes_read, true); - if (rc == 0) { - auto error = GetLastErrorAsString(); - throw IOException("Could not read file \"%s\": %s", handle.path, error); - } + auto bytes_read = FSInternalRead(handle, hFile, buffer, n, pos); pos += bytes_read; return bytes_read; } -void LocalFileSystem::Write(FileHandle &handle, void *buffer, int64_t nr_bytes, idx_t location) { - HANDLE hFile = ((WindowsFileHandle &)handle).fd; - DWORD bytes_written; +static DWORD FSInternalWrite(FileHandle &handle, HANDLE hFile, void *buffer, int64_t nr_bytes, idx_t location) { + DWORD bytes_written = 0; OVERLAPPED ov = {}; ov.Internal = 0; ov.InternalHigh = 0; ov.Offset = location & 0xFFFFFFFF; ov.OffsetHigh = location >> 32; ov.hEvent = 0; - WriteFile(hFile, buffer, (DWORD)nr_bytes, NULL, &ov); - auto rc = GetOverlappedResult(hFile, &ov, &bytes_written, true); - if (rc == 0) { + auto rc = WriteFile(hFile, buffer, (DWORD)nr_bytes, &bytes_written, &ov); + if (!rc) { auto error = GetLastErrorAsString(); - throw IOException("Could not write file \"%s\": %s", handle.path, error); + throw IOException("Could not write file \"%s\" (error in WriteFile): %s", handle.path, error); } + return bytes_written; +} + +void LocalFileSystem::Write(FileHandle &handle, void *buffer, int64_t nr_bytes, idx_t location) { + HANDLE hFile = ((WindowsFileHandle &)handle).fd; + auto bytes_written = FSInternalWrite(handle, hFile, buffer, nr_bytes, location); if (bytes_written != nr_bytes) { throw IOException("Could not write all bytes from file \"%s\": wanted=%lld wrote=%lld", handle.path, nr_bytes, bytes_written); @@ -21109,20 +19193,8 @@ void LocalFileSystem::Write(FileHandle &handle, void *buffer, int64_t nr_bytes, int64_t LocalFileSystem::Write(FileHandle &handle, void *buffer, int64_t nr_bytes) { HANDLE hFile = ((WindowsFileHandle &)handle).fd; - DWORD bytes_written; auto &pos = ((WindowsFileHandle &)handle).position; - OVERLAPPED ov = {}; - ov.Internal = 0; - ov.InternalHigh = 0; - ov.Offset = pos & 0xFFFFFFFF; - ov.OffsetHigh = pos >> 32; - ov.hEvent = 0; - WriteFile(hFile, buffer, (DWORD)nr_bytes, NULL, &ov); - auto rc = GetOverlappedResult(hFile, &ov, &bytes_written, true); - if (rc == 0) { - auto error = GetLastErrorAsString(); - throw IOException("Could not write file \"%s\": %s", handle.path, error); - } + auto bytes_written = FSInternalWrite(handle, hFile, buffer, nr_bytes, pos); pos += bytes_written; return bytes_written; } @@ -21173,13 +19245,18 @@ void LocalFileSystem::Truncate(FileHandle &handle, int64_t new_size) { } } +static DWORD WindowsGetFileAttributes(const string &filename) { + auto unicode_path = WindowsUtil::UTF8ToUnicode(filename.c_str()); + return GetFileAttributesW(unicode_path.c_str()); +} + bool LocalFileSystem::DirectoryExists(const string &directory) { - DWORD attrs = GetFileAttributesA(directory.c_str()); + DWORD attrs = WindowsGetFileAttributes(directory); return (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY)); } bool LocalFileSystem::FileExists(const string &filename) { - DWORD attrs = GetFileAttributesA(filename.c_str()); + DWORD attrs = WindowsGetFileAttributes(filename); return (attrs != INVALID_FILE_ATTRIBUTES && !(attrs & FILE_ATTRIBUTE_DIRECTORY)); } @@ -21187,79 +19264,58 @@ void LocalFileSystem::CreateDirectory(const string &directory) { if (DirectoryExists(directory)) { return; } - if (directory.empty() || !CreateDirectoryA(directory.c_str(), NULL) || !DirectoryExists(directory)) { + auto unicode_path = WindowsUtil::UTF8ToUnicode(directory.c_str()); + if (directory.empty() || !CreateDirectoryW(unicode_path.c_str(), NULL) || !DirectoryExists(directory)) { throw IOException("Could not create directory!"); } } -static void delete_dir_special_snowflake_windows(FileSystem &fs, string directory) { - if (directory.size() + 3 > MAX_PATH) { - throw IOException("Pathname too long"); - } - // create search pattern - TCHAR szDir[MAX_PATH]; - snprintf(szDir, MAX_PATH, "%s\\*", directory.c_str()); - - WIN32_FIND_DATA ffd; - HANDLE hFind = FindFirstFile(szDir, &ffd); - if (hFind == INVALID_HANDLE_VALUE) { - return; - } - - do { - if (string(ffd.cFileName) == "." || string(ffd.cFileName) == "..") { - continue; - } - if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - // recurse to zap directory contents - delete_dir_special_snowflake_windows(fs, fs.JoinPath(directory, ffd.cFileName)); +static void DeleteDirectoryRecursive(FileSystem &fs, string directory) { + fs.ListFiles(directory, [&](const string &fname, bool is_directory) { + if (is_directory) { + DeleteDirectoryRecursive(fs, fs.JoinPath(directory, fname)); } else { - if (strlen(ffd.cFileName) + directory.size() + 1 > MAX_PATH) { - throw IOException("Pathname too long"); - } - // create search pattern - TCHAR del_path[MAX_PATH]; - snprintf(del_path, MAX_PATH, "%s\\%s", directory.c_str(), ffd.cFileName); - if (!DeleteFileA(del_path)) { - throw IOException("Failed to delete directory entry"); - } + fs.RemoveFile(fs.JoinPath(directory, fname)); } - } while (FindNextFile(hFind, &ffd) != 0); - - DWORD dwError = GetLastError(); - if (dwError != ERROR_NO_MORE_FILES) { - throw IOException("Something went wrong"); - } - FindClose(hFind); - - if (!RemoveDirectoryA(directory.c_str())) { + }); + auto unicode_path = WindowsUtil::UTF8ToUnicode(directory.c_str()); + if (!RemoveDirectoryW(unicode_path.c_str())) { throw IOException("Failed to delete directory"); } } void LocalFileSystem::RemoveDirectory(const string &directory) { - delete_dir_special_snowflake_windows(*this, directory.c_str()); + if (FileExists(directory)) { + throw IOException("Attempting to delete directory \"%s\", but it is a file and not a directory!", directory); + } + if (!DirectoryExists(directory)) { + return; + } + DeleteDirectoryRecursive(*this, directory.c_str()); } void LocalFileSystem::RemoveFile(const string &filename) { - DeleteFileA(filename.c_str()); + auto unicode_path = WindowsUtil::UTF8ToUnicode(filename.c_str()); + DeleteFileW(unicode_path.c_str()); } bool LocalFileSystem::ListFiles(const string &directory, const std::function &callback) { string search_dir = JoinPath(directory, "*"); - WIN32_FIND_DATA ffd; - HANDLE hFind = FindFirstFile(search_dir.c_str(), &ffd); + auto unicode_path = WindowsUtil::UTF8ToUnicode(search_dir.c_str()); + + WIN32_FIND_DATAW ffd; + HANDLE hFind = FindFirstFileW(unicode_path.c_str(), &ffd); if (hFind == INVALID_HANDLE_VALUE) { return false; } do { - string cFileName = string(ffd.cFileName); + string cFileName = WindowsUtil::UnicodeToUTF8(ffd.cFileName); if (cFileName == "." || cFileName == "..") { continue; } callback(cFileName, ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); - } while (FindNextFile(hFind, &ffd) != 0); + } while (FindNextFileW(hFind, &ffd) != 0); DWORD dwError = GetLastError(); if (dwError != ERROR_NO_MORE_FILES) { @@ -21279,7 +19335,9 @@ void LocalFileSystem::FileSync(FileHandle &handle) { } void LocalFileSystem::MoveFile(const string &source, const string &target) { - if (!MoveFileA(source.c_str(), target.c_str())) { + auto source_unicode = WindowsUtil::UTF8ToUnicode(source.c_str()); + auto target_unicode = WindowsUtil::UTF8ToUnicode(target.c_str()); + if (!MoveFileW(source_unicode.c_str(), target_unicode.c_str())) { throw IOException("Could not move file"); } } @@ -21290,7 +19348,7 @@ FileType LocalFileSystem::GetFileType(FileHandle &handle) { if (strncmp(path.c_str(), PIPE_PREFIX, strlen(PIPE_PREFIX)) == 0) { return FileType::FILE_TYPE_FIFO; } - DWORD attrs = GetFileAttributesA(path.c_str()); + DWORD attrs = WindowsGetFileAttributes(path.c_str()); if (attrs != INVALID_FILE_ATTRIBUTES) { if (attrs & FILE_ATTRIBUTE_DIRECTORY) { return FileType::FILE_TYPE_DIR; @@ -22315,6 +20373,21 @@ duckdb::string_t StringCast::Operation(dtime_t input, Vector &result); template <> duckdb::string_t StringCast::Operation(timestamp_t input, Vector &result); +//! Temporary casting for Time Zone types. TODO: turn casting into functions. +struct StringCastTZ { + template + static inline string_t Operation(SRC input, Vector &vector) { + return StringCast::Operation(input, vector); + } +}; + +template <> +duckdb::string_t StringCastTZ::Operation(date_t input, Vector &result); +template <> +duckdb::string_t StringCastTZ::Operation(dtime_t input, Vector &result); +template <> +duckdb::string_t StringCastTZ::Operation(timestamp_t input, Vector &result); + } // namespace duckdb //===----------------------------------------------------------------------===// @@ -24442,14 +22515,14 @@ static bool IntegerCastLoop(const char *buf, idx_t len, T &result, bool strict) if (pos >= len) { return false; } - int64_t exponent = 0; + int32_t exponent = 0; 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; } } @@ -26113,6 +24186,65 @@ duckdb::string_t StringCast::Operation(duckdb::string_t input, Vector &result) { return StringVector::AddStringOrBlob(result, input); } +template <> +string_t StringCastTZ::Operation(dtime_t input, Vector &vector) { + int32_t time[4]; + Time::Convert(input, time[0], time[1], time[2], time[3]); + + // format for timetz is TIME+00 + char micro_buffer[10]; + const auto time_length = TimeToStringCast::Length(time, micro_buffer); + const idx_t length = time_length + 3; + + string_t result = StringVector::EmptyString(vector, length); + auto data = result.GetDataWriteable(); + + idx_t pos = 0; + TimeToStringCast::Format(data + pos, length, time, micro_buffer); + pos += time_length; + data[pos++] = '+'; + data[pos++] = '0'; + data[pos++] = '0'; + + result.Finalize(); + return result; +} + +template <> +string_t StringCastTZ::Operation(timestamp_t input, Vector &vector) { + date_t date_entry; + dtime_t time_entry; + Timestamp::Convert(input, date_entry, time_entry); + + int32_t date[3], time[4]; + Date::Convert(date_entry, date[0], date[1], date[2]); + Time::Convert(time_entry, time[0], time[1], time[2], time[3]); + + // format for timestamptz is DATE TIME+00 (separated by space) + idx_t year_length; + bool add_bc; + char micro_buffer[6]; + const idx_t date_length = DateToStringCast::Length(date, year_length, add_bc); + const idx_t time_length = TimeToStringCast::Length(time, micro_buffer); + const idx_t length = date_length + 1 + time_length + 3; + + string_t result = StringVector::EmptyString(vector, length); + auto data = result.GetDataWriteable(); + + idx_t pos = 0; + DateToStringCast::Format(data + pos, date, year_length, add_bc); + pos += date_length; + data[pos++] = ' '; + TimeToStringCast::Format(data + pos, time_length, time, micro_buffer); + pos += time_length; + data[pos++] = '+'; + data[pos++] = '0'; + data[pos++] = '0'; + + result.Finalize(); + return result; +} + } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB @@ -26137,12 +24269,14 @@ class PipeFileSystem : public FileSystem { int64_t GetFileSize(FileHandle &handle) override; + void Reset(FileHandle &handle) override; bool OnDiskFile(FileHandle &handle) override { return false; }; bool CanSeek() override { return false; } + void FileSync(FileHandle &handle) override; std::string GetName() const override { return "PipeFileSystem"; @@ -26161,13 +24295,13 @@ class PipeFile : public FileHandle { : FileHandle(pipe_fs, path), child_handle(move(child_handle_p)) { } - int64_t ReadChunk(void *buffer, int64_t nr_bytes); - int64_t WriteChunk(void *buffer, int64_t nr_bytes); - PipeFileSystem pipe_fs; unique_ptr child_handle; -protected: +public: + int64_t ReadChunk(void *buffer, int64_t nr_bytes); + int64_t WriteChunk(void *buffer, int64_t nr_bytes); + void Close() override { } }; @@ -26179,6 +24313,10 @@ int64_t PipeFile::WriteChunk(void *buffer, int64_t nr_bytes) { return child_handle->Write(buffer, nr_bytes); } +void PipeFileSystem::Reset(FileHandle &handle) { + throw InternalException("Cannot reset pipe file system"); +} + int64_t PipeFileSystem::Read(FileHandle &handle, void *buffer, int64_t nr_bytes) { auto &pipe = (PipeFile &)handle; return pipe.ReadChunk(buffer, nr_bytes); @@ -26193,6 +24331,9 @@ int64_t PipeFileSystem::GetFileSize(FileHandle &handle) { return 0; } +void PipeFileSystem::FileSync(FileHandle &handle) { +} + unique_ptr PipeFileSystem::OpenPipe(unique_ptr handle) { auto path = handle->path; return make_unique(move(handle), path); @@ -26201,13 +24342,29 @@ unique_ptr PipeFileSystem::OpenPipe(unique_ptr handle) { } // namespace duckdb + + #include +#ifndef DUCKDB_DISABLE_PRINT +#ifdef DUCKDB_WINDOWS +#include +#endif +#endif + namespace duckdb { // LCOV_EXCL_START void Printer::Print(const string &str) { #ifndef DUCKDB_DISABLE_PRINT +#ifdef DUCKDB_WINDOWS + if (IsTerminal()) { + // print utf8 to terminal + auto unicode = WindowsUtil::UTF8ToMBCS(str.c_str()); + fprintf(stderr, "%s\n", unicode.c_str()); + return; + } +#endif fprintf(stderr, "%s\n", str.c_str()); #endif } @@ -26228,6 +24385,17 @@ void Printer::FinishProgressBarPrint(const char *pbstr, int pbwidth) { fflush(stdout); #endif } + +bool Printer::IsTerminal() { +#ifndef DUCKDB_DISABLE_PRINT +#ifdef DUCKDB_WINDOWS + return GetFileType(GetStdHandle(STD_ERROR_HANDLE)) == FILE_TYPE_CHAR; +#else + throw InternalException("IsTerminal is only implemented for Windows"); +#endif +#endif + return false; +} // LCOV_EXCL_STOP } // namespace duckdb @@ -26237,49 +24405,43 @@ void Printer::FinishProgressBarPrint(const char *pbstr, int pbwidth) { namespace duckdb { -void ProgressBar::ProgressBarThread() { -#ifndef DUCKDB_NO_THREADS - WaitFor(std::chrono::milliseconds(show_progress_after)); - while (!stop) { - int new_percentage; - supported = executor->GetPipelinesProgress(new_percentage); - current_percentage = new_percentage; - if (supported && current_percentage > -1 && executor->context.print_progress_bar) { - Printer::PrintProgress(current_percentage, PROGRESS_BAR_STRING.c_str(), PROGRESS_BAR_WIDTH); - } - WaitFor(std::chrono::milliseconds(time_update_bar)); - } -#endif +ProgressBar::ProgressBar(Executor &executor, idx_t show_progress_after) + : executor(executor), show_progress_after(show_progress_after), current_percentage(-1) { } -int ProgressBar::GetCurrentPercentage() { +double ProgressBar::GetCurrentPercentage() { return current_percentage; } void ProgressBar::Start() { -#ifndef DUCKDB_NO_THREADS - stop = false; + profiler.Start(); current_percentage = 0; - progress_bar_thread = thread(&ProgressBar::ProgressBarThread, this); -#endif -} - -ProgressBar::~ProgressBar() { - Stop(); + supported = true; } -void ProgressBar::Stop() { -#ifndef DUCKDB_NO_THREADS - if (progress_bar_thread.joinable()) { - stop = true; - c.notify_one(); - progress_bar_thread.join(); - if (supported && current_percentage > 0 && executor->context.print_progress_bar) { +void ProgressBar::Update(bool final) { + if (!supported) { + return; + } + double new_percentage; + supported = executor.GetPipelinesProgress(new_percentage); + if (!supported) { + return; + } + auto sufficient_time_elapsed = profiler.Elapsed() > show_progress_after / 1000.0; + auto print_progress = ClientConfig::GetConfig(executor.context).print_progress_bar; + if (new_percentage > current_percentage) { + current_percentage = new_percentage; + } + if (supported && print_progress && sufficient_time_elapsed && current_percentage > -1 && print_progress) { + if (final) { Printer::FinishProgressBarPrint(PROGRESS_BAR_STRING.c_str(), PROGRESS_BAR_WIDTH); + } else { + Printer::PrintProgress(current_percentage, PROGRESS_BAR_STRING.c_str(), PROGRESS_BAR_WIDTH); } } -#endif } + } // namespace duckdb @@ -26552,11 +24714,9 @@ struct RowOperations { //! Swizzles the base pointer of each row to offset within heap block static void SwizzleHeapPointer(const RowLayout &layout, data_ptr_t row_ptr, const data_ptr_t heap_base_ptr, const idx_t count); - //! Swizzles the base offset of each row back to a pointer - static void UnswizzleHeapPointer(const RowLayout &layout, data_ptr_t row_ptr, const data_ptr_t heap_base_ptr, - const idx_t count); - //! Unswizzles offsets back to pointers to blobs - static void UnswizzleColumns(const RowLayout &layout, const data_ptr_t base_row_ptr, const idx_t count); + //! Unswizzles all offsets back to pointers + static void UnswizzlePointers(const RowLayout &layout, const data_ptr_t base_row_ptr, + const data_ptr_t base_heap_ptr, const idx_t count); }; } // namespace duckdb @@ -26792,46 +24952,44 @@ namespace duckdb { void RowOperations::SwizzleColumns(const RowLayout &layout, const data_ptr_t base_row_ptr, const idx_t count) { const idx_t row_width = layout.GetRowWidth(); - const idx_t heap_pointer_offset = layout.GetHeapPointerOffset(); - // Swizzle the blob columns one by one - for (idx_t col_idx = 0; col_idx < layout.ColumnCount(); col_idx++) { - auto physical_type = layout.GetTypes()[col_idx].InternalType(); - if (TypeIsConstantSize(physical_type)) { - continue; + data_ptr_t heap_row_ptrs[STANDARD_VECTOR_SIZE]; + idx_t done = 0; + while (done != count) { + const idx_t next = MinValue(count - done, STANDARD_VECTOR_SIZE); + const data_ptr_t row_ptr = base_row_ptr + done * row_width; + // Load heap row pointers + data_ptr_t heap_ptr_ptr = row_ptr + layout.GetHeapPointerOffset(); + for (idx_t i = 0; i < next; i++) { + heap_row_ptrs[i] = Load(heap_ptr_ptr); + heap_ptr_ptr += row_width; } - data_ptr_t row_ptr = base_row_ptr; - const idx_t &col_offset = layout.GetOffsets()[col_idx]; - if (physical_type == PhysicalType::VARCHAR) { - // Replace the pointer with the computed offset (if non-inlined) - const idx_t string_pointer_offset = sizeof(uint32_t) + string_t::PREFIX_LENGTH; - for (idx_t i = 0; i < count; i++) { - const string_t str = Load(row_ptr + col_offset); - if (!str.IsInlined()) { - // Load the pointer to the start of the row in the heap - data_ptr_t heap_row_ptr = Load(row_ptr + heap_pointer_offset); - // This is where the pointer that points to the heap is stored in the RowLayout - data_ptr_t col_ptr = row_ptr + col_offset + string_pointer_offset; - // Load the pointer to the data of this column in the same heap row - data_ptr_t heap_col_ptr = Load(col_ptr); - // Overwrite the column data pointer with the within-row offset (pointer arithmetic) - Store(heap_col_ptr - heap_row_ptr, col_ptr); - } - row_ptr += row_width; + // Loop through the blob columns + for (idx_t col_idx = 0; col_idx < layout.ColumnCount(); col_idx++) { + auto physical_type = layout.GetTypes()[col_idx].InternalType(); + if (TypeIsConstantSize(physical_type)) { + continue; } - } else { - // Replace the pointer with the computed offset - for (idx_t i = 0; i < count; i++) { - // Load the pointer to the start of the row in the heap - data_ptr_t heap_row_ptr = Load(row_ptr + heap_pointer_offset); - // This is where the pointer that points to the heap is stored in the RowLayout - data_ptr_t col_ptr = row_ptr + col_offset; - // Load the pointer to the data of this column in the same heap row - data_ptr_t heap_col_ptr = Load(col_ptr); - // Overwrite the column data pointer with the within-row offset (pointer arithmetic) - Store(heap_col_ptr - heap_row_ptr, col_ptr); - row_ptr += row_width; + data_ptr_t col_ptr = row_ptr + layout.GetOffsets()[col_idx]; + if (physical_type == PhysicalType::VARCHAR) { + data_ptr_t string_ptr = col_ptr + sizeof(uint32_t) + string_t::PREFIX_LENGTH; + for (idx_t i = 0; i < next; i++) { + if (Load(col_ptr) > string_t::INLINE_LENGTH) { + // Overwrite the string pointer with the within-row offset (if not inlined) + Store(Load(string_ptr) - heap_row_ptrs[i], string_ptr); + } + col_ptr += row_width; + string_ptr += row_width; + } + } else { + // Non-varchar blob columns + for (idx_t i = 0; i < next; i++) { + // Overwrite the column data pointer with the within-row offset + Store(Load(col_ptr) - heap_row_ptrs[i], col_ptr); + col_ptr += row_width; + } } } + done += next; } } @@ -26847,59 +25005,48 @@ void RowOperations::SwizzleHeapPointer(const RowLayout &layout, data_ptr_t row_p } } -void RowOperations::UnswizzleHeapPointer(const RowLayout &layout, data_ptr_t row_ptr, const data_ptr_t heap_base_ptr, - const idx_t count) { - const idx_t row_width = layout.GetRowWidth(); - row_ptr += layout.GetHeapPointerOffset(); - for (idx_t i = 0; i < count; i++) { - idx_t heap_row_offset = Load(row_ptr); - Store(heap_base_ptr + heap_row_offset, row_ptr); - row_ptr += row_width; - } -} - -void RowOperations::UnswizzleColumns(const RowLayout &layout, const data_ptr_t base_row_ptr, const idx_t count) { +void RowOperations::UnswizzlePointers(const RowLayout &layout, const data_ptr_t base_row_ptr, + const data_ptr_t base_heap_ptr, const idx_t count) { const idx_t row_width = layout.GetRowWidth(); - const idx_t heap_pointer_offset = layout.GetHeapPointerOffset(); - // Unswizzle the columns one by one - for (idx_t col_idx = 0; col_idx < layout.ColumnCount(); col_idx++) { - auto physical_type = layout.GetTypes()[col_idx].InternalType(); - if (TypeIsConstantSize(physical_type)) { - continue; - } - const idx_t col_offset = layout.GetOffsets()[col_idx]; - data_ptr_t row_ptr = base_row_ptr; - if (physical_type == PhysicalType::VARCHAR) { - // Replace offset with the pointer (if non-inlined) - const idx_t string_pointer_offset = sizeof(uint32_t) + string_t::PREFIX_LENGTH; - for (idx_t i = 0; i < count; i++) { - const string_t str = Load(row_ptr + col_offset); - if (!str.IsInlined()) { - // Load the pointer to the start of the row in the heap - data_ptr_t heap_row_ptr = Load(row_ptr + heap_pointer_offset); - // This is where the pointer that points to the heap is stored in the RowLayout - data_ptr_t col_ptr = row_ptr + col_offset + string_pointer_offset; - // Load the offset to the data of this column in the same heap row - idx_t heap_col_offset = Load(col_ptr); + data_ptr_t heap_row_ptrs[STANDARD_VECTOR_SIZE]; + idx_t done = 0; + while (done != count) { + const idx_t next = MinValue(count - done, STANDARD_VECTOR_SIZE); + const data_ptr_t row_ptr = base_row_ptr + done * row_width; + // Restore heap row pointers + data_ptr_t heap_ptr_ptr = row_ptr + layout.GetHeapPointerOffset(); + for (idx_t i = 0; i < next; i++) { + heap_row_ptrs[i] = base_heap_ptr + Load(heap_ptr_ptr); + Store(heap_row_ptrs[i], heap_ptr_ptr); + heap_ptr_ptr += row_width; + } + // Loop through the blob columns + for (idx_t col_idx = 0; col_idx < layout.ColumnCount(); col_idx++) { + auto physical_type = layout.GetTypes()[col_idx].InternalType(); + if (TypeIsConstantSize(physical_type)) { + continue; + } + data_ptr_t col_ptr = row_ptr + layout.GetOffsets()[col_idx]; + if (physical_type == PhysicalType::VARCHAR) { + data_ptr_t string_ptr = col_ptr + sizeof(uint32_t) + string_t::PREFIX_LENGTH; + for (idx_t i = 0; i < next; i++) { + if (Load(col_ptr) > string_t::INLINE_LENGTH) { + // Overwrite the string offset with the pointer (if not inlined) + Store(heap_row_ptrs[i] + Load(string_ptr), string_ptr); + } + col_ptr += row_width; + string_ptr += row_width; + } + } else { + // Non-varchar blob columns + for (idx_t i = 0; i < next; i++) { // Overwrite the column data offset with the pointer - Store(heap_row_ptr + heap_col_offset, col_ptr); + Store(heap_row_ptrs[i] + Load(col_ptr), col_ptr); + col_ptr += row_width; } - row_ptr += row_width; - } - } else { - // Replace the offset with the pointer - for (idx_t i = 0; i < count; i++) { - // Load the pointer to the start of the row in the heap - data_ptr_t heap_row_ptr = Load(row_ptr + heap_pointer_offset); - // This is where the pointer that points to the heap is stored in the RowLayout - data_ptr_t col_ptr = row_ptr + col_offset; - // Load the offset to the data of this column in the same heap row - idx_t heap_col_offset = Load(col_ptr); - // Overwrite the column data offset with the pointer - Store(heap_row_ptr + heap_col_offset, col_ptr); - row_ptr += row_width; } } + done += next; } } @@ -27027,7 +25174,7 @@ class RowDataCollection { idx_t AppendToBlock(RowDataBlock &block, BufferHandle &handle, vector &append_entries, idx_t remaining, idx_t entry_sizes[]); vector> Build(idx_t added_count, data_ptr_t key_locations[], idx_t entry_sizes[], - const SelectionVector *sel = &FlatVector::INCREMENTAL_SELECTION_VECTOR); + const SelectionVector *sel = FlatVector::IncrementalSelectionVector()); void Merge(RowDataCollection &other); @@ -27093,8 +25240,8 @@ static void GatherNestedVector(Vector &rows, const SelectionVector &row_sel, Vec auto ptrs = FlatVector::GetData(rows); // Build the gather locations - data_ptr_t data_locations[STANDARD_VECTOR_SIZE]; - data_ptr_t mask_locations[STANDARD_VECTOR_SIZE]; + auto data_locations = unique_ptr(new data_ptr_t[count]); + auto mask_locations = unique_ptr(new data_ptr_t[count]); for (idx_t i = 0; i < count; i++) { auto row_idx = row_sel.get_index(i); mask_locations[i] = ptrs[row_idx]; @@ -27102,7 +25249,7 @@ static void GatherNestedVector(Vector &rows, const SelectionVector &row_sel, Vec } // Deserialise into the selected locations - RowOperations::HeapGather(col, count, col_sel, col_no, data_locations, mask_locations); + RowOperations::HeapGather(col, count, col_sel, col_no, data_locations.get(), mask_locations.get()); } void RowOperations::Gather(Vector &rows, const SelectionVector &row_sel, Vector &col, const SelectionVector &col_sel, @@ -27342,7 +25489,7 @@ static void HeapGatherListVector(Vector &v, const idx_t vcount, const SelectionV } // now deserialize and add to listvector - RowOperations::HeapGather(list_vec_to_append, next, FlatVector::INCREMENTAL_SELECTION_VECTOR, 0, + RowOperations::HeapGather(list_vec_to_append, next, *FlatVector::IncrementalSelectionVector(), 0, list_entry_locations, nullptr); ListVector::Append(v, list_vec_to_append, next); @@ -27509,7 +25656,7 @@ static void ComputeListEntrySizes(Vector &v, VectorData &vdata, idx_t entry_size // compute and add to the total std::fill_n(list_entry_sizes, next, 0); RowOperations::ComputeEntrySizes(child_vector, list_entry_sizes, next, next, - FlatVector::INCREMENTAL_SELECTION_VECTOR, entry_offset); + *FlatVector::IncrementalSelectionVector(), entry_offset); for (idx_t list_idx = 0; list_idx < next; list_idx++) { entry_sizes[i] += list_entry_sizes[list_idx]; } @@ -27771,7 +25918,7 @@ static void HeapScatterListVector(Vector &v, idx_t vcount, const SelectionVector // variable size list entries: compute entry sizes and set list entry locations std::fill_n(list_entry_sizes, next, 0); RowOperations::ComputeEntrySizes(child_vector, list_entry_sizes, next, next, - FlatVector::INCREMENTAL_SELECTION_VECTOR, entry_offset); + *FlatVector::IncrementalSelectionVector(), entry_offset); for (idx_t entry_idx = 0; entry_idx < next; entry_idx++) { list_entry_locations[entry_idx] = key_locations[i]; key_locations[i] += list_entry_sizes[entry_idx]; @@ -27782,8 +25929,8 @@ static void HeapScatterListVector(Vector &v, idx_t vcount, const SelectionVector // now serialize to the locations RowOperations::HeapScatter(child_vector, ListVector::GetListSize(v), - FlatVector::INCREMENTAL_SELECTION_VECTOR, next, 0, list_entry_locations, nullptr, - entry_offset); + *FlatVector::IncrementalSelectionVector(), next, 0, list_entry_locations, + nullptr, entry_offset); // update for next iteration entry_remaining -= next; @@ -28254,7 +26401,7 @@ void RadixScatterListVector(Vector &v, VectorData &vdata, const SelectionVector // denote that the list is not empty with a 1 key_locations[i][0] = 1; key_locations[i]++; - RowOperations::RadixScatter(child_vector, list_size, FlatVector::INCREMENTAL_SELECTION_VECTOR, 1, + RowOperations::RadixScatter(child_vector, list_size, *FlatVector::IncrementalSelectionVector(), 1, key_locations + i, false, true, false, prefix_len, width - 1, list_entry.offset); } else { @@ -28285,7 +26432,7 @@ void RadixScatterListVector(Vector &v, VectorData &vdata, const SelectionVector // denote that the list is not empty with a 1 key_locations[i][0] = 1; key_locations[i]++; - RowOperations::RadixScatter(child_vector, list_size, FlatVector::INCREMENTAL_SELECTION_VECTOR, 1, + RowOperations::RadixScatter(child_vector, list_size, *FlatVector::IncrementalSelectionVector(), 1, key_locations + i, false, true, false, prefix_len, width - 1, list_entry.offset); } else { @@ -28328,7 +26475,7 @@ void RadixScatterStructVector(Vector &v, VectorData &vdata, idx_t vcount, const } // serialize the struct auto &child_vector = *StructVector::GetEntries(v)[0]; - RowOperations::RadixScatter(child_vector, vcount, FlatVector::INCREMENTAL_SELECTION_VECTOR, add_count, + RowOperations::RadixScatter(child_vector, vcount, *FlatVector::IncrementalSelectionVector(), add_count, key_locations, false, true, false, prefix_len, width, offset); // invert bits if desc if (desc) { @@ -28796,8 +26943,8 @@ namespace duckdb { // Remove this when we switch C++17: https://stackoverflow.com/a/53350948 constexpr uint8_t BufferedFileWriter::DEFAULT_OPEN_FLAGS; -BufferedFileWriter::BufferedFileWriter(FileSystem &fs, const string &path, uint8_t open_flags, FileOpener *opener) - : fs(fs), data(unique_ptr(new data_t[FILE_BUFFER_SIZE])), offset(0), total_written(0) { +BufferedFileWriter::BufferedFileWriter(FileSystem &fs, const string &path_p, uint8_t open_flags, FileOpener *opener) + : fs(fs), path(path_p), data(unique_ptr(new data_t[FILE_BUFFER_SIZE])), offset(0), total_written(0) { handle = fs.OpenFile(path, open_flags, FileLockType::WRITE_LOCK, FileSystem::DEFAULT_COMPRESSION, opener); } @@ -28888,6 +27035,9 @@ namespace duckdb { template <> string Deserializer::Read() { uint32_t size = Read(); + if (size == 0) { + return string(); + } auto buffer = unique_ptr(new data_t[size]); ReadData(buffer.get(), size); return string((char *)buffer.get(), size); @@ -28918,8 +27068,7 @@ void Deserializer::ReadStringVector(vector &list) { namespace duckdb { struct SortLayout; -struct SortedBlock; -struct SortedData; +struct SBScanState; using ValidityBytes = RowLayout::ValidityBytes; @@ -28929,14 +27078,14 @@ struct Comparators { static bool TieIsBreakable(const idx_t &col_idx, const data_ptr_t row_ptr, const RowLayout &row_layout); //! Compares the tuples that a being read from in the 'left' and 'right blocks during merge sort //! (only in case we cannot simply 'memcmp' - if there are blob columns) - static int CompareTuple(const SortedBlock &left, const SortedBlock &right, const data_ptr_t &l_ptr, + static int CompareTuple(const SBScanState &left, const SBScanState &right, const data_ptr_t &l_ptr, const data_ptr_t &r_ptr, const SortLayout &sort_layout, const bool &external_sort); //! Compare two blob values static int CompareVal(const data_ptr_t l_ptr, const data_ptr_t r_ptr, const LogicalType &type); private: //! Compares two blob values that were initially tied by their prefix - static int BreakBlobTie(const idx_t &tie_col, const SortedData &left, const SortedData &right, + static int BreakBlobTie(const idx_t &tie_col, const SBScanState &left, const SBScanState &right, const SortLayout &sort_layout, const bool &external); //! Compare two fixed-size values template @@ -28968,6 +27117,700 @@ struct Comparators { } // namespace duckdb +// DuckDB +// +// duckdb/common/fast_mem.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +template +static inline void MemcpyFixed(void *dest, const void *src) { + memcpy(dest, src, SIZE); +} + +template +static inline int MemcmpFixed(const void *str1, const void *str2) { + return memcmp(str1, str2, SIZE); +} + +namespace duckdb { + +//! This templated memcpy is significantly faster than std::memcpy, +//! but only when you are calling memcpy with a const size in a loop. +//! For instance `while () { memcpy(, , const_size); ... }` +static inline void FastMemcpy(void *dest, const void *src, const size_t size) { + // LCOV_EXCL_START + switch (size) { + case 0: + return; + case 1: + return MemcpyFixed<1>(dest, src); + case 2: + return MemcpyFixed<2>(dest, src); + case 3: + return MemcpyFixed<3>(dest, src); + case 4: + return MemcpyFixed<4>(dest, src); + case 5: + return MemcpyFixed<5>(dest, src); + case 6: + return MemcpyFixed<6>(dest, src); + case 7: + return MemcpyFixed<7>(dest, src); + case 8: + return MemcpyFixed<8>(dest, src); + case 9: + return MemcpyFixed<9>(dest, src); + case 10: + return MemcpyFixed<10>(dest, src); + case 11: + return MemcpyFixed<11>(dest, src); + case 12: + return MemcpyFixed<12>(dest, src); + case 13: + return MemcpyFixed<13>(dest, src); + case 14: + return MemcpyFixed<14>(dest, src); + case 15: + return MemcpyFixed<15>(dest, src); + case 16: + return MemcpyFixed<16>(dest, src); + case 17: + return MemcpyFixed<17>(dest, src); + case 18: + return MemcpyFixed<18>(dest, src); + case 19: + return MemcpyFixed<19>(dest, src); + case 20: + return MemcpyFixed<20>(dest, src); + case 21: + return MemcpyFixed<21>(dest, src); + case 22: + return MemcpyFixed<22>(dest, src); + case 23: + return MemcpyFixed<23>(dest, src); + case 24: + return MemcpyFixed<24>(dest, src); + case 25: + return MemcpyFixed<25>(dest, src); + case 26: + return MemcpyFixed<26>(dest, src); + case 27: + return MemcpyFixed<27>(dest, src); + case 28: + return MemcpyFixed<28>(dest, src); + case 29: + return MemcpyFixed<29>(dest, src); + case 30: + return MemcpyFixed<30>(dest, src); + case 31: + return MemcpyFixed<31>(dest, src); + case 32: + return MemcpyFixed<32>(dest, src); + case 33: + return MemcpyFixed<33>(dest, src); + case 34: + return MemcpyFixed<34>(dest, src); + case 35: + return MemcpyFixed<35>(dest, src); + case 36: + return MemcpyFixed<36>(dest, src); + case 37: + return MemcpyFixed<37>(dest, src); + case 38: + return MemcpyFixed<38>(dest, src); + case 39: + return MemcpyFixed<39>(dest, src); + case 40: + return MemcpyFixed<40>(dest, src); + case 41: + return MemcpyFixed<41>(dest, src); + case 42: + return MemcpyFixed<42>(dest, src); + case 43: + return MemcpyFixed<43>(dest, src); + case 44: + return MemcpyFixed<44>(dest, src); + case 45: + return MemcpyFixed<45>(dest, src); + case 46: + return MemcpyFixed<46>(dest, src); + case 47: + return MemcpyFixed<47>(dest, src); + case 48: + return MemcpyFixed<48>(dest, src); + case 49: + return MemcpyFixed<49>(dest, src); + case 50: + return MemcpyFixed<50>(dest, src); + case 51: + return MemcpyFixed<51>(dest, src); + case 52: + return MemcpyFixed<52>(dest, src); + case 53: + return MemcpyFixed<53>(dest, src); + case 54: + return MemcpyFixed<54>(dest, src); + case 55: + return MemcpyFixed<55>(dest, src); + case 56: + return MemcpyFixed<56>(dest, src); + case 57: + return MemcpyFixed<57>(dest, src); + case 58: + return MemcpyFixed<58>(dest, src); + case 59: + return MemcpyFixed<59>(dest, src); + case 60: + return MemcpyFixed<60>(dest, src); + case 61: + return MemcpyFixed<61>(dest, src); + case 62: + return MemcpyFixed<62>(dest, src); + case 63: + return MemcpyFixed<63>(dest, src); + case 64: + return MemcpyFixed<64>(dest, src); + case 65: + return MemcpyFixed<65>(dest, src); + case 66: + return MemcpyFixed<66>(dest, src); + case 67: + return MemcpyFixed<67>(dest, src); + case 68: + return MemcpyFixed<68>(dest, src); + case 69: + return MemcpyFixed<69>(dest, src); + case 70: + return MemcpyFixed<70>(dest, src); + case 71: + return MemcpyFixed<71>(dest, src); + case 72: + return MemcpyFixed<72>(dest, src); + case 73: + return MemcpyFixed<73>(dest, src); + case 74: + return MemcpyFixed<74>(dest, src); + case 75: + return MemcpyFixed<75>(dest, src); + case 76: + return MemcpyFixed<76>(dest, src); + case 77: + return MemcpyFixed<77>(dest, src); + case 78: + return MemcpyFixed<78>(dest, src); + case 79: + return MemcpyFixed<79>(dest, src); + case 80: + return MemcpyFixed<80>(dest, src); + case 81: + return MemcpyFixed<81>(dest, src); + case 82: + return MemcpyFixed<82>(dest, src); + case 83: + return MemcpyFixed<83>(dest, src); + case 84: + return MemcpyFixed<84>(dest, src); + case 85: + return MemcpyFixed<85>(dest, src); + case 86: + return MemcpyFixed<86>(dest, src); + case 87: + return MemcpyFixed<87>(dest, src); + case 88: + return MemcpyFixed<88>(dest, src); + case 89: + return MemcpyFixed<89>(dest, src); + case 90: + return MemcpyFixed<90>(dest, src); + case 91: + return MemcpyFixed<91>(dest, src); + case 92: + return MemcpyFixed<92>(dest, src); + case 93: + return MemcpyFixed<93>(dest, src); + case 94: + return MemcpyFixed<94>(dest, src); + case 95: + return MemcpyFixed<95>(dest, src); + case 96: + return MemcpyFixed<96>(dest, src); + case 97: + return MemcpyFixed<97>(dest, src); + case 98: + return MemcpyFixed<98>(dest, src); + case 99: + return MemcpyFixed<99>(dest, src); + case 100: + return MemcpyFixed<100>(dest, src); + case 101: + return MemcpyFixed<101>(dest, src); + case 102: + return MemcpyFixed<102>(dest, src); + case 103: + return MemcpyFixed<103>(dest, src); + case 104: + return MemcpyFixed<104>(dest, src); + case 105: + return MemcpyFixed<105>(dest, src); + case 106: + return MemcpyFixed<106>(dest, src); + case 107: + return MemcpyFixed<107>(dest, src); + case 108: + return MemcpyFixed<108>(dest, src); + case 109: + return MemcpyFixed<109>(dest, src); + case 110: + return MemcpyFixed<110>(dest, src); + case 111: + return MemcpyFixed<111>(dest, src); + case 112: + return MemcpyFixed<112>(dest, src); + case 113: + return MemcpyFixed<113>(dest, src); + case 114: + return MemcpyFixed<114>(dest, src); + case 115: + return MemcpyFixed<115>(dest, src); + case 116: + return MemcpyFixed<116>(dest, src); + case 117: + return MemcpyFixed<117>(dest, src); + case 118: + return MemcpyFixed<118>(dest, src); + case 119: + return MemcpyFixed<119>(dest, src); + case 120: + return MemcpyFixed<120>(dest, src); + case 121: + return MemcpyFixed<121>(dest, src); + case 122: + return MemcpyFixed<122>(dest, src); + case 123: + return MemcpyFixed<123>(dest, src); + case 124: + return MemcpyFixed<124>(dest, src); + case 125: + return MemcpyFixed<125>(dest, src); + case 126: + return MemcpyFixed<126>(dest, src); + case 127: + return MemcpyFixed<127>(dest, src); + case 128: + return MemcpyFixed<128>(dest, src); + case 129: + return MemcpyFixed<129>(dest, src); + case 130: + return MemcpyFixed<130>(dest, src); + case 131: + return MemcpyFixed<131>(dest, src); + case 132: + return MemcpyFixed<132>(dest, src); + case 133: + return MemcpyFixed<133>(dest, src); + case 134: + return MemcpyFixed<134>(dest, src); + case 135: + return MemcpyFixed<135>(dest, src); + case 136: + return MemcpyFixed<136>(dest, src); + case 137: + return MemcpyFixed<137>(dest, src); + case 138: + return MemcpyFixed<138>(dest, src); + case 139: + return MemcpyFixed<139>(dest, src); + case 140: + return MemcpyFixed<140>(dest, src); + case 141: + return MemcpyFixed<141>(dest, src); + case 142: + return MemcpyFixed<142>(dest, src); + case 143: + return MemcpyFixed<143>(dest, src); + case 144: + return MemcpyFixed<144>(dest, src); + case 145: + return MemcpyFixed<145>(dest, src); + case 146: + return MemcpyFixed<146>(dest, src); + case 147: + return MemcpyFixed<147>(dest, src); + case 148: + return MemcpyFixed<148>(dest, src); + case 149: + return MemcpyFixed<149>(dest, src); + case 150: + return MemcpyFixed<150>(dest, src); + case 151: + return MemcpyFixed<151>(dest, src); + case 152: + return MemcpyFixed<152>(dest, src); + case 153: + return MemcpyFixed<153>(dest, src); + case 154: + return MemcpyFixed<154>(dest, src); + case 155: + return MemcpyFixed<155>(dest, src); + case 156: + return MemcpyFixed<156>(dest, src); + case 157: + return MemcpyFixed<157>(dest, src); + case 158: + return MemcpyFixed<158>(dest, src); + case 159: + return MemcpyFixed<159>(dest, src); + case 160: + return MemcpyFixed<160>(dest, src); + case 161: + return MemcpyFixed<161>(dest, src); + case 162: + return MemcpyFixed<162>(dest, src); + case 163: + return MemcpyFixed<163>(dest, src); + case 164: + return MemcpyFixed<164>(dest, src); + case 165: + return MemcpyFixed<165>(dest, src); + case 166: + return MemcpyFixed<166>(dest, src); + case 167: + return MemcpyFixed<167>(dest, src); + case 168: + return MemcpyFixed<168>(dest, src); + case 169: + return MemcpyFixed<169>(dest, src); + case 170: + return MemcpyFixed<170>(dest, src); + case 171: + return MemcpyFixed<171>(dest, src); + case 172: + return MemcpyFixed<172>(dest, src); + case 173: + return MemcpyFixed<173>(dest, src); + case 174: + return MemcpyFixed<174>(dest, src); + case 175: + return MemcpyFixed<175>(dest, src); + case 176: + return MemcpyFixed<176>(dest, src); + case 177: + return MemcpyFixed<177>(dest, src); + case 178: + return MemcpyFixed<178>(dest, src); + case 179: + return MemcpyFixed<179>(dest, src); + case 180: + return MemcpyFixed<180>(dest, src); + case 181: + return MemcpyFixed<181>(dest, src); + case 182: + return MemcpyFixed<182>(dest, src); + case 183: + return MemcpyFixed<183>(dest, src); + case 184: + return MemcpyFixed<184>(dest, src); + case 185: + return MemcpyFixed<185>(dest, src); + case 186: + return MemcpyFixed<186>(dest, src); + case 187: + return MemcpyFixed<187>(dest, src); + case 188: + return MemcpyFixed<188>(dest, src); + case 189: + return MemcpyFixed<189>(dest, src); + case 190: + return MemcpyFixed<190>(dest, src); + case 191: + return MemcpyFixed<191>(dest, src); + case 192: + return MemcpyFixed<192>(dest, src); + case 193: + return MemcpyFixed<193>(dest, src); + case 194: + return MemcpyFixed<194>(dest, src); + case 195: + return MemcpyFixed<195>(dest, src); + case 196: + return MemcpyFixed<196>(dest, src); + case 197: + return MemcpyFixed<197>(dest, src); + case 198: + return MemcpyFixed<198>(dest, src); + case 199: + return MemcpyFixed<199>(dest, src); + case 200: + return MemcpyFixed<200>(dest, src); + case 201: + return MemcpyFixed<201>(dest, src); + case 202: + return MemcpyFixed<202>(dest, src); + case 203: + return MemcpyFixed<203>(dest, src); + case 204: + return MemcpyFixed<204>(dest, src); + case 205: + return MemcpyFixed<205>(dest, src); + case 206: + return MemcpyFixed<206>(dest, src); + case 207: + return MemcpyFixed<207>(dest, src); + case 208: + return MemcpyFixed<208>(dest, src); + case 209: + return MemcpyFixed<209>(dest, src); + case 210: + return MemcpyFixed<210>(dest, src); + case 211: + return MemcpyFixed<211>(dest, src); + case 212: + return MemcpyFixed<212>(dest, src); + case 213: + return MemcpyFixed<213>(dest, src); + case 214: + return MemcpyFixed<214>(dest, src); + case 215: + return MemcpyFixed<215>(dest, src); + case 216: + return MemcpyFixed<216>(dest, src); + case 217: + return MemcpyFixed<217>(dest, src); + case 218: + return MemcpyFixed<218>(dest, src); + case 219: + return MemcpyFixed<219>(dest, src); + case 220: + return MemcpyFixed<220>(dest, src); + case 221: + return MemcpyFixed<221>(dest, src); + case 222: + return MemcpyFixed<222>(dest, src); + case 223: + return MemcpyFixed<223>(dest, src); + case 224: + return MemcpyFixed<224>(dest, src); + case 225: + return MemcpyFixed<225>(dest, src); + case 226: + return MemcpyFixed<226>(dest, src); + case 227: + return MemcpyFixed<227>(dest, src); + case 228: + return MemcpyFixed<228>(dest, src); + case 229: + return MemcpyFixed<229>(dest, src); + case 230: + return MemcpyFixed<230>(dest, src); + case 231: + return MemcpyFixed<231>(dest, src); + case 232: + return MemcpyFixed<232>(dest, src); + case 233: + return MemcpyFixed<233>(dest, src); + case 234: + return MemcpyFixed<234>(dest, src); + case 235: + return MemcpyFixed<235>(dest, src); + case 236: + return MemcpyFixed<236>(dest, src); + case 237: + return MemcpyFixed<237>(dest, src); + case 238: + return MemcpyFixed<238>(dest, src); + case 239: + return MemcpyFixed<239>(dest, src); + case 240: + return MemcpyFixed<240>(dest, src); + case 241: + return MemcpyFixed<241>(dest, src); + case 242: + return MemcpyFixed<242>(dest, src); + case 243: + return MemcpyFixed<243>(dest, src); + case 244: + return MemcpyFixed<244>(dest, src); + case 245: + return MemcpyFixed<245>(dest, src); + case 246: + return MemcpyFixed<246>(dest, src); + case 247: + return MemcpyFixed<247>(dest, src); + case 248: + return MemcpyFixed<248>(dest, src); + case 249: + return MemcpyFixed<249>(dest, src); + case 250: + return MemcpyFixed<250>(dest, src); + case 251: + return MemcpyFixed<251>(dest, src); + case 252: + return MemcpyFixed<252>(dest, src); + case 253: + return MemcpyFixed<253>(dest, src); + case 254: + return MemcpyFixed<254>(dest, src); + case 255: + return MemcpyFixed<255>(dest, src); + case 256: + return MemcpyFixed<256>(dest, src); + default: + memcpy(dest, src, size); + } + // LCOV_EXCL_STOP +} + +//! This templated memcmp is significantly faster than std::memcmp, +//! but only when you are calling memcmp with a const size in a loop. +//! For instance `while () { memcmp(, , const_size); ... }` +static inline int FastMemcmp(const void *str1, const void *str2, const size_t size) { + // LCOV_EXCL_START + switch (size) { + case 0: + return 0; + case 1: + return MemcmpFixed<1>(str1, str2); + case 2: + return MemcmpFixed<2>(str1, str2); + case 3: + return MemcmpFixed<3>(str1, str2); + case 4: + return MemcmpFixed<4>(str1, str2); + case 5: + return MemcmpFixed<5>(str1, str2); + case 6: + return MemcmpFixed<6>(str1, str2); + case 7: + return MemcmpFixed<7>(str1, str2); + case 8: + return MemcmpFixed<8>(str1, str2); + case 9: + return MemcmpFixed<9>(str1, str2); + case 10: + return MemcmpFixed<10>(str1, str2); + case 11: + return MemcmpFixed<11>(str1, str2); + case 12: + return MemcmpFixed<12>(str1, str2); + case 13: + return MemcmpFixed<13>(str1, str2); + case 14: + return MemcmpFixed<14>(str1, str2); + case 15: + return MemcmpFixed<15>(str1, str2); + case 16: + return MemcmpFixed<16>(str1, str2); + case 17: + return MemcmpFixed<17>(str1, str2); + case 18: + return MemcmpFixed<18>(str1, str2); + case 19: + return MemcmpFixed<19>(str1, str2); + case 20: + return MemcmpFixed<20>(str1, str2); + case 21: + return MemcmpFixed<21>(str1, str2); + case 22: + return MemcmpFixed<22>(str1, str2); + case 23: + return MemcmpFixed<23>(str1, str2); + case 24: + return MemcmpFixed<24>(str1, str2); + case 25: + return MemcmpFixed<25>(str1, str2); + case 26: + return MemcmpFixed<26>(str1, str2); + case 27: + return MemcmpFixed<27>(str1, str2); + case 28: + return MemcmpFixed<28>(str1, str2); + case 29: + return MemcmpFixed<29>(str1, str2); + case 30: + return MemcmpFixed<30>(str1, str2); + case 31: + return MemcmpFixed<31>(str1, str2); + case 32: + return MemcmpFixed<32>(str1, str2); + case 33: + return MemcmpFixed<33>(str1, str2); + case 34: + return MemcmpFixed<34>(str1, str2); + case 35: + return MemcmpFixed<35>(str1, str2); + case 36: + return MemcmpFixed<36>(str1, str2); + case 37: + return MemcmpFixed<37>(str1, str2); + case 38: + return MemcmpFixed<38>(str1, str2); + case 39: + return MemcmpFixed<39>(str1, str2); + case 40: + return MemcmpFixed<40>(str1, str2); + case 41: + return MemcmpFixed<41>(str1, str2); + case 42: + return MemcmpFixed<42>(str1, str2); + case 43: + return MemcmpFixed<43>(str1, str2); + case 44: + return MemcmpFixed<44>(str1, str2); + case 45: + return MemcmpFixed<45>(str1, str2); + case 46: + return MemcmpFixed<46>(str1, str2); + case 47: + return MemcmpFixed<47>(str1, str2); + case 48: + return MemcmpFixed<48>(str1, str2); + case 49: + return MemcmpFixed<49>(str1, str2); + case 50: + return MemcmpFixed<50>(str1, str2); + case 51: + return MemcmpFixed<51>(str1, str2); + case 52: + return MemcmpFixed<52>(str1, str2); + case 53: + return MemcmpFixed<53>(str1, str2); + case 54: + return MemcmpFixed<54>(str1, str2); + case 55: + return MemcmpFixed<55>(str1, str2); + case 56: + return MemcmpFixed<56>(str1, str2); + case 57: + return MemcmpFixed<57>(str1, str2); + case 58: + return MemcmpFixed<58>(str1, str2); + case 59: + return MemcmpFixed<59>(str1, str2); + case 60: + return MemcmpFixed<60>(str1, str2); + case 61: + return MemcmpFixed<61>(str1, str2); + case 62: + return MemcmpFixed<62>(str1, str2); + case 63: + return MemcmpFixed<63>(str1, str2); + case 64: + return MemcmpFixed<64>(str1, str2); + default: + return memcmp(str1, str2, size); + } + // LCOV_EXCL_STOP +} + +} // namespace duckdb + //===----------------------------------------------------------------------===// // DuckDB // @@ -28996,59 +27839,36 @@ struct RowDataBlock; struct SortLayout; struct GlobalSortState; +enum class SortedDataType { BLOB, PAYLOAD }; + //! Object that holds sorted rows, and an accompanying heap if there are blobs struct SortedData { public: - SortedData(const RowLayout &layout, BufferManager &buffer_manager, GlobalSortState &state); + SortedData(SortedDataType type, const RowLayout &layout, BufferManager &buffer_manager, GlobalSortState &state); //! Number of rows that this object holds idx_t Count(); - //! Pin the current block so it can be read - void Pin(); - //! Pointer to the row that is currently being read from - data_ptr_t DataPtr() const; - //! Pointer to the heap row that corresponds to the current row - data_ptr_t HeapPtr() const; - //! Advance one row - void Advance(const bool &adv); //! Initialize new block to write to void CreateBlock(); - //! Reset read indices to the given indices - void ResetIndices(idx_t block_idx_to, idx_t entry_idx_to); //! Create a slice that holds the rows between the start and end indices - unique_ptr CreateSlice(idx_t start_block_index, idx_t start_entry_index, idx_t end_block_index, - idx_t end_entry_index); + unique_ptr CreateSlice(idx_t start_block_index, idx_t end_block_index, idx_t end_entry_index); //! Unswizzles all void Unswizzle(); public: + const SortedDataType type; //! Layout of this data const RowLayout layout; //! Data and heap blocks vector data_blocks; vector heap_blocks; - //! Buffer handles to the data being currently read - unique_ptr data_handle; - unique_ptr heap_handle; - //! Read indices - idx_t block_idx; - idx_t entry_idx; //! Whether the pointers in this sorted data are swizzled bool swizzled; -private: - //! Pin fixed-size row data - void PinData(); - //! Pin the accompanying heap data (if any) - void PinHeap(); - private: //! The buffer manager BufferManager &buffer_manager; //! The global state GlobalSortState &state; - //! Pointers into the buffers being currently read - data_ptr_t data_ptr; - data_ptr_t heap_ptr; }; //! Block that holds sorted rows: radix, blob and payload data @@ -29057,21 +27877,17 @@ struct SortedBlock { SortedBlock(BufferManager &buffer_manager, GlobalSortState &gstate); //! Number of rows that this object holds idx_t Count() const; - //! The remaining number of rows to be read from this object - idx_t Remaining() const; //! Initialize this block to write data to void InitializeWrite(); //! Init new block to write to void CreateBlock(); - //! Pins radix block with given index - void PinRadix(idx_t pin_block_idx); //! Fill this sorted block by appending the blocks held by a vector of sorted blocks void AppendSortedBlocks(vector> &sorted_blocks); //! Locate the block and entry index of a row in this block, //! given an index between 0 and the total number of rows in this block void GlobalToLocalIndex(const idx_t &global_idx, idx_t &local_block_index, idx_t &local_entry_index); //! Create a slice that holds the rows between the start and end indices - unique_ptr CreateSlice(const idx_t start, const idx_t end); + unique_ptr CreateSlice(const idx_t start, const idx_t end, idx_t &entry_idx); //! Size (in bytes) of the heap of this block idx_t HeapSize() const; @@ -29081,25 +27897,59 @@ struct SortedBlock { public: //! Radix/memcmp sortable data vector radix_sorting_data; - unique_ptr radix_handle; - idx_t block_idx; - idx_t entry_idx; //! Variable sized sorting data unique_ptr blob_sorting_data; //! Payload data unique_ptr payload_data; private: - //! Buffer manager, and sorting layout constants + //! Buffer manager, global state, and sorting layout constants BufferManager &buffer_manager; GlobalSortState &state; const SortLayout &sort_layout; const RowLayout &payload_layout; }; -struct SortedDataScanner { +//! State used to scan a SortedBlock e.g. during merge sort +struct SBScanState { public: - SortedDataScanner(SortedData &sorted_data, GlobalSortState &global_sort_state); + SBScanState(BufferManager &buffer_manager, GlobalSortState &state); + + void PinRadix(idx_t block_idx_to); + void PinData(SortedData &sd); + + data_ptr_t RadixPtr() const; + data_ptr_t DataPtr(SortedData &sd) const; + data_ptr_t HeapPtr(SortedData &sd) const; + data_ptr_t BaseHeapPtr(SortedData &sd) const; + + idx_t Remaining() const; + + void SetIndices(idx_t block_idx_to, idx_t entry_idx_to); + +public: + BufferManager &buffer_manager; + const SortLayout &sort_layout; + GlobalSortState &state; + + SortedBlock *sb; + + idx_t block_idx; + idx_t entry_idx; + + unique_ptr radix_handle = nullptr; + + unique_ptr blob_sorting_data_handle = nullptr; + unique_ptr blob_sorting_heap_handle = nullptr; + + unique_ptr payload_data_handle = nullptr; + unique_ptr payload_heap_handle = nullptr; +}; + +//! Used to scan the data into DataChunks after sorting +struct PayloadScanner { +public: + PayloadScanner(SortedData &sorted_data, GlobalSortState &global_sort_state); //! Scans the next data chunk from the sorted data void Scan(DataChunk &chunk); @@ -29107,6 +27957,8 @@ struct SortedDataScanner { private: //! The sorted data being scanned SortedData &sorted_data; + //! Read state + SBScanState read_state; //! The total count of sorted_data const idx_t total_count; //! The global sort state @@ -29168,8 +28020,9 @@ struct GlobalSortState { void PrepareMergePhase(); //! Initializes the global sort state for another round of merging void InitializeMergeRound(); - //! Completes the cascaded merge sort round - void CompleteMergeRound(); + //! Completes the cascaded merge sort round. + //! Pass true if you wish to use the radix data for further comparisons. + void CompleteMergeRound(bool keep_radix_data = false); public: //! The lock for updating the order global state @@ -29247,7 +28100,7 @@ struct LocalSortState { private: //! Selection vector and addresses for scattering the data to rows - const SelectionVector &sel_ptr = FlatVector::INCREMENTAL_SELECTION_VECTOR; + const SelectionVector &sel_ptr = *FlatVector::IncrementalSelectionVector(); Vector addresses = Vector(LogicalType::POINTER); }; @@ -29258,13 +28111,29 @@ struct MergeSorter { //! Finds and merges partitions until the current cascaded merge round is finished void PerformInMergeRound(); +private: + //! The global sorting state + GlobalSortState &state; + //! The sorting and payload layouts + BufferManager &buffer_manager; + const SortLayout &sort_layout; + + //! The left and right reader + unique_ptr left; + unique_ptr right; + + //! Input and output blocks + unique_ptr left_input; + unique_ptr right_input; + SortedBlock *result; + private: //! Computes the left and right block that will be merged next (Merge Path partition) void GetNextPartition(); //! Finds the boundary of the next partition using binary search - void GetIntersection(SortedBlock &l, SortedBlock &r, const idx_t diagonal, idx_t &l_idx, idx_t &r_idx); + void GetIntersection(const idx_t diagonal, idx_t &l_idx, idx_t &r_idx); //! Compare values within SortedBlocks using a global index - int CompareUsingGlobalIndex(SortedBlock &l, SortedBlock &r, const idx_t l_idx, const idx_t r_idx); + int CompareUsingGlobalIndex(SBScanState &l, SBScanState &r, const idx_t l_idx, const idx_t r_idx); //! Finds the next partition and merges it void MergePartition(); @@ -29276,7 +28145,7 @@ struct MergeSorter { void MergeRadix(const idx_t &count, const bool left_smaller[]); //! Merges SortedData according to the 'left_smaller' array void MergeData(SortedData &result_data, SortedData &l_data, SortedData &r_data, const idx_t &count, - const bool left_smaller[], idx_t next_entry_sizes[]); + const bool left_smaller[], idx_t next_entry_sizes[], bool reset_indices); //! Merges constant size rows according to the 'left_smaller' array void MergeRows(data_ptr_t &l_ptr, idx_t &l_entry_idx, const idx_t &l_count, data_ptr_t &r_ptr, idx_t &r_entry_idx, const idx_t &r_count, RowDataBlock *target_block, data_ptr_t &target_ptr, const idx_t &entry_size, @@ -29290,18 +28159,6 @@ struct MergeSorter { idx_t &source_entry_idx, data_ptr_t &source_heap_ptr, RowDataBlock *target_data_block, data_ptr_t &target_data_ptr, RowDataBlock *target_heap_block, BufferHandle &target_heap_handle, data_ptr_t &target_heap_ptr, idx_t &copied, const idx_t &count); - -private: - //! The global sorting state - GlobalSortState &state; - //! The sorting and payload layouts - BufferManager &buffer_manager; - const SortLayout &sort_layout; - - //! The left, right and result blocks of the current partition - unique_ptr left_block; - unique_ptr right_block; - SortedBlock *result; }; } // namespace duckdb @@ -29330,17 +28187,16 @@ bool Comparators::TieIsBreakable(const idx_t &col_idx, const data_ptr_t row_ptr, return true; } -int Comparators::CompareTuple(const SortedBlock &left, const SortedBlock &right, const data_ptr_t &l_ptr, +int Comparators::CompareTuple(const SBScanState &left, const SBScanState &right, const data_ptr_t &l_ptr, const data_ptr_t &r_ptr, const SortLayout &sort_layout, const bool &external_sort) { // Compare the sorting columns one by one int comp_res = 0; data_ptr_t l_ptr_offset = l_ptr; data_ptr_t r_ptr_offset = r_ptr; for (idx_t col_idx = 0; col_idx < sort_layout.column_count; col_idx++) { - comp_res = memcmp(l_ptr_offset, r_ptr_offset, sort_layout.column_sizes[col_idx]); + comp_res = FastMemcmp(l_ptr_offset, r_ptr_offset, sort_layout.column_sizes[col_idx]); if (comp_res == 0 && !sort_layout.constant_size[col_idx]) { - comp_res = - BreakBlobTie(col_idx, *left.blob_sorting_data, *right.blob_sorting_data, sort_layout, external_sort); + comp_res = BreakBlobTie(col_idx, left, right, sort_layout, external_sort); } if (comp_res != 0) { break; @@ -29366,11 +28222,11 @@ int Comparators::CompareVal(const data_ptr_t l_ptr, const data_ptr_t r_ptr, cons } } -int Comparators::BreakBlobTie(const idx_t &tie_col, const SortedData &left, const SortedData &right, +int Comparators::BreakBlobTie(const idx_t &tie_col, const SBScanState &left, const SBScanState &right, const SortLayout &sort_layout, const bool &external) { const idx_t &col_idx = sort_layout.sorting_to_blob_col.at(tie_col); - data_ptr_t l_data_ptr = left.DataPtr(); - data_ptr_t r_data_ptr = right.DataPtr(); + data_ptr_t l_data_ptr = left.DataPtr(*left.sb->blob_sorting_data); + data_ptr_t r_data_ptr = right.DataPtr(*right.sb->blob_sorting_data); if (!TieIsBreakable(col_idx, l_data_ptr, sort_layout.blob_layout)) { // Quick check to see if ties can be broken return 0; @@ -29381,12 +28237,12 @@ int Comparators::BreakBlobTie(const idx_t &tie_col, const SortedData &left, cons r_data_ptr += tie_col_offset; // Do the comparison const int order = sort_layout.order_types[tie_col] == OrderType::DESCENDING ? -1 : 1; - const auto &type = left.layout.GetTypes()[col_idx]; + const auto &type = sort_layout.blob_layout.GetTypes()[col_idx]; int result; if (external) { // Store heap pointers - data_ptr_t l_heap_ptr = left.HeapPtr(); - data_ptr_t r_heap_ptr = right.HeapPtr(); + data_ptr_t l_heap_ptr = left.HeapPtr(*left.sb->blob_sorting_data); + data_ptr_t r_heap_ptr = right.HeapPtr(*right.sb->blob_sorting_data); // Unswizzle offset to pointer UnswizzleSingleValue(l_data_ptr, l_heap_ptr, type); UnswizzleSingleValue(r_data_ptr, r_heap_ptr, type); @@ -29666,6 +28522,7 @@ void Comparators::SwizzleSingleValue(data_ptr_t data_ptr, const data_ptr_t &heap + namespace duckdb { MergeSorter::MergeSorter(GlobalSortState &state, BufferManager &buffer_manager) @@ -29686,21 +28543,23 @@ void MergeSorter::PerformInMergeRound() { } void MergeSorter::MergePartition() { - auto &left = *left_block; - auto &right = *right_block; + auto &left_block = *left->sb; + auto &right_block = *right->sb; #ifdef DEBUG - D_ASSERT(left.radix_sorting_data.size() == left.payload_data->data_blocks.size()); - D_ASSERT(right.radix_sorting_data.size() == right.payload_data->data_blocks.size()); + D_ASSERT(left_block.radix_sorting_data.size() == left_block.payload_data->data_blocks.size()); + D_ASSERT(right_block.radix_sorting_data.size() == right_block.payload_data->data_blocks.size()); if (!state.payload_layout.AllConstant() && state.external) { - D_ASSERT(left.payload_data->data_blocks.size() == left.payload_data->heap_blocks.size()); - D_ASSERT(right.payload_data->data_blocks.size() == right.payload_data->heap_blocks.size()); + D_ASSERT(left_block.payload_data->data_blocks.size() == left_block.payload_data->heap_blocks.size()); + D_ASSERT(right_block.payload_data->data_blocks.size() == right_block.payload_data->heap_blocks.size()); } if (!sort_layout.all_constant) { - D_ASSERT(left.radix_sorting_data.size() == left.blob_sorting_data->data_blocks.size()); - D_ASSERT(right.radix_sorting_data.size() == right.blob_sorting_data->data_blocks.size()); + D_ASSERT(left_block.radix_sorting_data.size() == left_block.blob_sorting_data->data_blocks.size()); + D_ASSERT(right_block.radix_sorting_data.size() == right_block.blob_sorting_data->data_blocks.size()); if (state.external) { - D_ASSERT(left.blob_sorting_data->data_blocks.size() == left.blob_sorting_data->heap_blocks.size()); - D_ASSERT(right.blob_sorting_data->data_blocks.size() == right.blob_sorting_data->heap_blocks.size()); + D_ASSERT(left_block.blob_sorting_data->data_blocks.size() == + left_block.blob_sorting_data->heap_blocks.size()); + D_ASSERT(right_block.blob_sorting_data->data_blocks.size() == + right_block.blob_sorting_data->heap_blocks.size()); } } #endif @@ -29712,12 +28571,12 @@ void MergeSorter::MergePartition() { idx_t next_entry_sizes[STANDARD_VECTOR_SIZE]; // Merge loop #ifdef DEBUG - auto l_count = left.Remaining(); - auto r_count = right.Remaining(); + auto l_count = left->Remaining(); + auto r_count = right->Remaining(); #endif while (true) { - auto l_remaining = left.Remaining(); - auto r_remaining = right.Remaining(); + auto l_remaining = left->Remaining(); + auto r_remaining = right->Remaining(); if (l_remaining + r_remaining == 0) { // Done break; @@ -29730,17 +28589,12 @@ void MergeSorter::MergePartition() { // Actually merge the data (radix, blob, and payload) MergeRadix(next, left_smaller); if (!sort_layout.all_constant) { - MergeData(*result->blob_sorting_data, *left.blob_sorting_data, *right.blob_sorting_data, next, left_smaller, - next_entry_sizes); - D_ASSERT(left.block_idx == left.blob_sorting_data->block_idx && - left.entry_idx == left.blob_sorting_data->entry_idx); - D_ASSERT(right.block_idx == right.blob_sorting_data->block_idx && - right.entry_idx == right.blob_sorting_data->entry_idx); + MergeData(*result->blob_sorting_data, *left_block.blob_sorting_data, *right_block.blob_sorting_data, next, + left_smaller, next_entry_sizes, true); D_ASSERT(result->radix_sorting_data.size() == result->blob_sorting_data->data_blocks.size()); } - MergeData(*result->payload_data, *left.payload_data, *right.payload_data, next, left_smaller, next_entry_sizes); - D_ASSERT(left.block_idx == left.payload_data->block_idx && left.entry_idx == left.payload_data->entry_idx); - D_ASSERT(right.block_idx == right.payload_data->block_idx && right.entry_idx == right.payload_data->entry_idx); + MergeData(*result->payload_data, *left_block.payload_data, *right_block.payload_data, next, left_smaller, + next_entry_sizes, false); D_ASSERT(result->radix_sorting_data.size() == result->payload_data->data_blocks.size()); } #ifdef DEBUG @@ -29753,34 +28607,39 @@ void MergeSorter::GetNextPartition() { state.sorted_blocks_temp[state.pair_idx].push_back(make_unique(buffer_manager, state)); result = state.sorted_blocks_temp[state.pair_idx].back().get(); // Determine which blocks must be merged - auto &left = *state.sorted_blocks[state.pair_idx * 2]; - auto &right = *state.sorted_blocks[state.pair_idx * 2 + 1]; - const idx_t l_count = left.Count(); - const idx_t r_count = right.Count(); + auto &left_block = *state.sorted_blocks[state.pair_idx * 2]; + auto &right_block = *state.sorted_blocks[state.pair_idx * 2 + 1]; + const idx_t l_count = left_block.Count(); + const idx_t r_count = right_block.Count(); + // Initialize left and right reader + left = make_unique(buffer_manager, state); + right = make_unique(buffer_manager, state); // Compute the work that this thread must do using Merge Path idx_t l_end; idx_t r_end; if (state.l_start + state.r_start + state.block_capacity < l_count + r_count) { + left->sb = state.sorted_blocks[state.pair_idx * 2].get(); + right->sb = state.sorted_blocks[state.pair_idx * 2 + 1].get(); const idx_t intersection = state.l_start + state.r_start + state.block_capacity; - GetIntersection(left, right, intersection, l_end, r_end); + GetIntersection(intersection, l_end, r_end); D_ASSERT(l_end <= l_count); D_ASSERT(r_end <= r_count); D_ASSERT(intersection == l_end + r_end); - // Unpin after finding the intersection - if (!sort_layout.blob_layout.AllConstant()) { - left.blob_sorting_data->ResetIndices(0, 0); - right.blob_sorting_data->ResetIndices(0, 0); - } } else { l_end = l_count; r_end = r_count; } // Create slices of the data that this thread must merge - left_block = left.CreateSlice(state.l_start, l_end); - right_block = right.CreateSlice(state.r_start, r_end); - // Update global state + left->SetIndices(0, 0); + right->SetIndices(0, 0); + left_input = left_block.CreateSlice(state.l_start, l_end, left->entry_idx); + right_input = right_block.CreateSlice(state.r_start, r_end, right->entry_idx); + left->sb = left_input.get(); + right->sb = right_input.get(); state.l_start = l_end; state.r_start = r_end; + D_ASSERT(left->Remaining() + right->Remaining() == state.block_capacity || (l_end == l_count && r_end == r_count)); + // Update global state if (state.l_start == l_count && state.r_start == r_count) { // Delete references to previous pair state.sorted_blocks[state.pair_idx * 2] = nullptr; @@ -29792,9 +28651,9 @@ void MergeSorter::GetNextPartition() { } } -int MergeSorter::CompareUsingGlobalIndex(SortedBlock &l, SortedBlock &r, const idx_t l_idx, const idx_t r_idx) { - D_ASSERT(l_idx < l.Count()); - D_ASSERT(r_idx < r.Count()); +int MergeSorter::CompareUsingGlobalIndex(SBScanState &l, SBScanState &r, const idx_t l_idx, const idx_t r_idx) { + D_ASSERT(l_idx < l.sb->Count()); + D_ASSERT(r_idx < r.sb->Count()); // Easy comparison using the previous result (intersections must increase monotonically) if (l_idx < state.l_start) { @@ -29804,37 +28663,28 @@ int MergeSorter::CompareUsingGlobalIndex(SortedBlock &l, SortedBlock &r, const i return 1; } - idx_t l_block_idx; - idx_t l_entry_idx; - l.GlobalToLocalIndex(l_idx, l_block_idx, l_entry_idx); + l.sb->GlobalToLocalIndex(l_idx, l.block_idx, l.entry_idx); + r.sb->GlobalToLocalIndex(r_idx, r.block_idx, r.entry_idx); - idx_t r_block_idx; - idx_t r_entry_idx; - r.GlobalToLocalIndex(r_idx, r_block_idx, r_entry_idx); - - l.PinRadix(l_block_idx); - r.PinRadix(r_block_idx); - data_ptr_t l_ptr = l.radix_handle->Ptr() + l_entry_idx * sort_layout.entry_size; - data_ptr_t r_ptr = r.radix_handle->Ptr() + r_entry_idx * sort_layout.entry_size; + l.PinRadix(l.block_idx); + r.PinRadix(r.block_idx); + data_ptr_t l_ptr = l.radix_handle->Ptr() + l.entry_idx * sort_layout.entry_size; + data_ptr_t r_ptr = r.radix_handle->Ptr() + r.entry_idx * sort_layout.entry_size; int comp_res; if (sort_layout.all_constant) { - comp_res = memcmp(l_ptr, r_ptr, sort_layout.comparison_size); + comp_res = FastMemcmp(l_ptr, r_ptr, sort_layout.comparison_size); } else { - l.blob_sorting_data->block_idx = l_block_idx; - l.blob_sorting_data->entry_idx = l_entry_idx; - l.blob_sorting_data->Pin(); - r.blob_sorting_data->block_idx = r_block_idx; - r.blob_sorting_data->entry_idx = r_entry_idx; - r.blob_sorting_data->Pin(); + l.PinData(*l.sb->blob_sorting_data); + r.PinData(*r.sb->blob_sorting_data); comp_res = Comparators::CompareTuple(l, r, l_ptr, r_ptr, sort_layout, state.external); } return comp_res; } -void MergeSorter::GetIntersection(SortedBlock &l, SortedBlock &r, const idx_t diagonal, idx_t &l_idx, idx_t &r_idx) { - const idx_t l_count = l.Count(); - const idx_t r_count = r.Count(); +void MergeSorter::GetIntersection(const idx_t diagonal, idx_t &l_idx, idx_t &r_idx) { + const idx_t l_count = left->sb->Count(); + const idx_t r_count = right->sb->Count(); // Cover some edge cases // Code coverage off because these edge cases cannot happen unless other code changes // Edge cases have been tested extensively while developing Merge Path in a script @@ -29864,16 +28714,16 @@ void MergeSorter::GetIntersection(SortedBlock &l, SortedBlock &r, const idx_t di const idx_t search_space = diagonal > MaxValue(l_count, r_count) ? l_count + r_count - diagonal : MinValue(diagonal, MinValue(l_count, r_count)); // Double binary search - idx_t left = 0; - idx_t right = search_space - 1; + idx_t li = 0; + idx_t ri = search_space - 1; idx_t middle; int comp_res; - while (left <= right) { - middle = (left + right) / 2; + while (li <= ri) { + middle = (li + ri) / 2; l_idx = l_offset - middle; r_idx = r_offset + middle; if (l_idx == l_count || r_idx == 0) { - comp_res = CompareUsingGlobalIndex(l, r, l_idx - 1, r_idx); + comp_res = CompareUsingGlobalIndex(*left, *right, l_idx - 1, r_idx); if (comp_res > 0) { l_idx--; r_idx++; @@ -29890,15 +28740,15 @@ void MergeSorter::GetIntersection(SortedBlock &l, SortedBlock &r, const idx_t di break; } } - comp_res = CompareUsingGlobalIndex(l, r, l_idx, r_idx); + comp_res = CompareUsingGlobalIndex(*left, *right, l_idx, r_idx); if (comp_res > 0) { - left = middle + 1; + li = middle + 1; } else { - right = middle - 1; + ri = middle - 1; } } - int l_r_min1 = CompareUsingGlobalIndex(l, r, l_idx, r_idx - 1); - int l_min1_r = CompareUsingGlobalIndex(l, r, l_idx - 1, r_idx); + int l_r_min1 = CompareUsingGlobalIndex(*left, *right, l_idx, r_idx - 1); + int l_min1_r = CompareUsingGlobalIndex(*left, *right, l_idx - 1, r_idx); if (l_r_min1 > 0 && l_min1_r < 0) { return; } else if (l_r_min1 > 0) { @@ -29911,13 +28761,15 @@ void MergeSorter::GetIntersection(SortedBlock &l, SortedBlock &r, const idx_t di } void MergeSorter::ComputeMerge(const idx_t &count, bool left_smaller[]) { - auto &left = *left_block; - auto &right = *right_block; - // Store indices to restore after computing the merge - idx_t l_block_idx = left.block_idx; - idx_t r_block_idx = right.block_idx; - idx_t l_entry_idx = left.entry_idx; - idx_t r_entry_idx = right.entry_idx; + auto &l = *left; + auto &r = *right; + auto &l_sorted_block = *l.sb; + auto &r_sorted_block = *r.sb; + // Save indices to restore afterwards + idx_t l_block_idx_before = l.block_idx; + idx_t l_entry_idx_before = l.entry_idx; + idx_t r_block_idx_before = r.block_idx; + idx_t r_entry_idx_before = r.entry_idx; // Data pointers for both sides data_ptr_t l_radix_ptr; data_ptr_t r_radix_ptr; @@ -29925,91 +28777,84 @@ void MergeSorter::ComputeMerge(const idx_t &count, bool left_smaller[]) { idx_t compared = 0; while (compared < count) { // Move to the next block (if needed) - if (l_block_idx < left.radix_sorting_data.size() && l_entry_idx == left.radix_sorting_data[l_block_idx].count) { - l_block_idx++; - l_entry_idx = 0; - if (!sort_layout.all_constant) { - left.blob_sorting_data->block_idx = l_block_idx; - left.blob_sorting_data->entry_idx = l_entry_idx; - } - } - if (r_block_idx < right.radix_sorting_data.size() && - r_entry_idx == right.radix_sorting_data[r_block_idx].count) { - r_block_idx++; - r_entry_idx = 0; - if (!sort_layout.all_constant) { - right.blob_sorting_data->block_idx = r_block_idx; - right.blob_sorting_data->entry_idx = r_entry_idx; - } - } - const bool l_done = l_block_idx == left.radix_sorting_data.size(); - const bool r_done = r_block_idx == right.radix_sorting_data.size(); + if (l.block_idx < l_sorted_block.radix_sorting_data.size() && + l.entry_idx == l_sorted_block.radix_sorting_data[l.block_idx].count) { + l.block_idx++; + l.entry_idx = 0; + } + if (r.block_idx < r_sorted_block.radix_sorting_data.size() && + r.entry_idx == r_sorted_block.radix_sorting_data[r.block_idx].count) { + r.block_idx++; + r.entry_idx = 0; + } + const bool l_done = l.block_idx == l_sorted_block.radix_sorting_data.size(); + const bool r_done = r.block_idx == r_sorted_block.radix_sorting_data.size(); if (l_done || r_done) { // One of the sides is exhausted, no need to compare break; } // Pin the radix sorting data if (!l_done) { - left.PinRadix(l_block_idx); - l_radix_ptr = left.radix_handle->Ptr() + l_entry_idx * sort_layout.entry_size; + left->PinRadix(l.block_idx); + l_radix_ptr = left->RadixPtr(); } if (!r_done) { - right.PinRadix(r_block_idx); - r_radix_ptr = right.radix_handle->Ptr() + r_entry_idx * sort_layout.entry_size; + right->PinRadix(r.block_idx); + r_radix_ptr = right->RadixPtr(); } - const idx_t &l_count = !l_done ? left.radix_sorting_data[l_block_idx].count : 0; - const idx_t &r_count = !r_done ? right.radix_sorting_data[r_block_idx].count : 0; + const idx_t &l_count = !l_done ? l_sorted_block.radix_sorting_data[l.block_idx].count : 0; + const idx_t &r_count = !r_done ? r_sorted_block.radix_sorting_data[r.block_idx].count : 0; // Compute the merge if (sort_layout.all_constant) { // All sorting columns are constant size - for (; compared < count && l_entry_idx < l_count && r_entry_idx < r_count; compared++) { - left_smaller[compared] = memcmp(l_radix_ptr, r_radix_ptr, sort_layout.comparison_size) < 0; + for (; compared < count && l.entry_idx < l_count && r.entry_idx < r_count; compared++) { + left_smaller[compared] = FastMemcmp(l_radix_ptr, r_radix_ptr, sort_layout.comparison_size) < 0; const bool &l_smaller = left_smaller[compared]; const bool r_smaller = !l_smaller; // Use comparison bool (0 or 1) to increment entries and pointers - l_entry_idx += l_smaller; - r_entry_idx += r_smaller; + l.entry_idx += l_smaller; + r.entry_idx += r_smaller; l_radix_ptr += l_smaller * sort_layout.entry_size; r_radix_ptr += r_smaller * sort_layout.entry_size; } } else { // Pin the blob data if (!l_done) { - left.blob_sorting_data->Pin(); + left->PinData(*l_sorted_block.blob_sorting_data); } if (!r_done) { - right.blob_sorting_data->Pin(); + right->PinData(*r_sorted_block.blob_sorting_data); } // Merge with variable size sorting columns - for (; compared < count && l_entry_idx < l_count && r_entry_idx < r_count; compared++) { - D_ASSERT(l_block_idx == left.blob_sorting_data->block_idx && - l_entry_idx == left.blob_sorting_data->entry_idx); - D_ASSERT(r_block_idx == right.blob_sorting_data->block_idx && - r_entry_idx == right.blob_sorting_data->entry_idx); + for (; compared < count && l.entry_idx < l_count && r.entry_idx < r_count; compared++) { left_smaller[compared] = - Comparators::CompareTuple(left, right, l_radix_ptr, r_radix_ptr, sort_layout, state.external) < 0; + Comparators::CompareTuple(*left, *right, l_radix_ptr, r_radix_ptr, sort_layout, state.external) < 0; const bool &l_smaller = left_smaller[compared]; const bool r_smaller = !l_smaller; // Use comparison bool (0 or 1) to increment entries and pointers - l_entry_idx += l_smaller; - r_entry_idx += r_smaller; + l.entry_idx += l_smaller; + r.entry_idx += r_smaller; l_radix_ptr += l_smaller * sort_layout.entry_size; r_radix_ptr += r_smaller * sort_layout.entry_size; - left.blob_sorting_data->Advance(l_smaller); - right.blob_sorting_data->Advance(r_smaller); } } } - // Reset block indices before the actual merge - if (!sort_layout.all_constant) { - left.blob_sorting_data->ResetIndices(left.block_idx, left.entry_idx); - right.blob_sorting_data->ResetIndices(right.block_idx, right.entry_idx); - } + // Reset block indices + left->SetIndices(l_block_idx_before, l_entry_idx_before); + right->SetIndices(r_block_idx_before, r_entry_idx_before); } void MergeSorter::MergeRadix(const idx_t &count, const bool left_smaller[]) { - auto &left = *left_block; - auto &right = *right_block; + auto &l = *left; + auto &r = *right; + // Save indices to restore afterwards + idx_t l_block_idx_before = l.block_idx; + idx_t l_entry_idx_before = l.entry_idx; + idx_t r_block_idx_before = r.block_idx; + idx_t r_entry_idx_before = r.entry_idx; + + auto &l_blocks = l.sb->radix_sorting_data; + auto &r_blocks = r.sb->radix_sorting_data; RowDataBlock *l_block; RowDataBlock *r_block; @@ -30023,54 +28868,63 @@ void MergeSorter::MergeRadix(const idx_t &count, const bool left_smaller[]) { idx_t copied = 0; while (copied < count) { // Move to the next block (if needed) - if (left.block_idx < left.radix_sorting_data.size() && - left.entry_idx == left.radix_sorting_data[left.block_idx].count) { + if (l.block_idx < l_blocks.size() && l.entry_idx == l_blocks[l.block_idx].count) { // Delete reference to previous block - left.radix_sorting_data[left.block_idx].block = nullptr; + l_blocks[l.block_idx].block = nullptr; // Advance block - left.block_idx++; - left.entry_idx = 0; + l.block_idx++; + l.entry_idx = 0; } - if (right.block_idx < right.radix_sorting_data.size() && - right.entry_idx == right.radix_sorting_data[right.block_idx].count) { + if (r.block_idx < r_blocks.size() && r.entry_idx == r_blocks[r.block_idx].count) { // Delete reference to previous block - right.radix_sorting_data[right.block_idx].block = nullptr; + r_blocks[r.block_idx].block = nullptr; // Advance block - right.block_idx++; - right.entry_idx = 0; + r.block_idx++; + r.entry_idx = 0; } - const bool l_done = left.block_idx == left.radix_sorting_data.size(); - const bool r_done = right.block_idx == right.radix_sorting_data.size(); + 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 if (!l_done) { - l_block = &left.radix_sorting_data[left.block_idx]; - left.PinRadix(left.block_idx); - l_ptr = left.radix_handle->Ptr() + left.entry_idx * sort_layout.entry_size; + l_block = &l_blocks[l.block_idx]; + left->PinRadix(l.block_idx); + l_ptr = l.RadixPtr(); } if (!r_done) { - r_block = &right.radix_sorting_data[right.block_idx]; - right.PinRadix(right.block_idx); - r_ptr = right.radix_handle->Ptr() + right.entry_idx * sort_layout.entry_size; + r_block = &r_blocks[r.block_idx]; + r.PinRadix(r.block_idx); + r_ptr = r.RadixPtr(); } 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 - MergeRows(l_ptr, left.entry_idx, l_count, r_ptr, right.entry_idx, r_count, result_block, result_ptr, + MergeRows(l_ptr, l.entry_idx, l_count, r_ptr, r.entry_idx, r_count, result_block, result_ptr, sort_layout.entry_size, left_smaller, copied, count); } else if (r_done) { // Right side is exhausted - FlushRows(l_ptr, left.entry_idx, l_count, result_block, result_ptr, sort_layout.entry_size, copied, count); + FlushRows(l_ptr, l.entry_idx, l_count, result_block, result_ptr, sort_layout.entry_size, copied, count); } else { // Left side is exhausted - FlushRows(r_ptr, right.entry_idx, r_count, result_block, result_ptr, sort_layout.entry_size, copied, count); + FlushRows(r_ptr, r.entry_idx, r_count, result_block, result_ptr, sort_layout.entry_size, copied, count); } } + // Reset block indices + left->SetIndices(l_block_idx_before, l_entry_idx_before); + right->SetIndices(r_block_idx_before, r_entry_idx_before); } void MergeSorter::MergeData(SortedData &result_data, SortedData &l_data, SortedData &r_data, const idx_t &count, - const bool left_smaller[], idx_t next_entry_sizes[]) { + const bool left_smaller[], idx_t next_entry_sizes[], bool reset_indices) { + auto &l = *left; + auto &r = *right; + // Save indices to restore afterwards + idx_t l_block_idx_before = l.block_idx; + idx_t l_entry_idx_before = l.entry_idx; + idx_t r_block_idx_before = r.block_idx; + idx_t r_entry_idx_before = r.entry_idx; + const auto &layout = result_data.layout; const idx_t row_width = layout.GetRowWidth(); const idx_t heap_pointer_offset = layout.GetHeapPointerOffset(); @@ -30099,76 +28953,70 @@ void MergeSorter::MergeData(SortedData &result_data, SortedData &l_data, SortedD idx_t copied = 0; while (copied < count) { // Move to new data blocks (if needed) - if (l_data.block_idx < l_data.data_blocks.size() && - l_data.entry_idx == l_data.data_blocks[l_data.block_idx].count) { + if (l.block_idx < l_data.data_blocks.size() && l.entry_idx == l_data.data_blocks[l.block_idx].count) { // Delete reference to previous block - l_data.data_blocks[l_data.block_idx].block = nullptr; + l_data.data_blocks[l.block_idx].block = nullptr; if (!layout.AllConstant() && state.external) { - l_data.heap_blocks[l_data.block_idx].block = nullptr; + l_data.heap_blocks[l.block_idx].block = nullptr; } // Advance block - l_data.block_idx++; - l_data.entry_idx = 0; + l.block_idx++; + l.entry_idx = 0; } - if (r_data.block_idx < r_data.data_blocks.size() && - r_data.entry_idx == r_data.data_blocks[r_data.block_idx].count) { + if (r.block_idx < r_data.data_blocks.size() && r.entry_idx == r_data.data_blocks[r.block_idx].count) { // Delete reference to previous block - r_data.data_blocks[r_data.block_idx].block = nullptr; + r_data.data_blocks[r.block_idx].block = nullptr; if (!layout.AllConstant() && state.external) { - r_data.heap_blocks[r_data.block_idx].block = nullptr; + r_data.heap_blocks[r.block_idx].block = nullptr; } // Advance block - r_data.block_idx++; - r_data.entry_idx = 0; + r.block_idx++; + r.entry_idx = 0; } - const bool l_done = l_data.block_idx == l_data.data_blocks.size(); - const bool r_done = r_data.block_idx == r_data.data_blocks.size(); + const bool l_done = l.block_idx == l_data.data_blocks.size(); + const bool r_done = r.block_idx == r_data.data_blocks.size(); // Pin the row data blocks if (!l_done) { - l_data.Pin(); - l_ptr = l_data.data_handle->Ptr() + l_data.entry_idx * row_width; + l.PinData(l_data); + l_ptr = l.DataPtr(l_data); } if (!r_done) { - r_data.Pin(); - r_ptr = r_data.data_handle->Ptr() + r_data.entry_idx * row_width; + r.PinData(r_data); + r_ptr = r.DataPtr(r_data); } - const idx_t &l_count = !l_done ? l_data.data_blocks[l_data.block_idx].count : 0; - const idx_t &r_count = !r_done ? r_data.data_blocks[r_data.block_idx].count : 0; + const idx_t &l_count = !l_done ? l_data.data_blocks[l.block_idx].count : 0; + const idx_t &r_count = !r_done ? r_data.data_blocks[r.block_idx].count : 0; // Perform the merge if (layout.AllConstant() || !state.external) { // If all constant size, or if we are doing an in-memory sort, we do not need to touch the heap if (!l_done && !r_done) { // Both sides have data - merge - MergeRows(l_ptr, l_data.entry_idx, l_count, r_ptr, r_data.entry_idx, r_count, result_data_block, - result_data_ptr, row_width, left_smaller, copied, count); + MergeRows(l_ptr, l.entry_idx, l_count, r_ptr, r.entry_idx, r_count, result_data_block, result_data_ptr, + row_width, left_smaller, copied, count); } else if (r_done) { // Right side is exhausted - FlushRows(l_ptr, l_data.entry_idx, l_count, result_data_block, result_data_ptr, row_width, copied, - count); + FlushRows(l_ptr, l.entry_idx, l_count, result_data_block, result_data_ptr, row_width, copied, count); } else { // Left side is exhausted - FlushRows(r_ptr, r_data.entry_idx, r_count, result_data_block, result_data_ptr, row_width, copied, - count); + FlushRows(r_ptr, r.entry_idx, r_count, result_data_block, result_data_ptr, row_width, copied, count); } } else { // External sorting with variable size data. Pin the heap blocks too if (!l_done) { - l_heap_ptr = l_data.heap_handle->Ptr() + Load(l_ptr + heap_pointer_offset); - D_ASSERT(l_heap_ptr - l_data.heap_handle->Ptr() >= 0); - D_ASSERT((idx_t)(l_heap_ptr - l_data.heap_handle->Ptr()) < - l_data.heap_blocks[l_data.block_idx].byte_offset); + l_heap_ptr = l.BaseHeapPtr(l_data) + Load(l_ptr + heap_pointer_offset); + D_ASSERT(l_heap_ptr - l.BaseHeapPtr(l_data) >= 0); + D_ASSERT((idx_t)(l_heap_ptr - l.BaseHeapPtr(l_data)) < l_data.heap_blocks[l.block_idx].byte_offset); } if (!r_done) { - r_heap_ptr = r_data.heap_handle->Ptr() + Load(r_ptr + heap_pointer_offset); - D_ASSERT(r_heap_ptr - r_data.heap_handle->Ptr() >= 0); - D_ASSERT((idx_t)(r_heap_ptr - r_data.heap_handle->Ptr()) < - r_data.heap_blocks[r_data.block_idx].byte_offset); + r_heap_ptr = r.BaseHeapPtr(r_data) + Load(r_ptr + heap_pointer_offset); + D_ASSERT(r_heap_ptr - r.BaseHeapPtr(r_data) >= 0); + D_ASSERT((idx_t)(r_heap_ptr - r.BaseHeapPtr(r_data)) < r_data.heap_blocks[r.block_idx].byte_offset); } // Both the row and heap data need to be dealt with if (!l_done && !r_done) { // Both sides have data - merge - idx_t l_idx_copy = l_data.entry_idx; - idx_t r_idx_copy = r_data.entry_idx; + idx_t l_idx_copy = l.entry_idx; + idx_t r_idx_copy = r.entry_idx; data_ptr_t result_data_ptr_copy = result_data_ptr; idx_t copied_copy = copied; // Merge row data @@ -30190,10 +29038,10 @@ void MergeSorter::MergeData(SortedData &result_data, SortedData &l_data, SortedD entry_size = l_smaller * Load(l_heap_ptr_copy) + r_smaller * Load(r_heap_ptr_copy); D_ASSERT(entry_size >= sizeof(uint32_t)); - D_ASSERT(l_heap_ptr_copy - l_data.heap_handle->Ptr() + l_smaller * entry_size <= - l_data.heap_blocks[l_data.block_idx].byte_offset); - D_ASSERT(r_heap_ptr_copy - r_data.heap_handle->Ptr() + r_smaller * entry_size <= - r_data.heap_blocks[r_data.block_idx].byte_offset); + D_ASSERT(l_heap_ptr_copy - l.BaseHeapPtr(l_data) + l_smaller * entry_size <= + l_data.heap_blocks[l.block_idx].byte_offset); + D_ASSERT(r_heap_ptr_copy - r.BaseHeapPtr(r_data) + r_smaller * entry_size <= + r_data.heap_blocks[r.block_idx].byte_offset); l_heap_ptr_copy += l_smaller * entry_size; r_heap_ptr_copy += r_smaller * entry_size; copy_bytes += entry_size; @@ -30211,14 +29059,14 @@ void MergeSorter::MergeData(SortedData &result_data, SortedData &l_data, SortedD const bool &l_smaller = left_smaller[copied + i]; const bool r_smaller = !l_smaller; const auto &entry_size = next_entry_sizes[copied + i]; - memcpy(result_heap_ptr, l_heap_ptr, l_smaller * entry_size); - memcpy(result_heap_ptr, r_heap_ptr, r_smaller * entry_size); + memcpy(result_heap_ptr, (data_ptr_t)(l_smaller * (idx_t)l_heap_ptr + r_smaller * (idx_t)r_heap_ptr), + entry_size); D_ASSERT(Load(result_heap_ptr) == entry_size); result_heap_ptr += entry_size; l_heap_ptr += l_smaller * entry_size; r_heap_ptr += r_smaller * entry_size; - l_data.entry_idx += l_smaller; - r_data.entry_idx += r_smaller; + l.entry_idx += l_smaller; + r.entry_idx += r_smaller; } // Update result indices and pointers result_heap_block->count += merged; @@ -30226,16 +29074,20 @@ void MergeSorter::MergeData(SortedData &result_data, SortedData &l_data, SortedD copied += merged; } else if (r_done) { // Right side is exhausted - flush left - FlushBlobs(layout, l_count, l_ptr, l_data.entry_idx, l_heap_ptr, result_data_block, result_data_ptr, + FlushBlobs(layout, l_count, l_ptr, l.entry_idx, l_heap_ptr, result_data_block, result_data_ptr, result_heap_block, *result_heap_handle, result_heap_ptr, copied, count); } else { // Left side is exhausted - flush right - FlushBlobs(layout, r_count, r_ptr, r_data.entry_idx, r_heap_ptr, result_data_block, result_data_ptr, + FlushBlobs(layout, r_count, r_ptr, r.entry_idx, r_heap_ptr, result_data_block, result_data_ptr, result_heap_block, *result_heap_handle, result_heap_ptr, copied, count); } D_ASSERT(result_data_block->count == result_heap_block->count); } } + if (reset_indices) { + left->SetIndices(l_block_idx_before, l_entry_idx_before); + right->SetIndices(r_block_idx_before, r_entry_idx_before); + } } void MergeSorter::MergeRows(data_ptr_t &l_ptr, idx_t &l_entry_idx, const idx_t &l_count, data_ptr_t &r_ptr, @@ -30248,8 +29100,7 @@ void MergeSorter::MergeRows(data_ptr_t &l_ptr, idx_t &l_entry_idx, const idx_t & const bool &l_smaller = left_smaller[copied + i]; const bool r_smaller = !l_smaller; // Use comparison bool (0 or 1) to copy an entry from either side - memcpy(target_ptr, l_ptr, l_smaller * entry_size); - memcpy(target_ptr, r_ptr, r_smaller * entry_size); + FastMemcpy(target_ptr, (data_ptr_t)(l_smaller * (idx_t)l_ptr + r_smaller * (idx_t)r_ptr), entry_size); target_ptr += entry_size; // Use the comparison bool to increment entries and pointers l_entry_idx += l_smaller; @@ -30330,6 +29181,7 @@ void MergeSorter::FlushBlobs(const RowLayout &layout, const idx_t &source_count, + namespace duckdb { //! Calls std::sort on strings that are tied by their prefix after the radix sort @@ -30369,7 +29221,7 @@ static void SortTiedBlobs(BufferManager &buffer_manager, const data_ptr_t datapt buffer_manager.Allocate(MaxValue((end - start) * sort_layout.entry_size, (idx_t)Storage::BLOCK_SIZE)); data_ptr_t temp_ptr = temp_block->Ptr(); for (idx_t i = 0; i < end - start; i++) { - memcpy(temp_ptr, entry_ptrs[i], sort_layout.entry_size); + FastMemcpy(temp_ptr, entry_ptrs[i], sort_layout.entry_size); temp_ptr += sort_layout.entry_size; } memcpy(dataptr + start * sort_layout.entry_size, temp_block->Ptr(), (end - start) * sort_layout.entry_size); @@ -30429,7 +29281,7 @@ static void ComputeTies(data_ptr_t dataptr, const idx_t &count, const idx_t &col // Align dataptr dataptr += col_offset; for (idx_t i = 0; i < count - 1; i++) { - ties[i] = ties[i] && memcmp(dataptr, dataptr + sort_layout.entry_size, tie_size) == 0; + ties[i] = ties[i] && FastMemcmp(dataptr, dataptr + sort_layout.entry_size, tie_size) == 0; dataptr += sort_layout.entry_size; } } @@ -30467,7 +29319,7 @@ void RadixSortLSD(BufferManager &buffer_manager, const data_ptr_t &dataptr, cons data_ptr_t row_ptr = source_ptr + (count - 1) * row_width; for (idx_t i = 0; i < count; i++) { idx_t &radix_offset = --counts[*(row_ptr + offset)]; - memcpy(target_ptr + radix_offset * row_width, row_ptr, row_width); + FastMemcpy(target_ptr + radix_offset * row_width, row_ptr, row_width); row_ptr -= row_width; } swap = !swap; @@ -30490,14 +29342,14 @@ inline void InsertionSort(const data_ptr_t orig_ptr, const data_ptr_t temp_ptr, const data_ptr_t val = temp_val.get(); const auto comp_width = total_comp_width - offset; for (idx_t i = 1; i < count; i++) { - memcpy(val, source_ptr + i * row_width, row_width); + FastMemcpy(val, source_ptr + i * row_width, row_width); idx_t j = i; while (j > 0 && - memcmp(source_ptr + (j - 1) * row_width + total_offset, val + total_offset, comp_width) > 0) { - memcpy(source_ptr + j * row_width, source_ptr + (j - 1) * row_width, row_width); + FastMemcmp(source_ptr + (j - 1) * row_width + total_offset, val + total_offset, comp_width) > 0) { + FastMemcpy(source_ptr + j * row_width, source_ptr + (j - 1) * row_width, row_width); j--; } - memcpy(source_ptr + j * row_width, val, row_width); + FastMemcpy(source_ptr + j * row_width, val, row_width); } } if (swap) { @@ -30531,7 +29383,7 @@ void RadixSortMSD(const data_ptr_t orig_ptr, const data_ptr_t temp_ptr, const id data_ptr_t row_ptr = source_ptr; for (idx_t i = 0; i < count; i++) { const idx_t &radix_offset = locations[*(row_ptr + total_offset)]++; - memcpy(target_ptr + radix_offset * row_width, row_ptr, row_width); + FastMemcpy(target_ptr + radix_offset * row_width, row_ptr, row_width); row_ptr += row_width; } swap = !swap; @@ -30663,6 +29515,7 @@ void LocalSortState::SortInMemory() { + //===----------------------------------------------------------------------===// // DuckDB // @@ -30727,17 +29580,17 @@ class ValidityStatistics : public BaseStatistics { public: void Merge(const BaseStatistics &other) override; - bool IsConstant() override; + bool IsConstant() const override; - unique_ptr Copy() override; - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(Deserializer &source); - void Verify(Vector &vector, const SelectionVector &sel, idx_t count) override; + unique_ptr Copy() const override; + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(FieldReader &reader); + void Verify(Vector &vector, const SelectionVector &sel, idx_t count) const override; static unique_ptr Combine(const unique_ptr &lstats, const unique_ptr &rstats); - string ToString() override; + string ToString() const override; }; } // namespace duckdb @@ -30767,14 +29620,14 @@ class StringStatistics : public BaseStatistics { void Update(const string_t &value); void Merge(const BaseStatistics &other) override; - unique_ptr Copy() override; - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(Deserializer &source, LogicalType type); - void Verify(Vector &vector, const SelectionVector &sel, idx_t count) override; + unique_ptr Copy() const override; + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(FieldReader &reader, LogicalType type); + void Verify(Vector &vector, const SelectionVector &sel, idx_t count) const override; - FilterPropagateResult CheckZonemap(ExpressionType comparison_type, const string &value); + FilterPropagateResult CheckZonemap(ExpressionType comparison_type, const string &value) const; - string ToString() override; + string ToString() const override; }; } // namespace duckdb @@ -31038,7 +29891,7 @@ void LocalSortState::ReOrder(SortedData &sd, data_ptr_t sorting_ptr, RowDataColl const idx_t sorting_entry_size = gstate.sort_layout.entry_size; for (idx_t i = 0; i < count; i++) { auto index = Load(sorting_ptr); - memcpy(ordered_data_ptr, unordered_data_ptr + index * row_width, row_width); + FastMemcpy(ordered_data_ptr, unordered_data_ptr + index * row_width, row_width); ordered_data_ptr += row_width; sorting_ptr += sorting_entry_size; } @@ -31180,7 +30033,7 @@ void GlobalSortState::InitializeMergeRound() { } } -void GlobalSortState::CompleteMergeRound() { +void GlobalSortState::CompleteMergeRound(bool keep_radix_data) { sorted_blocks.clear(); for (auto &sorted_block_vector : sorted_blocks_temp) { sorted_blocks.push_back(make_unique(buffer_manager, *this)); @@ -31192,7 +30045,7 @@ void GlobalSortState::CompleteMergeRound() { odd_one_out = nullptr; } // Only one block left: Done! - if (sorted_blocks.size() == 1) { + if (sorted_blocks.size() == 1 && !keep_radix_data) { sorted_blocks[0]->radix_sorting_data.clear(); sorted_blocks[0]->blob_sorting_data = nullptr; } @@ -31209,8 +30062,9 @@ void GlobalSortState::CompleteMergeRound() { namespace duckdb { -SortedData::SortedData(const RowLayout &layout, BufferManager &buffer_manager, GlobalSortState &state) - : layout(layout), block_idx(0), entry_idx(0), swizzled(false), buffer_manager(buffer_manager), state(state) { +SortedData::SortedData(SortedDataType type, const RowLayout &layout, BufferManager &buffer_manager, + GlobalSortState &state) + : type(type), layout(layout), swizzled(false), buffer_manager(buffer_manager), state(state) { } idx_t SortedData::Count() { @@ -31223,37 +30077,6 @@ idx_t SortedData::Count() { return count; } -void SortedData::Pin() { - PinData(); - if (!layout.AllConstant() && state.external) { - PinHeap(); - } -} - -data_ptr_t SortedData::DataPtr() const { - D_ASSERT(data_blocks[block_idx].block->Readers() != 0 && - data_handle->handle->BlockId() == data_blocks[block_idx].block->BlockId()); - return data_ptr + entry_idx * layout.GetRowWidth(); -} - -data_ptr_t SortedData::HeapPtr() const { - D_ASSERT(!layout.AllConstant() && state.external); - D_ASSERT(heap_blocks[block_idx].block->Readers() != 0 && - heap_handle->handle->BlockId() == heap_blocks[block_idx].block->BlockId()); - return heap_ptr + Load(DataPtr() + layout.GetHeapPointerOffset()); -} - -void SortedData::Advance(const bool &adv) { - entry_idx += adv; - if (entry_idx == data_blocks[block_idx].count) { - block_idx++; - entry_idx = 0; - if (block_idx < data_blocks.size()) { - Pin(); - } - } -} - void SortedData::CreateBlock() { auto capacity = MaxValue(((idx_t)Storage::BLOCK_SIZE + layout.GetRowWidth() - 1) / layout.GetRowWidth(), state.block_capacity); @@ -31264,15 +30087,9 @@ void SortedData::CreateBlock() { } } -void SortedData::ResetIndices(idx_t block_idx_to, idx_t entry_idx_to) { - block_idx = block_idx_to; - entry_idx = entry_idx_to; -} - -unique_ptr SortedData::CreateSlice(idx_t start_block_index, idx_t start_entry_index, idx_t end_block_index, - idx_t end_entry_index) { +unique_ptr SortedData::CreateSlice(idx_t start_block_index, idx_t end_block_index, idx_t end_entry_index) { // Add the corresponding blocks to the result - auto result = make_unique(layout, buffer_manager, state); + auto result = make_unique(type, layout, buffer_manager, state); for (idx_t i = start_block_index; i <= end_block_index; i++) { result->data_blocks.push_back(data_blocks[i]); if (!layout.AllConstant() && state.external) { @@ -31287,7 +30104,6 @@ unique_ptr SortedData::CreateSlice(idx_t start_block_index, idx_t st } } // Use start and end entry indices to set the boundaries - result->entry_idx = start_entry_index; D_ASSERT(end_entry_index <= result->data_blocks.back().count); result->data_blocks.back().count = end_entry_index; if (!layout.AllConstant() && state.external) { @@ -31305,37 +30121,18 @@ void SortedData::Unswizzle() { auto &heap_block = heap_blocks[i]; auto data_handle_p = buffer_manager.Pin(data_block.block); auto heap_handle_p = buffer_manager.Pin(heap_block.block); - RowOperations::UnswizzleHeapPointer(layout, data_handle_p->Ptr(), heap_handle_p->Ptr(), data_block.count); - RowOperations::UnswizzleColumns(layout, data_handle_p->Ptr(), data_block.count); + RowOperations::UnswizzlePointers(layout, data_handle_p->Ptr(), heap_handle_p->Ptr(), data_block.count); state.heap_blocks.push_back(move(heap_block)); state.pinned_blocks.push_back(move(heap_handle_p)); } heap_blocks.clear(); } -void SortedData::PinData() { - D_ASSERT(block_idx < data_blocks.size()); - auto &block = data_blocks[block_idx]; - if (!data_handle || data_handle->handle->BlockId() != block.block->BlockId()) { - data_handle = buffer_manager.Pin(data_blocks[block_idx].block); - } - data_ptr = data_handle->Ptr(); -} - -void SortedData::PinHeap() { - D_ASSERT(!layout.AllConstant() && state.external); - auto &block = heap_blocks[block_idx]; - if (!heap_handle || heap_handle->handle->BlockId() != block.block->BlockId()) { - heap_handle = buffer_manager.Pin(heap_blocks[block_idx].block); - } - heap_ptr = heap_handle->Ptr(); -} - SortedBlock::SortedBlock(BufferManager &buffer_manager, GlobalSortState &state) - : block_idx(0), entry_idx(0), buffer_manager(buffer_manager), state(state), sort_layout(state.sort_layout), + : buffer_manager(buffer_manager), state(state), sort_layout(state.sort_layout), payload_layout(state.payload_layout) { - blob_sorting_data = make_unique(sort_layout.blob_layout, buffer_manager, state); - payload_data = make_unique(payload_layout, buffer_manager, state); + blob_sorting_data = make_unique(SortedDataType::BLOB, sort_layout.blob_layout, buffer_manager, state); + payload_data = make_unique(SortedDataType::PAYLOAD, payload_layout, buffer_manager, state); } idx_t SortedBlock::Count() const { @@ -31348,17 +30145,6 @@ idx_t SortedBlock::Count() const { return count; } -idx_t SortedBlock::Remaining() const { - idx_t remaining = 0; - if (block_idx < radix_sorting_data.size()) { - remaining += radix_sorting_data[block_idx].count - entry_idx; - for (idx_t i = block_idx + 1; i < radix_sorting_data.size(); i++) { - remaining += radix_sorting_data[i].count; - } - } - return remaining; -} - void SortedBlock::InitializeWrite() { CreateBlock(); if (!sort_layout.all_constant) { @@ -31373,14 +30159,6 @@ void SortedBlock::CreateBlock() { radix_sorting_data.emplace_back(buffer_manager, capacity, sort_layout.entry_size); } -void SortedBlock::PinRadix(idx_t pin_block_idx) { - D_ASSERT(pin_block_idx < radix_sorting_data.size()); - auto &block = radix_sorting_data[pin_block_idx]; - if (!radix_handle || radix_handle->handle->BlockId() != block.block->BlockId()) { - radix_handle = buffer_manager.Pin(block.block); - } -} - void SortedBlock::AppendSortedBlocks(vector> &sorted_blocks) { D_ASSERT(Count() == 0); for (auto &sb : sorted_blocks) { @@ -31425,7 +30203,7 @@ void SortedBlock::GlobalToLocalIndex(const idx_t &global_idx, idx_t &local_block D_ASSERT(local_entry_index < radix_sorting_data[local_block_index].count); } -unique_ptr SortedBlock::CreateSlice(const idx_t start, const idx_t end) { +unique_ptr SortedBlock::CreateSlice(const idx_t start, const idx_t end, idx_t &entry_idx) { // Identify blocks/entry indices of this slice idx_t start_block_index; idx_t start_entry_index; @@ -31443,18 +30221,15 @@ unique_ptr SortedBlock::CreateSlice(const idx_t start, const idx_t radix_sorting_data[i].block = nullptr; } // Use start and end entry indices to set the boundaries - result->entry_idx = start_entry_index; + entry_idx = start_entry_index; D_ASSERT(end_entry_index <= result->radix_sorting_data.back().count); result->radix_sorting_data.back().count = end_entry_index; // Same for the var size sorting data if (!sort_layout.all_constant) { - result->blob_sorting_data = - blob_sorting_data->CreateSlice(start_block_index, start_entry_index, end_block_index, end_entry_index); + result->blob_sorting_data = blob_sorting_data->CreateSlice(start_block_index, end_block_index, end_entry_index); } // And the payload data - result->payload_data = - payload_data->CreateSlice(start_block_index, start_entry_index, end_block_index, end_entry_index); - D_ASSERT(result->Remaining() == end - start); + result->payload_data = payload_data->CreateSlice(start_block_index, end_block_index, end_entry_index); return result; } @@ -31489,19 +30264,91 @@ idx_t SortedBlock::SizeInBytes() const { return bytes; } -SortedDataScanner::SortedDataScanner(SortedData &sorted_data, GlobalSortState &global_sort_state) - : sorted_data(sorted_data), total_count(sorted_data.Count()), global_sort_state(global_sort_state), - total_scanned(0) { +SBScanState::SBScanState(BufferManager &buffer_manager, GlobalSortState &state) + : buffer_manager(buffer_manager), sort_layout(state.sort_layout), state(state), block_idx(0), entry_idx(0) { } -void SortedDataScanner::Scan(DataChunk &chunk) { +void SBScanState::PinRadix(idx_t block_idx_to) { + auto &radix_sorting_data = sb->radix_sorting_data; + D_ASSERT(block_idx_to < radix_sorting_data.size()); + auto &block = radix_sorting_data[block_idx_to]; + if (!radix_handle || radix_handle->handle->BlockId() != block.block->BlockId()) { + radix_handle = buffer_manager.Pin(block.block); + } +} + +void SBScanState::PinData(SortedData &sd) { + D_ASSERT(block_idx < sd.data_blocks.size()); + auto &data_handle = sd.type == SortedDataType::BLOB ? blob_sorting_data_handle : payload_data_handle; + auto &heap_handle = sd.type == SortedDataType::BLOB ? blob_sorting_heap_handle : payload_heap_handle; + + auto &data_block = sd.data_blocks[block_idx]; + if (!data_handle || data_handle->handle->BlockId() != data_block.block->BlockId()) { + data_handle = buffer_manager.Pin(data_block.block); + } + if (sd.layout.AllConstant() || !state.external) { + return; + } + auto &heap_block = sd.heap_blocks[block_idx]; + if (!heap_handle || heap_handle->handle->BlockId() != heap_block.block->BlockId()) { + heap_handle = buffer_manager.Pin(heap_block.block); + } +} + +data_ptr_t SBScanState::RadixPtr() const { + return radix_handle->Ptr() + entry_idx * sort_layout.entry_size; +} + +data_ptr_t SBScanState::DataPtr(SortedData &sd) const { + auto &data_handle = sd.type == SortedDataType::BLOB ? *blob_sorting_data_handle : *payload_data_handle; + D_ASSERT(sd.data_blocks[block_idx].block->Readers() != 0 && + data_handle.handle->BlockId() == sd.data_blocks[block_idx].block->BlockId()); + return data_handle.Ptr() + entry_idx * sd.layout.GetRowWidth(); +} + +data_ptr_t SBScanState::HeapPtr(SortedData &sd) const { + return BaseHeapPtr(sd) + Load(DataPtr(sd) + sd.layout.GetHeapPointerOffset()); +} + +data_ptr_t SBScanState::BaseHeapPtr(SortedData &sd) const { + auto &heap_handle = sd.type == SortedDataType::BLOB ? *blob_sorting_heap_handle : *payload_heap_handle; + D_ASSERT(!sd.layout.AllConstant() && state.external); + D_ASSERT(sd.heap_blocks[block_idx].block->Readers() != 0 && + heap_handle.handle->BlockId() == sd.heap_blocks[block_idx].block->BlockId()); + return heap_handle.Ptr(); +} + +idx_t SBScanState::Remaining() const { + const auto &blocks = sb->radix_sorting_data; + idx_t remaining = 0; + if (block_idx < blocks.size()) { + remaining += blocks[block_idx].count - entry_idx; + for (idx_t i = block_idx + 1; i < blocks.size(); i++) { + remaining += blocks[i].count; + } + } + return remaining; +} + +void SBScanState::SetIndices(idx_t block_idx_to, idx_t entry_idx_to) { + block_idx = block_idx_to; + entry_idx = entry_idx_to; +} + +PayloadScanner::PayloadScanner(SortedData &sorted_data, GlobalSortState &global_sort_state) + : sorted_data(sorted_data), read_state(global_sort_state.buffer_manager, global_sort_state), + total_count(sorted_data.Count()), global_sort_state(global_sort_state), total_scanned(0) { +} + +void PayloadScanner::Scan(DataChunk &chunk) { auto count = MinValue((idx_t)STANDARD_VECTOR_SIZE, total_count - total_scanned); if (count == 0) { - D_ASSERT(sorted_data.block_idx == sorted_data.data_blocks.size()); + D_ASSERT(read_state.block_idx == sorted_data.data_blocks.size()); + chunk.SetCardinality(count); return; } // Eagerly delete references to blocks that we've passed - for (idx_t i = 0; i < sorted_data.block_idx; i++) { + for (idx_t i = 0; i < read_state.block_idx; i++) { sorted_data.data_blocks[i].block = nullptr; } const idx_t &row_width = sorted_data.layout.GetRowWidth(); @@ -31509,10 +30356,10 @@ void SortedDataScanner::Scan(DataChunk &chunk) { idx_t scanned = 0; auto data_pointers = FlatVector::GetData(addresses); while (scanned < count) { - sorted_data.Pin(); - auto &data_block = sorted_data.data_blocks[sorted_data.block_idx]; - idx_t next = MinValue(data_block.count - sorted_data.entry_idx, count - scanned); - const data_ptr_t data_ptr = sorted_data.data_handle->Ptr() + sorted_data.entry_idx * row_width; + read_state.PinData(sorted_data); + auto &data_block = sorted_data.data_blocks[read_state.block_idx]; + idx_t next = MinValue(data_block.count - read_state.entry_idx, count - scanned); + const data_ptr_t data_ptr = read_state.payload_data_handle->Ptr() + read_state.entry_idx * row_width; // Set up the next pointers data_ptr_t row_ptr = data_ptr; for (idx_t i = 0; i < next; i++) { @@ -31521,14 +30368,13 @@ void SortedDataScanner::Scan(DataChunk &chunk) { } // Unswizzle the offsets back to pointers (if needed) if (!sorted_data.layout.AllConstant() && global_sort_state.external) { - RowOperations::UnswizzleHeapPointer(sorted_data.layout, data_ptr, sorted_data.heap_handle->Ptr(), next); - RowOperations::UnswizzleColumns(sorted_data.layout, data_ptr, next); + RowOperations::UnswizzlePointers(sorted_data.layout, data_ptr, read_state.payload_heap_handle->Ptr(), next); } // Update state indices - sorted_data.entry_idx += next; - if (sorted_data.entry_idx == data_block.count) { - sorted_data.block_idx++; - sorted_data.entry_idx = 0; + read_state.entry_idx += next; + if (read_state.entry_idx == data_block.count) { + read_state.block_idx++; + read_state.entry_idx = 0; } scanned += next; } @@ -31536,8 +30382,8 @@ void SortedDataScanner::Scan(DataChunk &chunk) { // Deserialize the payload data for (idx_t col_idx = 0; col_idx < sorted_data.layout.ColumnCount(); col_idx++) { const auto col_offset = sorted_data.layout.GetOffsets()[col_idx]; - RowOperations::Gather(addresses, FlatVector::INCREMENTAL_SELECTION_VECTOR, chunk.data[col_idx], - FlatVector::INCREMENTAL_SELECTION_VECTOR, count, col_offset, col_idx); + RowOperations::Gather(addresses, *FlatVector::IncrementalSelectionVector(), chunk.data[col_idx], + *FlatVector::IncrementalSelectionVector(), count, col_offset, col_idx); } chunk.SetCardinality(count); chunk.Verify(); @@ -31839,6 +30685,12 @@ string StringUtil::CandidatesMessage(const vector &candidates, const str return result_str; } +string StringUtil::CandidatesErrorMessage(const vector &strings, const string &target, + const string &message_prefix, idx_t n) { + auto closest_strings = StringUtil::TopNLevenshtein(strings, target, n); + return StringUtil::CandidatesMessage(closest_strings, message_prefix); +} + } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB @@ -31864,54 +30716,6 @@ string StringUtil::CandidatesMessage(const vector &candidates, const str -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/profiler.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - -namespace duckdb { - -//! The profiler can be used to measure elapsed time -template -class Profiler { -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; -}; - -} // namespace duckdb @@ -31924,6 +30728,7 @@ class Profiler { namespace duckdb { +class ClientContext; class ExpressionExecutor; class PhysicalOperator; class SQLStatement; @@ -31936,6 +30741,7 @@ struct ExpressionInfo { vector> children; // Extract ExpressionInformation from a given expression state void ExtractExpressionsRecursive(unique_ptr &state); + //! Whether or not expression has function bool hasfunction; //! The function Name @@ -31951,6 +30757,7 @@ struct ExpressionInfo { //! The ExpressionRootInfo keeps information related to the root of an expression tree struct ExpressionRootInfo { ExpressionRootInfo(ExpressionExecutorState &executor, string name); + //! Count the number of time the executor called uint64_t total_count = 0; //! Count the number of time the executor called since last sampling @@ -31974,6 +30781,7 @@ struct ExpressionRootInfo { struct ExpressionExecutorInfo { explicit ExpressionExecutorInfo() {}; explicit ExpressionExecutorInfo(ExpressionExecutor &executor, const string &name, int id); + //! A vector which contain the pointer to all ExpressionRootInfo vector> roots; //! Id, it will be used as index for executors_info vector @@ -31981,11 +30789,12 @@ struct ExpressionExecutorInfo { }; struct OperatorInformation { + explicit OperatorInformation(double time_ = 0, idx_t elements_ = 0) : time(time_), elements(elements_) { + } + double time = 0; idx_t elements = 0; string name; - explicit OperatorInformation(double time_ = 0, idx_t elements_ = 0) : time(time_), elements(elements_) { - } //! A vector of Expression Executor Info vector> executors_info; }; @@ -32011,7 +30820,7 @@ class OperatorProfiler { //! Whether or not the profiler is enabled bool enabled; //! The timer used to time the execution time of the individual Physical Operators - Profiler op; + Profiler op; //! The stack of Physical Operators that are currently active const PhysicalOperator *active_operator; //! A mapping of physical operators to recorded timings @@ -32021,10 +30830,7 @@ class OperatorProfiler { //! The QueryProfiler can be used to measure timings of queries class QueryProfiler { public: - DUCKDB_API QueryProfiler() - : automatic_print_format(ProfilerPrintFormat::NONE), enabled(false), detailed_enabled(false), running(false), - query_requires_profiling(false) { - } + DUCKDB_API QueryProfiler(ClientContext &context); public: struct TreeNode { @@ -32044,34 +30850,20 @@ class QueryProfiler { private: unique_ptr CreateTree(PhysicalOperator *root, idx_t depth = 0); void Render(const TreeNode &node, std::ostream &str) const; - //! The lock used for flushing information from a thread into the global query profiler - mutex flush_lock; public: - DUCKDB_API void Enable() { - enabled = true; - detailed_enabled = false; - } - - DUCKDB_API void DetailedEnable() { - detailed_enabled = true; - } - - DUCKDB_API void Disable() { - enabled = false; - } - - DUCKDB_API bool IsEnabled() { - return enabled; - } + DUCKDB_API bool IsEnabled() const; + DUCKDB_API bool IsDetailedEnabled() const; + DUCKDB_API ProfilerPrintFormat GetPrintFormat() const; + DUCKDB_API string GetSaveLocation() const; - bool IsDetailedEnabled() const { - return detailed_enabled; - } + DUCKDB_API static QueryProfiler &Get(ClientContext &context); - DUCKDB_API void StartQuery(string query); + DUCKDB_API void StartQuery(string query, bool is_explain_analyze = false); DUCKDB_API void EndQuery(); + DUCKDB_API void StartExplainAnalyze(); + //! Adds the timings gathered by an OperatorProfiler to this query profiler DUCKDB_API void Flush(OperatorProfiler &profiler); @@ -32087,12 +30879,6 @@ class QueryProfiler { DUCKDB_API string ToJSON() const; DUCKDB_API void WriteToFile(const char *path, string &info) const; - //! The format to automatically print query profiling information in (default: disabled) - ProfilerPrintFormat automatic_print_format; - //! The file to save query profiling information to, instead of printing it to the console (empty = print to - //! console) - string save_location; - idx_t OperatorSize() { return tree_map.size(); } @@ -32100,13 +30886,14 @@ class QueryProfiler { void Finalize(TreeNode &node); private: - //! Whether or not query profiling is enabled - bool enabled; - //! Whether or not detailed query profiling is enabled - bool detailed_enabled; + ClientContext &context; + //! Whether or not the query profiler is running bool running; + //! The lock used for flushing information from a thread into the global query profiler + mutex flush_lock; + //! Whether or not the query requires profiling bool query_requires_profiling; //! The root of the query tree @@ -32114,9 +30901,11 @@ class QueryProfiler { //! The query string string query; //! The timer used to time the execution time of the entire query - Profiler main_query; + Profiler main_query; //! A map of a Physical Operator pointer to a tree node TreeMap tree_map; + //! Whether or not we are running as part of a explain_analyze query + bool is_explain_analyze; public: const TreeMap &GetTreeMap() const { @@ -32125,7 +30914,7 @@ class QueryProfiler { private: //! The timer used to time the individual phases of the planning process - Profiler phase_profiler; + Profiler phase_profiler; //! A mapping of the phase names to the timings using PhaseTimingStorage = unordered_map; PhaseTimingStorage phase_timings; @@ -32145,12 +30934,12 @@ class QueryProfiler { class QueryProfilerHistory { private: //! Previous Query profilers - deque>> prev_profilers; + deque>> prev_profilers; //! Previous Query profilers size uint64_t prev_profilers_size = 20; public: - deque>> &GetPrevProfilers() { + deque>> &GetPrevProfilers() { return prev_profilers; } QueryProfilerHistory() { @@ -32215,19 +31004,19 @@ struct TreeRendererConfig { bool detailed = false; #ifndef DUCKDB_ASCII_TREE_RENDERER - const char *LTCORNER = "┌"; - const char *RTCORNER = "┐"; - const char *LDCORNER = "└"; - const char *RDCORNER = "┘"; - - const char *MIDDLE = "┼"; - const char *TMIDDLE = "┬"; - const char *LMIDDLE = "├"; - const char *RMIDDLE = "┤"; - const char *DMIDDLE = "┴"; - - const char *VERTICAL = "│"; - const char *HORIZONTAL = "─"; + const char *LTCORNER = "\342\224\214"; // "┌"; + const char *RTCORNER = "\342\224\220"; // "┐"; + const char *LDCORNER = "\342\224\224"; // "└"; + const char *RDCORNER = "\342\224\230"; // "┘"; + + const char *MIDDLE = "\342\224\274"; // "┼"; + const char *TMIDDLE = "\342\224\254"; // "┬"; + const char *LMIDDLE = "\342\224\234"; // "├"; + const char *RMIDDLE = "\342\224\244"; // "┤"; + const char *DMIDDLE = "\342\224\264"; // "┴"; + + const char *VERTICAL = "\342\224\202"; // "│"; + const char *HORIZONTAL = "\342\224\200"; // "─"; #else // ASCII version const char *LTCORNER = "<"; @@ -33771,23 +32560,6 @@ int NumericHelper::UnsignedLength(uint64_t value) { namespace duckdb { struct ValueOperations { - //===--------------------------------------------------------------------===// - // Numeric Operations - //===--------------------------------------------------------------------===// - // A + B - static Value Add(const Value &left, const Value &right); - // A - B - static Value Subtract(const Value &left, const Value &right); - // A * B - static Value Multiply(const Value &left, const Value &right); - // A / B - static Value Divide(const Value &left, const Value &right); - // A % B - static Value Modulo(const Value &left, const Value &right); - // // MIN(A, B) - // static Value Min(const Value &left, const Value &right); - // // MAX(A, B) - // static Value Max(const Value &left, const Value &right); //===--------------------------------------------------------------------===// // Comparison Operations //===--------------------------------------------------------------------===// @@ -33818,11 +32590,6 @@ struct ValueOperations { static bool DistinctLessThan(const Value &left, const Value &right); // A <= B, NULLs last static bool DistinctLessThanEquals(const Value &left, const Value &right); - //===--------------------------------------------------------------------===// - // Hash functions - //===--------------------------------------------------------------------===// - // result = HASH(A) - static hash_t Hash(const Value &left); }; } // namespace duckdb @@ -34336,11 +33103,11 @@ struct SelCache { namespace duckdb { class Vector; -//! The VectorCache holds cached data for +//! The VectorCache holds cached data that allows for re-use of the same memory by vectors class VectorCache { public: - // Instantiate a vector cache with the given type - VectorCache(const LogicalType &type); + //! Instantiate a vector cache with the given type + explicit VectorCache(const LogicalType &type); buffer_ptr buffer; @@ -34355,6 +33122,30 @@ class VectorCache { +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/types/arrow_aux_data.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { +struct ArrowAuxiliaryData : VectorAuxiliaryData { + explicit ArrowAuxiliaryData(shared_ptr arrow_array_p) + : VectorAuxiliaryData(VectorAuxiliaryDataType::ARROW_AUXILIARY), arrow_array(std::move(arrow_array_p)) { + + }; + ~ArrowAuxiliaryData() override {}; + shared_ptr arrow_array; +}; +} // namespace duckdb + namespace duckdb { @@ -34622,6 +33413,7 @@ struct DuckDBArrowArrayHolder { vector children = {}; vector children_ptrs = {}; array buffers = {{nullptr}}; + vector> arrow_original_array; }; static void ReleaseDuckDBArrowArray(ArrowArray *array) { @@ -34758,6 +33550,79 @@ void SetStructMap(DuckDBArrowArrayChildHolder &child_holder, const LogicalType & } } +struct ArrowUUIDConversion { + using internal_type_t = uint64_t; + + static unique_ptr InitializeVector(Vector &data, idx_t size) { + return make_unique(LogicalType::VARCHAR, size); + } + + static idx_t GetStringLength(uint64_t value) { + return UUID::STRING_SIZE; + } + + static string_t ConvertValue(Vector &tgt_vec, string_t *tgt_ptr, internal_type_t *src_ptr, idx_t row) { + auto str_value = UUID::ToString(src_ptr[row]); + // Have to store this string + tgt_ptr[row] = StringVector::AddStringOrBlob(tgt_vec, str_value); + return tgt_ptr[row]; + } +}; + +struct ArrowVarcharConversion { + using internal_type_t = string_t; + + static unique_ptr InitializeVector(Vector &data, idx_t size) { + return make_unique(data); + } + static idx_t GetStringLength(string_t value) { + return value.GetSize(); + } + + static string_t ConvertValue(Vector &tgt_vec, string_t *tgt_ptr, internal_type_t *src_ptr, idx_t row) { + return src_ptr[row]; + } +}; + +template +void SetVarchar(DuckDBArrowArrayChildHolder &child_holder, const LogicalType &type, Vector &data, idx_t size) { + auto &child = child_holder.array; + child_holder.vector = CONVERT::InitializeVector(data, size); + auto target_data_ptr = FlatVector::GetData(data); + child.n_buffers = 3; + child_holder.offsets = unique_ptr(new data_t[sizeof(uint32_t) * (size + 1)]); + child.buffers[1] = child_holder.offsets.get(); + D_ASSERT(child.buffers[1]); + //! step 1: figure out total string length: + idx_t total_string_length = 0; + auto source_ptr = FlatVector::GetData(data); + auto &mask = FlatVector::Validity(data); + for (idx_t row_idx = 0; row_idx < size; row_idx++) { + if (!mask.RowIsValid(row_idx)) { + continue; + } + total_string_length += CONVERT::GetStringLength(source_ptr[row_idx]); + } + //! step 2: allocate this much + child_holder.data = unique_ptr(new data_t[total_string_length]); + child.buffers[2] = child_holder.data.get(); + D_ASSERT(child.buffers[2]); + //! step 3: assign buffers + idx_t current_heap_offset = 0; + auto target_ptr = (uint32_t *)child.buffers[1]; + + for (idx_t row_idx = 0; row_idx < size; row_idx++) { + target_ptr[row_idx] = current_heap_offset; + if (!mask.RowIsValid(row_idx)) { + continue; + } + string_t str = CONVERT::ConvertValue(*child_holder.vector, target_data_ptr, source_ptr, row_idx); + memcpy((void *)((uint8_t *)child.buffers[2] + current_heap_offset), str.GetDataUnsafe(), str.GetSize()); + current_heap_offset += str.GetSize(); + } + target_ptr[size] = current_heap_offset; //! need to terminate last string! +} + void SetArrowChild(DuckDBArrowArrayChildHolder &child_holder, const LogicalType &type, Vector &data, idx_t size) { auto &child = child_holder.array; switch (type.id()) { @@ -34805,6 +33670,8 @@ void SetArrowChild(DuckDBArrowArrayChildHolder &child_holder, const LogicalType case LogicalTypeId::TIMESTAMP_NS: case LogicalTypeId::TIMESTAMP_SEC: case LogicalTypeId::TIME: + case LogicalTypeId::TIMESTAMP_TZ: + case LogicalTypeId::TIME_TZ: child_holder.vector = make_unique(data); child.n_buffers = 2; child.buffers[1] = (void *)FlatVector::GetData(*child_holder.vector); @@ -34860,39 +33727,11 @@ void SetArrowChild(DuckDBArrowArrayChildHolder &child_holder, const LogicalType } case LogicalTypeId::BLOB: case LogicalTypeId::VARCHAR: { - child_holder.vector = make_unique(data); - child.n_buffers = 3; - child_holder.offsets = unique_ptr(new data_t[sizeof(uint32_t) * (size + 1)]); - child.buffers[1] = child_holder.offsets.get(); - D_ASSERT(child.buffers[1]); - //! step 1: figure out total string length: - idx_t total_string_length = 0; - auto string_t_ptr = FlatVector::GetData(*child_holder.vector); - auto &mask = FlatVector::Validity(*child_holder.vector); - for (idx_t row_idx = 0; row_idx < size; row_idx++) { - if (!mask.RowIsValid(row_idx)) { - continue; - } - total_string_length += string_t_ptr[row_idx].GetSize(); - } - //! step 2: allocate this much - child_holder.data = unique_ptr(new data_t[total_string_length]); - child.buffers[2] = child_holder.data.get(); - D_ASSERT(child.buffers[2]); - //! step 3: assign buffers - idx_t current_heap_offset = 0; - auto target_ptr = (uint32_t *)child.buffers[1]; - - for (idx_t row_idx = 0; row_idx < size; row_idx++) { - target_ptr[row_idx] = current_heap_offset; - if (!mask.RowIsValid(row_idx)) { - continue; - } - auto &str = string_t_ptr[row_idx]; - memcpy((void *)((uint8_t *)child.buffers[2] + current_heap_offset), str.GetDataUnsafe(), str.GetSize()); - current_heap_offset += str.GetSize(); - } - target_ptr[size] = current_heap_offset; //! need to terminate last string! + SetVarchar(child_holder, type, data, size); + break; + } + case LogicalTypeId::UUID: { + SetVarchar(child_holder, type, data, size); break; } case LogicalTypeId::LIST: { @@ -34948,6 +33787,23 @@ void SetArrowChild(DuckDBArrowArrayChildHolder &child_holder, const LogicalType } break; } + case LogicalTypeId::ENUM: { + // We need to initialize our dictionary + child_holder.children.resize(1); + idx_t dict_size = EnumType::GetSize(type); + InitializeChild(child_holder.children[0], dict_size); + Vector dictionary(EnumType::GetValuesInsertOrder(type)); + SetArrowChild(child_holder.children[0], dictionary.GetType(), dictionary, dict_size); + child_holder.children_ptrs.push_back(&child_holder.children[0].array); + + // now we set the data + child.dictionary = child_holder.children_ptrs[0]; + child_holder.vector = make_unique(data); + child.n_buffers = 2; + child.buffers[1] = (void *)FlatVector::GetData(*child_holder.vector); + + break; + } default: throw std::runtime_error("Unsupported type " + type.ToString()); } @@ -34984,7 +33840,12 @@ void DataChunk::ToArrowArray(ArrowArray *out_array) { InitializeChild(child_holder, size()); auto &vector = child_holder.vector; auto &child = child_holder.array; - + auto vec_buffer = data[col_idx].GetBuffer(); + if (vec_buffer->GetAuxiliaryData() && + vec_buffer->GetAuxiliaryDataType() == VectorAuxiliaryDataType::ARROW_AUXILIARY) { + auto arrow_aux_data = (ArrowAuxiliaryData *)vec_buffer->GetAuxiliaryData(); + root_holder->arrow_original_array.push_back(arrow_aux_data->arrow_array); + } //! We could, in theory, output other types of vectors here, currently only FLAT Vectors SetArrowChild(child_holder, GetTypes()[col_idx], data[col_idx], size()); SetChildValidityMask(*vector, child); @@ -35451,29 +34312,44 @@ int32_t Date::ExtractISODayOfTheWeek(date_t date) { } } -static int32_t GetISOWeek(int32_t year, int32_t month, int32_t day) { +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 - auto day_of_the_fourth = Date::ExtractISODayOfTheWeek(Date::FromDate(year, 1, 4)); + 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 - sunday, first is the first day - auto first_day_of_the_first_week = day_of_the_fourth >= 4 ? 0 : 5 - day_of_the_fourth; - if (day_of_the_year < first_day_of_the_first_week) { - // day is part of last year - return GetISOWeek(year - 1, 12, 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_week) / 7) + 1; + return ((day_of_the_year - first_day_of_the_first_isoweek) / 7) + 1; } } -int32_t Date::ExtractISOWeekNumber(date_t date) { - int32_t year, month, day; +void Date::ExtractISOYearWeek(date_t date, int32_t &year, int32_t &week) { + int32_t month, day; Date::Convert(date, year, month, day); - return GetISOWeek(year, month - 1, day - 1); + week = GetISOYearWeek(year, month - 1, day - 1); +} + +int32_t Date::ExtractISOWeekNumber(date_t date) { + int32_t year, week; + ExtractISOYearWeek(date, year, week); + return week; +} + +int32_t Date::ExtractISOYearNumber(date_t date) { + int32_t year, week; + ExtractISOYearWeek(date, year, week); + return year; } int32_t Date::ExtractWeekNumberRegular(date_t date, bool monday_first) { @@ -36568,13 +35444,18 @@ enum class DatePartSpecifier : uint8_t { DOW, ISODOW, WEEK, + ISOYEAR, QUARTER, DOY, - YEARWEEK + YEARWEEK, + ERA, + TIMEZONE, + TIMEZONE_HOUR, + TIMEZONE_MINUTE }; -bool TryGetDatePartSpecifier(const string &specifier, DatePartSpecifier &result); -DatePartSpecifier GetDatePartSpecifier(const string &specifier); +DUCKDB_API bool TryGetDatePartSpecifier(const string &specifier, DatePartSpecifier &result); +DUCKDB_API DatePartSpecifier GetDatePartSpecifier(const string &specifier); } // namespace duckdb @@ -36646,7 +35527,7 @@ bool TryAddOperator::Operation(int16_t left, int16_t right, int16_t &result); template <> bool TryAddOperator::Operation(int32_t left, int32_t right, int32_t &result); template <> -bool TryAddOperator::Operation(int64_t left, int64_t right, int64_t &result); +DUCKDB_API bool TryAddOperator::Operation(int64_t left, int64_t right, int64_t &result); struct AddOperatorOverflowCheck { template @@ -36758,7 +35639,7 @@ bool TryMultiplyOperator::Operation(int16_t left, int16_t right, int16_t &result template <> bool TryMultiplyOperator::Operation(int32_t left, int32_t right, int32_t &result); template <> -bool TryMultiplyOperator::Operation(int64_t left, int64_t right, int64_t &result); +DUCKDB_API bool TryMultiplyOperator::Operation(int64_t left, int64_t right, int64_t &result); struct MultiplyOperatorOverflowCheck { template @@ -36908,7 +35789,7 @@ interval_parse_time : { // parse the remainder of the time as a Time type dtime_t time; idx_t pos; - if (!Time::TryConvertTime(str + start_pos, len, pos, time)) { + if (!Time::TryConvertTime(str + start_pos, len - start_pos, pos, time)) { return false; } result.micros += time.micros; @@ -37228,6 +36109,61 @@ bool Interval::GreaterThanEquals(interval_t left, interval_t right) { return GreaterThan(left, right) || Equals(left, right); } +date_t Interval::Add(date_t left, interval_t right) { + date_t result; + if (right.months != 0) { + int32_t year, month, day; + Date::Convert(left, year, month, day); + int32_t year_diff = right.months / Interval::MONTHS_PER_YEAR; + year += year_diff; + month += right.months - year_diff * Interval::MONTHS_PER_YEAR; + if (month > Interval::MONTHS_PER_YEAR) { + year++; + month -= Interval::MONTHS_PER_YEAR; + } else if (month <= 0) { + year--; + month += Interval::MONTHS_PER_YEAR; + } + day = MinValue(day, Date::MonthDays(year, month)); + result = Date::FromDate(year, month, day); + } else { + result = left; + } + if (right.days != 0) { + if (!TryAddOperator::Operation(result.days, right.days, result.days)) { + throw OutOfRangeException("Date out of range"); + } + } + if (right.micros != 0) { + if (!TryAddOperator::Operation(result.days, int32_t(right.micros / Interval::MICROS_PER_DAY), result.days)) { + throw OutOfRangeException("Date out of range"); + } + } + return result; +} + +dtime_t Interval::Add(dtime_t left, interval_t right, date_t &date) { + int64_t diff = right.micros - ((right.micros / Interval::MICROS_PER_DAY) * Interval::MICROS_PER_DAY); + left += diff; + if (left.micros >= Interval::MICROS_PER_DAY) { + left.micros -= Interval::MICROS_PER_DAY; + date.days++; + } else if (left.micros < 0) { + left.micros += Interval::MICROS_PER_DAY; + date.days--; + } + return left; +} + +timestamp_t Interval::Add(timestamp_t left, interval_t right) { + date_t date; + dtime_t time; + Timestamp::Convert(left, date, time); + auto new_date = Interval::Add(date, right); + auto new_time = Interval::Add(time, right, new_date); + return Timestamp::FromDatetime(new_date, new_time); +} + } // namespace duckdb @@ -37754,6 +36690,28 @@ string Time::ToString(dtime_t time) { return string(buffer.get(), length); } +string Time::ToUTCOffset(int hour_offset, int minute_offset) { + dtime_t time((hour_offset * Interval::MINS_PER_HOUR + minute_offset) * Interval::MICROS_PER_MINUTE); + + char buffer[1 + 2 + 1 + 2]; + idx_t length = 0; + buffer[length++] = (time.micros < 0 ? '-' : '+'); + time.micros = std::abs(time.micros); + + int32_t time_units[4]; + Time::Convert(time, time_units[0], time_units[1], time_units[2], time_units[3]); + + TimeToStringCast::FormatTwoDigits(buffer + length, time_units[0]); + length += 2; + if (time_units[1]) { + buffer[length++] = ':'; + TimeToStringCast::FormatTwoDigits(buffer + length, time_units[1]); + length += 2; + } + + return string(buffer, length); +} + dtime_t Time::FromTime(int32_t hour, int32_t minute, int32_t second, int32_t microseconds) { int64_t result; result = hour; // hours @@ -37970,7 +36928,12 @@ timestamp_t Timestamp::FromDatetime(date_t date, dtime_t time) { void Timestamp::Convert(timestamp_t timestamp, date_t &out_date, dtime_t &out_time) { out_date = GetDate(timestamp); - out_time = dtime_t(timestamp.value - (int64_t(out_date.days) * int64_t(Interval::MICROS_PER_DAY))); + int64_t days_micros; + if (!TryMultiplyOperator::Operation(out_date.days, Interval::MICROS_PER_DAY, + days_micros)) { + throw ConversionException("Date out of range in timestamp conversion"); + } + out_time = dtime_t(timestamp.value - days_micros); D_ASSERT(timestamp == Timestamp::FromDatetime(out_date, out_time)); } @@ -38191,13 +37154,14 @@ void ValidityMask::Slice(const ValidityMask &other, idx_t offset) { Initialize(other); return; } - Initialize(STANDARD_VECTOR_SIZE); + ValidityMask new_mask(STANDARD_VECTOR_SIZE); // FIXME THIS NEEDS FIXING! #if 1 for (idx_t i = offset; i < STANDARD_VECTOR_SIZE; i++) { - Set(i - offset, other.RowIsValid(i)); + new_mask.Set(i - offset, other.RowIsValid(i)); } + Initialize(new_mask); #else // first shift the "whole" units idx_t entire_units = offset / BITS_PER_VALUE; @@ -38205,7 +37169,7 @@ void ValidityMask::Slice(const ValidityMask &other, idx_t offset) { if (entire_units > 0) { idx_t validity_idx; for (validity_idx = 0; validity_idx + entire_units < STANDARD_ENTRY_COUNT; validity_idx++) { - validity_mask[validity_idx] = other.validity_mask[validity_idx + entire_units]; + new_mask.validity_mask[validity_idx] = other.validity_mask[validity_idx + entire_units]; } } // now we shift the remaining sub units @@ -38220,15 +37184,17 @@ void ValidityMask::Slice(const ValidityMask &other, idx_t offset) { if (sub_units > 0) { idx_t validity_idx; for (validity_idx = 0; validity_idx + 1 < STANDARD_ENTRY_COUNT; validity_idx++) { - validity_mask[validity_idx] = (other.validity_mask[validity_idx] >> sub_units) | - (other.validity_mask[validity_idx + 1] << (BITS_PER_VALUE - sub_units)); + new_mask.validity_mask[validity_idx] = + (other.validity_mask[validity_idx] >> sub_units) | + (other.validity_mask[validity_idx + 1] << (BITS_PER_VALUE - sub_units)); } - validity_mask[validity_idx] >>= sub_units; + new_mask.validity_mask[validity_idx] >>= sub_units; } #ifdef DEBUG for (idx_t i = offset; i < STANDARD_VECTOR_SIZE; i++) { - D_ASSERT(RowIsValid(i - offset) == other.RowIsValid(i)); + D_ASSERT(new_mask.RowIsValid(i - offset) == other.RowIsValid(i)); } + Initialize(new_mask); #endif #endif } @@ -38341,6 +37307,8 @@ hugeint_t ModuloOperator::Operation(hugeint_t left, hugeint_t right); + + namespace duckdb { Value::Value(LogicalType type) : type_(move(type)), is_null(true) { @@ -38383,6 +37351,39 @@ Value::Value(string val) : type_(LogicalType::VARCHAR), is_null(false), str_valu } } +Value::~Value() { +} + +Value::Value(const Value &other) + : type_(other.type_), is_null(other.is_null), value_(other.value_), str_value(other.str_value), + struct_value(other.struct_value), list_value(other.list_value) { +} + +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)) { +} + +Value &Value::operator=(const Value &other) { + type_ = other.type_; + is_null = other.is_null; + value_ = other.value_; + str_value = other.str_value; + struct_value = other.struct_value; + list_value = other.list_value; + return *this; +} + +Value &Value::operator=(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); + return *this; +} + Value Value::MinimumValue(const LogicalType &type) { switch (type.id()) { case LogicalTypeId::BOOLEAN: @@ -38409,60 +37410,45 @@ Value Value::MinimumValue(const LogicalType &type) { case LogicalTypeId::UBIGINT: return Value::UBIGINT(NumericLimits::Minimum()); case LogicalTypeId::DATE: - return Value::DATE(date_t(NumericLimits::Minimum())); + return Value::DATE(Date::FromDate(Date::DATE_MIN_YEAR, Date::DATE_MIN_MONTH, Date::DATE_MIN_DAY)); case LogicalTypeId::TIME: return Value::TIME(dtime_t(0)); case LogicalTypeId::TIMESTAMP: - return Value::TIMESTAMP(timestamp_t(NumericLimits::Minimum())); + return Value::TIMESTAMP(Date::FromDate(Timestamp::MIN_YEAR, Timestamp::MIN_MONTH, Timestamp::MIN_DAY), + dtime_t(0)); case LogicalTypeId::TIMESTAMP_SEC: - return Value::TimestampSec(timestamp_t(NumericLimits::Minimum())); + return MinimumValue(LogicalType::TIMESTAMP).CastAs(LogicalType::TIMESTAMP_S); case LogicalTypeId::TIMESTAMP_MS: - return Value::TimestampMs(timestamp_t(NumericLimits::Minimum())); + return MinimumValue(LogicalType::TIMESTAMP).CastAs(LogicalType::TIMESTAMP_MS); case LogicalTypeId::TIMESTAMP_NS: - return Value::TimestampNs(timestamp_t(NumericLimits::Minimum())); + return Value::TIMESTAMPNS(timestamp_t(NumericLimits::Minimum())); + case LogicalTypeId::TIME_TZ: + return Value::TIMETZ(dtime_t(0)); + case LogicalTypeId::TIMESTAMP_TZ: + return Value::TIMESTAMPTZ(Timestamp::FromDatetime( + Date::FromDate(Timestamp::MIN_YEAR, Timestamp::MIN_MONTH, Timestamp::MIN_DAY), dtime_t(0))); case LogicalTypeId::FLOAT: return Value::FLOAT(NumericLimits::Minimum()); case LogicalTypeId::DOUBLE: return Value::DOUBLE(NumericLimits::Minimum()); case LogicalTypeId::DECIMAL: { - Value result; + auto width = DecimalType::GetWidth(type); + auto scale = DecimalType::GetScale(type); switch (type.InternalType()) { case PhysicalType::INT16: - result = Value::MinimumValue(LogicalType::SMALLINT); - break; + return Value::DECIMAL(int16_t(-NumericHelper::POWERS_OF_TEN[width] + 1), width, scale); case PhysicalType::INT32: - result = Value::MinimumValue(LogicalType::INTEGER); - break; + return Value::DECIMAL(int32_t(-NumericHelper::POWERS_OF_TEN[width] + 1), width, scale); case PhysicalType::INT64: - result = Value::MinimumValue(LogicalType::BIGINT); - break; + return Value::DECIMAL(int64_t(-NumericHelper::POWERS_OF_TEN[width] + 1), width, scale); case PhysicalType::INT128: - result = Value::MinimumValue(LogicalType::HUGEINT); - break; + return Value::DECIMAL(-Hugeint::POWERS_OF_TEN[width] + 1, width, scale); default: throw InternalException("Unknown decimal type"); } - result.type_ = type; - return result; - } - case LogicalTypeId::ENUM: { - Value result; - switch (type.InternalType()) { - case PhysicalType::UINT8: - result = Value::MinimumValue(LogicalType::UTINYINT); - break; - case PhysicalType::UINT16: - result = Value::MinimumValue(LogicalType::USMALLINT); - break; - case PhysicalType::UINT32: - result = Value::MinimumValue(LogicalType::UINTEGER); - break; - default: - throw InternalException("ENUM can only have unsigned integers (except UINT64) as physical types"); - } - result.type_ = type; - return result; } + case LogicalTypeId::ENUM: + return Value::ENUM(0, type); default: throw InvalidTypeException(type, "MinimumValue requires numeric type"); } @@ -38471,7 +37457,7 @@ Value Value::MinimumValue(const LogicalType &type) { Value Value::MaximumValue(const LogicalType &type) { switch (type.id()) { case LogicalTypeId::BOOLEAN: - return Value::BOOLEAN(false); + return Value::BOOLEAN(true); case LogicalTypeId::TINYINT: return Value::TINYINT(NumericLimits::Maximum()); case LogicalTypeId::SMALLINT: @@ -38494,60 +37480,43 @@ Value Value::MaximumValue(const LogicalType &type) { case LogicalTypeId::UBIGINT: return Value::UBIGINT(NumericLimits::Maximum()); case LogicalTypeId::DATE: - return Value::DATE(date_t(NumericLimits::Maximum())); + return Value::DATE(Date::FromDate(Date::DATE_MAX_YEAR, Date::DATE_MAX_MONTH, Date::DATE_MAX_DAY)); case LogicalTypeId::TIME: - return Value::TIME(dtime_t(Interval::SECS_PER_DAY * Interval::MICROS_PER_SEC)); + return Value::TIME(dtime_t(Interval::SECS_PER_DAY * Interval::MICROS_PER_SEC - 1)); case LogicalTypeId::TIMESTAMP: return Value::TIMESTAMP(timestamp_t(NumericLimits::Maximum())); case LogicalTypeId::TIMESTAMP_MS: - return Value::TimestampMs(timestamp_t(NumericLimits::Maximum())); + return MaximumValue(LogicalType::TIMESTAMP).CastAs(LogicalType::TIMESTAMP_MS); case LogicalTypeId::TIMESTAMP_NS: - return Value::TimestampNs(timestamp_t(NumericLimits::Maximum())); + return Value::TIMESTAMPNS(timestamp_t(NumericLimits::Maximum())); case LogicalTypeId::TIMESTAMP_SEC: - return Value::TimestampSec(timestamp_t(NumericLimits::Maximum())); + return MaximumValue(LogicalType::TIMESTAMP).CastAs(LogicalType::TIMESTAMP_S); + case LogicalTypeId::TIME_TZ: + return Value::TIMETZ(dtime_t(Interval::SECS_PER_DAY * Interval::MICROS_PER_SEC - 1)); + case LogicalTypeId::TIMESTAMP_TZ: + return Value::TIMESTAMPTZ(timestamp_t(NumericLimits::Maximum())); case LogicalTypeId::FLOAT: return Value::FLOAT(NumericLimits::Maximum()); case LogicalTypeId::DOUBLE: return Value::DOUBLE(NumericLimits::Maximum()); case LogicalTypeId::DECIMAL: { - Value result; + auto width = DecimalType::GetWidth(type); + auto scale = DecimalType::GetScale(type); switch (type.InternalType()) { case PhysicalType::INT16: - result = Value::MaximumValue(LogicalType::SMALLINT); - break; + return Value::DECIMAL(int16_t(NumericHelper::POWERS_OF_TEN[width] - 1), width, scale); case PhysicalType::INT32: - result = Value::MaximumValue(LogicalType::INTEGER); - break; + return Value::DECIMAL(int32_t(NumericHelper::POWERS_OF_TEN[width] - 1), width, scale); case PhysicalType::INT64: - result = Value::MaximumValue(LogicalType::BIGINT); - break; + return Value::DECIMAL(int64_t(NumericHelper::POWERS_OF_TEN[width] - 1), width, scale); case PhysicalType::INT128: - result = Value::MaximumValue(LogicalType::HUGEINT); - break; + return Value::DECIMAL(Hugeint::POWERS_OF_TEN[width] - 1, width, scale); default: throw InternalException("Unknown decimal type"); } - result.type_ = type; - return result; - } - case LogicalTypeId::ENUM: { - Value result; - switch (type.InternalType()) { - case PhysicalType::UINT8: - result = Value::MaximumValue(LogicalType::UTINYINT); - break; - case PhysicalType::UINT16: - result = Value::MaximumValue(LogicalType::USMALLINT); - break; - case PhysicalType::UINT32: - result = Value::MaximumValue(LogicalType::UINTEGER); - break; - default: - throw InternalException("ENUM can only have unsigned integers (except UINT64) as physical types"); - } - result.type_ = type; - return result; } + case LogicalTypeId::ENUM: + return Value::ENUM(EnumType::GetSize(type) - 1, type); default: throw InvalidTypeException(type, "MaximumValue requires numeric type"); } @@ -38748,6 +37717,13 @@ Value Value::TIME(dtime_t value) { return result; } +Value Value::TIMETZ(dtime_t value) { + Value result(LogicalType::TIME_TZ); + result.value_.time = value; + result.is_null = false; + return result; +} + Value Value::TIME(int32_t hour, int32_t min, int32_t sec, int32_t micros) { return Value::TIME(Time::FromTime(hour, min, sec, micros)); } @@ -38759,21 +37735,28 @@ Value Value::TIMESTAMP(timestamp_t value) { return result; } -Value Value::TimestampNs(timestamp_t timestamp) { +Value Value::TIMESTAMPTZ(timestamp_t value) { + Value result(LogicalType::TIMESTAMP_TZ); + result.value_.timestamp = value; + result.is_null = false; + return result; +} + +Value Value::TIMESTAMPNS(timestamp_t timestamp) { Value result(LogicalType::TIMESTAMP_NS); result.value_.timestamp = timestamp; result.is_null = false; return result; } -Value Value::TimestampMs(timestamp_t timestamp) { +Value Value::TIMESTAMPMS(timestamp_t timestamp) { Value result(LogicalType::TIMESTAMP_MS); result.value_.timestamp = timestamp; result.is_null = false; return result; } -Value Value::TimestampSec(timestamp_t timestamp) { +Value Value::TIMESTAMPSEC(timestamp_t timestamp) { Value result(LogicalType::TIMESTAMP_S); result.value_.timestamp = timestamp; result.is_null = false; @@ -38834,6 +37817,16 @@ Value Value::LIST(vector values) { return result; } +Value Value::LIST(LogicalType child_type, vector values) { + if (values.empty()) { + return Value::EMPTYLIST(move(child_type)); + } + for (auto &val : values) { + val = val.CastAs(child_type); + } + return Value::LIST(move(values)); +} + Value Value::EMPTYLIST(LogicalType child_type) { Value result; result.type_ = LogicalType::LIST(move(child_type)); @@ -38995,7 +37988,7 @@ Value Value::CreateValue(Value value) { //===--------------------------------------------------------------------===// template T Value::GetValueInternal() const { - if (is_null) { + if (IsNull()) { return NullValue(); } switch (type_.id()) { @@ -39015,8 +38008,10 @@ T Value::GetValueInternal() const { case LogicalTypeId::DATE: return Cast::Operation(value_.date); case LogicalTypeId::TIME: + case LogicalTypeId::TIME_TZ: return Cast::Operation(value_.time); case LogicalTypeId::TIMESTAMP: + case LogicalTypeId::TIMESTAMP_TZ: return Cast::Operation(value_.timestamp); case LogicalTypeId::UTINYINT: return Cast::Operation(value_.utinyint); @@ -39039,6 +38034,19 @@ T Value::GetValueInternal() const { return Cast::Operation(value_.interval); case LogicalTypeId::DECIMAL: return CastAs(LogicalType::DOUBLE).GetValueInternal(); + case LogicalTypeId::ENUM: { + switch (type_.InternalType()) { + case PhysicalType::UINT8: + return Cast::Operation(value_.utinyint); + case PhysicalType::UINT16: + return Cast::Operation(value_.usmallint); + case PhysicalType::UINT32: + return Cast::Operation(value_.uinteger); + default: + throw InternalException("Invalid Internal Type for ENUMs"); + } + } + default: throw NotImplementedException("Unimplemented type \"%s\" for GetValue()", type_.ToString()); } @@ -39065,12 +38073,18 @@ int32_t Value::GetValue() const { } template <> int64_t Value::GetValue() const { - if (type_.id() == LogicalTypeId::TIMESTAMP || type_.id() == LogicalTypeId::TIME || - type_.id() == LogicalTypeId::TIMESTAMP_SEC || type_.id() == LogicalTypeId::TIMESTAMP_NS || - type_.id() == LogicalTypeId::TIMESTAMP_MS) { + switch (type_.id()) { + case LogicalTypeId::TIMESTAMP: + case LogicalTypeId::TIMESTAMP_SEC: + case LogicalTypeId::TIMESTAMP_NS: + case LogicalTypeId::TIMESTAMP_MS: + case LogicalTypeId::TIME: + case LogicalTypeId::TIME_TZ: + case LogicalTypeId::TIMESTAMP_TZ: return value_.bigint; + default: + return GetValueInternal(); } - return GetValueInternal(); } template <> hugeint_t Value::GetValue() const { @@ -39129,24 +38143,31 @@ uintptr_t Value::GetPointer() const { Value Value::Numeric(const LogicalType &type, int64_t value) { switch (type.id()) { + case LogicalTypeId::BOOLEAN: + D_ASSERT(value == 0 || value == 1); + return Value::BOOLEAN(value ? 1 : 0); case LogicalTypeId::TINYINT: - D_ASSERT(value <= NumericLimits::Maximum()); + D_ASSERT(value >= NumericLimits::Minimum() && value <= NumericLimits::Maximum()); return Value::TINYINT((int8_t)value); case LogicalTypeId::SMALLINT: - D_ASSERT(value <= NumericLimits::Maximum()); + D_ASSERT(value >= NumericLimits::Minimum() && value <= NumericLimits::Maximum()); return Value::SMALLINT((int16_t)value); case LogicalTypeId::INTEGER: - D_ASSERT(value <= NumericLimits::Maximum()); + D_ASSERT(value >= NumericLimits::Minimum() && value <= NumericLimits::Maximum()); return Value::INTEGER((int32_t)value); case LogicalTypeId::BIGINT: return Value::BIGINT(value); case LogicalTypeId::UTINYINT: + D_ASSERT(value >= NumericLimits::Minimum() && value <= NumericLimits::Maximum()); return Value::UTINYINT((uint8_t)value); case LogicalTypeId::USMALLINT: + D_ASSERT(value >= NumericLimits::Minimum() && value <= NumericLimits::Maximum()); return Value::USMALLINT((uint16_t)value); case LogicalTypeId::UINTEGER: + D_ASSERT(value >= NumericLimits::Minimum() && value <= NumericLimits::Maximum()); return Value::UINTEGER((uint32_t)value); case LogicalTypeId::UBIGINT: + D_ASSERT(value >= 0); return Value::UBIGINT(value); case LogicalTypeId::HUGEINT: return Value::HUGEINT(value); @@ -39161,25 +38182,32 @@ Value Value::Numeric(const LogicalType &type, int64_t value) { case LogicalTypeId::POINTER: return Value::POINTER(value); case LogicalTypeId::DATE: - D_ASSERT(value <= NumericLimits::Maximum()); + D_ASSERT(value >= NumericLimits::Minimum() && value <= NumericLimits::Maximum()); return Value::DATE(date_t(value)); case LogicalTypeId::TIME: return Value::TIME(dtime_t(value)); case LogicalTypeId::TIMESTAMP: return Value::TIMESTAMP(timestamp_t(value)); case LogicalTypeId::TIMESTAMP_NS: - return Value::TimestampNs(timestamp_t(value)); + return Value::TIMESTAMPNS(timestamp_t(value)); case LogicalTypeId::TIMESTAMP_MS: - return Value::TimestampMs(timestamp_t(value)); + return Value::TIMESTAMPMS(timestamp_t(value)); case LogicalTypeId::TIMESTAMP_SEC: - return Value::TimestampSec(timestamp_t(value)); + return Value::TIMESTAMPSEC(timestamp_t(value)); + case LogicalTypeId::TIME_TZ: + return Value::TIMETZ(dtime_t(value)); + case LogicalTypeId::TIMESTAMP_TZ: + return Value::TIMESTAMPTZ(timestamp_t(value)); case LogicalTypeId::ENUM: switch (type.InternalType()) { case PhysicalType::UINT8: + D_ASSERT(value >= NumericLimits::Minimum() && value <= NumericLimits::Maximum()); return Value::UTINYINT((uint8_t)value); case PhysicalType::UINT16: + D_ASSERT(value >= NumericLimits::Minimum() && value <= NumericLimits::Maximum()); return Value::USMALLINT((uint16_t)value); case PhysicalType::UINT32: + D_ASSERT(value >= NumericLimits::Minimum() && value <= NumericLimits::Maximum()); return Value::UINTEGER((uint32_t)value); default: throw InternalException("Enum doesn't accept this physical type"); @@ -39189,116 +38217,284 @@ Value Value::Numeric(const LogicalType &type, int64_t value) { } } +Value Value::Numeric(const LogicalType &type, hugeint_t value) { +#ifdef DEBUG + // perform a throwing cast to verify that the type fits + Value::HUGEINT(value).CastAs(type); +#endif + switch (type.id()) { + case LogicalTypeId::HUGEINT: + return Value::HUGEINT(value); + case LogicalTypeId::UBIGINT: + return Value::UBIGINT(Hugeint::Cast(value)); + default: + return Value::Numeric(type, Hugeint::Cast(value)); + } +} + //===--------------------------------------------------------------------===// // GetValueUnsafe //===--------------------------------------------------------------------===// template <> -int8_t &Value::GetValueUnsafe() { +DUCKDB_API bool Value::GetValueUnsafe() const { + D_ASSERT(type_.InternalType() == PhysicalType::BOOL); + return value_.boolean; +} + +template <> +int8_t Value::GetValueUnsafe() const { D_ASSERT(type_.InternalType() == PhysicalType::INT8 || type_.InternalType() == PhysicalType::BOOL); return value_.tinyint; } template <> -int16_t &Value::GetValueUnsafe() { +int16_t Value::GetValueUnsafe() const { D_ASSERT(type_.InternalType() == PhysicalType::INT16); return value_.smallint; } template <> -int32_t &Value::GetValueUnsafe() { +int32_t Value::GetValueUnsafe() const { D_ASSERT(type_.InternalType() == PhysicalType::INT32); return value_.integer; } template <> -int64_t &Value::GetValueUnsafe() { +int64_t Value::GetValueUnsafe() const { D_ASSERT(type_.InternalType() == PhysicalType::INT64); return value_.bigint; } template <> -hugeint_t &Value::GetValueUnsafe() { +hugeint_t Value::GetValueUnsafe() const { D_ASSERT(type_.InternalType() == PhysicalType::INT128); return value_.hugeint; } template <> -uint8_t &Value::GetValueUnsafe() { +uint8_t Value::GetValueUnsafe() const { D_ASSERT(type_.InternalType() == PhysicalType::UINT8); return value_.utinyint; } template <> -uint16_t &Value::GetValueUnsafe() { +uint16_t Value::GetValueUnsafe() const { D_ASSERT(type_.InternalType() == PhysicalType::UINT16); return value_.usmallint; } template <> -uint32_t &Value::GetValueUnsafe() { +uint32_t Value::GetValueUnsafe() const { D_ASSERT(type_.InternalType() == PhysicalType::UINT32); return value_.uinteger; } template <> -uint64_t &Value::GetValueUnsafe() { +uint64_t Value::GetValueUnsafe() const { D_ASSERT(type_.InternalType() == PhysicalType::UINT64); return value_.ubigint; } template <> -string &Value::GetValueUnsafe() { +string Value::GetValueUnsafe() const { D_ASSERT(type_.InternalType() == PhysicalType::VARCHAR); return str_value; } template <> -float &Value::GetValueUnsafe() { +DUCKDB_API string_t Value::GetValueUnsafe() const { + D_ASSERT(type_.InternalType() == PhysicalType::VARCHAR); + return string_t(str_value); +} + +template <> +float Value::GetValueUnsafe() const { D_ASSERT(type_.InternalType() == PhysicalType::FLOAT); return value_.float_; } template <> -double &Value::GetValueUnsafe() { +double Value::GetValueUnsafe() const { D_ASSERT(type_.InternalType() == PhysicalType::DOUBLE); return value_.double_; } template <> -date_t &Value::GetValueUnsafe() { +date_t Value::GetValueUnsafe() const { D_ASSERT(type_.InternalType() == PhysicalType::INT32); return value_.date; } template <> -dtime_t &Value::GetValueUnsafe() { +dtime_t Value::GetValueUnsafe() const { D_ASSERT(type_.InternalType() == PhysicalType::INT64); return value_.time; } template <> -timestamp_t &Value::GetValueUnsafe() { +timestamp_t Value::GetValueUnsafe() const { D_ASSERT(type_.InternalType() == PhysicalType::INT64); return value_.timestamp; } template <> -interval_t &Value::GetValueUnsafe() { +interval_t Value::GetValueUnsafe() const { D_ASSERT(type_.InternalType() == PhysicalType::INTERVAL); return value_.interval; } -Value Value::Numeric(const LogicalType &type, hugeint_t value) { - switch (type.id()) { - case LogicalTypeId::HUGEINT: - return Value::HUGEINT(value); +//===--------------------------------------------------------------------===// +// GetReferenceUnsafe +//===--------------------------------------------------------------------===// +template <> +int8_t &Value::GetReferenceUnsafe() { + D_ASSERT(type_.InternalType() == PhysicalType::INT8 || type_.InternalType() == PhysicalType::BOOL); + return value_.tinyint; +} + +template <> +int16_t &Value::GetReferenceUnsafe() { + D_ASSERT(type_.InternalType() == PhysicalType::INT16); + return value_.smallint; +} + +template <> +int32_t &Value::GetReferenceUnsafe() { + D_ASSERT(type_.InternalType() == PhysicalType::INT32); + return value_.integer; +} + +template <> +int64_t &Value::GetReferenceUnsafe() { + D_ASSERT(type_.InternalType() == PhysicalType::INT64); + return value_.bigint; +} + +template <> +hugeint_t &Value::GetReferenceUnsafe() { + D_ASSERT(type_.InternalType() == PhysicalType::INT128); + return value_.hugeint; +} + +template <> +uint8_t &Value::GetReferenceUnsafe() { + D_ASSERT(type_.InternalType() == PhysicalType::UINT8); + return value_.utinyint; +} + +template <> +uint16_t &Value::GetReferenceUnsafe() { + D_ASSERT(type_.InternalType() == PhysicalType::UINT16); + return value_.usmallint; +} + +template <> +uint32_t &Value::GetReferenceUnsafe() { + D_ASSERT(type_.InternalType() == PhysicalType::UINT32); + return value_.uinteger; +} + +template <> +uint64_t &Value::GetReferenceUnsafe() { + D_ASSERT(type_.InternalType() == PhysicalType::UINT64); + return value_.ubigint; +} + +template <> +float &Value::GetReferenceUnsafe() { + D_ASSERT(type_.InternalType() == PhysicalType::FLOAT); + return value_.float_; +} + +template <> +double &Value::GetReferenceUnsafe() { + D_ASSERT(type_.InternalType() == PhysicalType::DOUBLE); + return value_.double_; +} + +template <> +date_t &Value::GetReferenceUnsafe() { + D_ASSERT(type_.InternalType() == PhysicalType::INT32); + return value_.date; +} + +template <> +dtime_t &Value::GetReferenceUnsafe() { + D_ASSERT(type_.InternalType() == PhysicalType::INT64); + return value_.time; +} + +template <> +timestamp_t &Value::GetReferenceUnsafe() { + D_ASSERT(type_.InternalType() == PhysicalType::INT64); + return value_.timestamp; +} + +template <> +interval_t &Value::GetReferenceUnsafe() { + D_ASSERT(type_.InternalType() == PhysicalType::INTERVAL); + return value_.interval; +} + +//===--------------------------------------------------------------------===// +// Hash +//===--------------------------------------------------------------------===// +hash_t Value::Hash() const { + if (IsNull()) { + return 0; + } + switch (type_.InternalType()) { + case PhysicalType::BOOL: + return duckdb::Hash(value_.boolean); + case PhysicalType::INT8: + return duckdb::Hash(value_.tinyint); + case PhysicalType::INT16: + return duckdb::Hash(value_.smallint); + case PhysicalType::INT32: + return duckdb::Hash(value_.integer); + case PhysicalType::INT64: + return duckdb::Hash(value_.bigint); + case PhysicalType::UINT8: + return duckdb::Hash(value_.utinyint); + case PhysicalType::UINT16: + return duckdb::Hash(value_.usmallint); + case PhysicalType::UINT32: + return duckdb::Hash(value_.uinteger); + case PhysicalType::UINT64: + return duckdb::Hash(value_.ubigint); + case PhysicalType::INT128: + return duckdb::Hash(value_.hugeint); + case PhysicalType::FLOAT: + return duckdb::Hash(value_.float_); + case PhysicalType::DOUBLE: + return duckdb::Hash(value_.double_); + case PhysicalType::INTERVAL: + return duckdb::Hash(value_.interval); + case PhysicalType::VARCHAR: + return duckdb::Hash(string_t(StringValue::Get(*this))); + case PhysicalType::STRUCT: { + auto &struct_children = StructValue::GetChildren(*this); + hash_t hash = 0; + for (auto &entry : struct_children) { + hash ^= entry.Hash(); + } + return hash; + } + case PhysicalType::LIST: { + auto &list_children = ListValue::GetChildren(*this); + hash_t hash = 0; + for (auto &entry : list_children) { + hash ^= entry.Hash(); + } + return hash; + } default: - return Value::Numeric(type, Hugeint::Cast(value)); + throw InternalException("Unimplemented type for value hash"); } } string Value::ToString() const { - if (is_null) { + if (IsNull()) { return "NULL"; } switch (type_.id()) { @@ -39348,6 +38544,10 @@ string Value::ToString() const { return Time::ToString(value_.time); case LogicalTypeId::TIMESTAMP: return Timestamp::ToString(value_.timestamp); + case LogicalTypeId::TIME_TZ: + return Time::ToString(value_.time) + Time::ToUTCOffset(0, 0); + case LogicalTypeId::TIMESTAMP_TZ: + return Timestamp::ToString(value_.timestamp) + Time::ToUTCOffset(0, 0); case LogicalTypeId::TIMESTAMP_SEC: return Timestamp::ToString(Timestamp::FromEpochSeconds(value_.timestamp.value)); case LogicalTypeId::TIMESTAMP_MS: @@ -39419,7 +38619,7 @@ string Value::ToString() const { default: throw InternalException("ENUM can only have unsigned integers (except UINT64) as physical types"); } - return values_insert_order[enum_idx]; + return values_insert_order.GetValue(enum_idx).ToString(); } default: throw NotImplementedException("Unimplemented type for printing: %s", type_.ToString()); @@ -39427,27 +38627,110 @@ string Value::ToString() const { } //===--------------------------------------------------------------------===// -// Numeric Operators +// Type-specific getters //===--------------------------------------------------------------------===// -Value Value::operator+(const Value &rhs) const { - return ValueOperations::Add(*this, rhs); +bool BooleanValue::Get(const Value &value) { + return value.GetValueUnsafe(); } -Value Value::operator-(const Value &rhs) const { - return ValueOperations::Subtract(*this, rhs); +int8_t TinyIntValue::Get(const Value &value) { + return value.GetValueUnsafe(); } -Value Value::operator*(const Value &rhs) const { - return ValueOperations::Multiply(*this, rhs); +int16_t SmallIntValue::Get(const Value &value) { + return value.GetValueUnsafe(); } -Value Value::operator/(const Value &rhs) const { - return ValueOperations::Divide(*this, rhs); +int32_t IntegerValue::Get(const Value &value) { + return value.GetValueUnsafe(); } -Value Value::operator%(const Value &rhs) const { - throw NotImplementedException("value modulo"); - // return ValueOperations::Modulo(*this, rhs); +int64_t BigIntValue::Get(const Value &value) { + return value.GetValueUnsafe(); +} + +hugeint_t HugeIntValue::Get(const Value &value) { + return value.GetValueUnsafe(); +} + +uint8_t UTinyIntValue::Get(const Value &value) { + return value.GetValueUnsafe(); +} + +uint16_t USmallIntValue::Get(const Value &value) { + return value.GetValueUnsafe(); +} + +uint32_t UIntegerValue::Get(const Value &value) { + return value.GetValueUnsafe(); +} + +uint64_t UBigIntValue::Get(const Value &value) { + return value.GetValueUnsafe(); +} + +float FloatValue::Get(const Value &value) { + return value.GetValueUnsafe(); +} + +double DoubleValue::Get(const Value &value) { + return value.GetValueUnsafe(); +} + +const string &StringValue::Get(const Value &value) { + D_ASSERT(value.type().InternalType() == PhysicalType::VARCHAR); + return value.str_value; +} + +date_t DateValue::Get(const Value &value) { + return value.GetValueUnsafe(); +} + +dtime_t TimeValue::Get(const Value &value) { + return value.GetValueUnsafe(); +} + +timestamp_t TimestampValue::Get(const Value &value) { + return value.GetValueUnsafe(); +} + +interval_t IntervalValue::Get(const Value &value) { + return value.GetValueUnsafe(); +} + +const vector &StructValue::GetChildren(const Value &value) { + D_ASSERT(value.type().InternalType() == PhysicalType::STRUCT); + return value.struct_value; +} + +const vector &ListValue::GetChildren(const Value &value) { + D_ASSERT(value.type().InternalType() == PhysicalType::LIST); + return value.list_value; +} + +hugeint_t IntegralValue::Get(const Value &value) { + switch (value.type().InternalType()) { + case PhysicalType::INT8: + return TinyIntValue::Get(value); + case PhysicalType::INT16: + return SmallIntValue::Get(value); + case PhysicalType::INT32: + return IntegerValue::Get(value); + case PhysicalType::INT64: + return BigIntValue::Get(value); + case PhysicalType::INT128: + return HugeIntValue::Get(value); + case PhysicalType::UINT8: + return UTinyIntValue::Get(value); + case PhysicalType::UINT16: + return USmallIntValue::Get(value); + case PhysicalType::UINT32: + return UIntegerValue::Get(value); + case PhysicalType::UINT64: + return UBigIntValue::Get(value); + default: + throw InternalException("Invalid internal type \"%s\" for IntegralValue::Get", value.type().ToString()); + } } //===--------------------------------------------------------------------===// @@ -39539,10 +38822,12 @@ bool Value::TryCastAs(const LogicalType &target_type, bool strict) { return true; } -void Value::Serialize(Serializer &serializer) { - type_.Serialize(serializer); - serializer.Write(is_null); - if (!is_null) { +void Value::Serialize(Serializer &main_serializer) const { + FieldWriter writer(main_serializer); + writer.WriteSerializable(type_); + writer.WriteField(IsNull()); + if (!IsNull()) { + auto &serializer = writer.GetSerializer(); switch (type_.InternalType()) { case PhysicalType::BOOL: serializer.Write(value_.boolean); @@ -39593,16 +38878,19 @@ void Value::Serialize(Serializer &serializer) { } } } + writer.Finalize(); } -Value Value::Deserialize(Deserializer &source) { - auto type = LogicalType::Deserialize(source); - auto is_null = source.Read(); +Value Value::Deserialize(Deserializer &main_source) { + FieldReader reader(main_source); + auto type = reader.ReadRequiredSerializable(); + auto is_null = reader.ReadRequired(); Value new_value = Value(type); if (is_null) { return new_value; } new_value.is_null = false; + auto &source = reader.GetSource(); switch (type.InternalType()) { case PhysicalType::BOOL: new_value.value_.boolean = source.Read(); @@ -39649,9 +38937,11 @@ Value Value::Deserialize(Deserializer &source) { default: { Vector v(type); v.Deserialize(1, source); - return v.GetValue(0); + new_value = v.GetValue(0); + break; } } + reader.Finalize(); return new_value; } @@ -39660,10 +38950,10 @@ void Value::Print() const { } bool Value::ValuesAreEqual(const Value &result_value, const Value &value) { - if (result_value.is_null != value.is_null) { + if (result_value.IsNull() != value.IsNull()) { return false; } - if (result_value.is_null && value.is_null) { + if (result_value.IsNull() && value.IsNull()) { // NULL = NULL in checking code return true; } @@ -39724,8 +39014,6 @@ bool Value::IsValid(double value) { - - #include // strlen() on Solaris namespace duckdb { @@ -39781,12 +39069,13 @@ void Vector::Reference(const Value &value) { auto struct_buffer = make_unique(); auto &child_types = StructType::GetChildTypes(value.type()); auto &child_vectors = struct_buffer->GetChildren(); + auto &value_children = StructValue::GetChildren(value); for (idx_t i = 0; i < child_types.size(); i++) { - auto vector = make_unique(value.is_null ? Value(child_types[i].second) : value.struct_value[i]); + auto vector = make_unique(value.IsNull() ? Value(child_types[i].second) : value_children[i]); child_vectors.push_back(move(vector)); } auxiliary = move(struct_buffer); - if (value.is_null) { + if (value.IsNull()) { SetValue(0, value); } } else if (internal_type == PhysicalType::LIST) { @@ -40004,98 +39293,66 @@ void Vector::SetValue(idx_t index, const Value &val) { } validity.EnsureWritable(); - validity.Set(index, !val.is_null); - if (val.is_null && GetType().InternalType() != PhysicalType::STRUCT) { + validity.Set(index, !val.IsNull()); + if (val.IsNull() && GetType().InternalType() != PhysicalType::STRUCT) { // for structs we still need to set the child-entries to NULL // so we do not bail out yet return; } - switch (GetType().id()) { - case LogicalTypeId::BOOLEAN: - ((bool *)data)[index] = val.value_.boolean; - break; - case LogicalTypeId::TINYINT: - ((int8_t *)data)[index] = val.value_.tinyint; - break; - case LogicalTypeId::SMALLINT: - ((int16_t *)data)[index] = val.value_.smallint; + switch (GetType().InternalType()) { + case PhysicalType::BOOL: + ((bool *)data)[index] = val.GetValueUnsafe(); break; - case LogicalTypeId::DATE: - case LogicalTypeId::INTEGER: - ((int32_t *)data)[index] = val.value_.integer; + case PhysicalType::INT8: + ((int8_t *)data)[index] = val.GetValueUnsafe(); break; - case LogicalTypeId::TIMESTAMP: - case LogicalTypeId::TIMESTAMP_SEC: - case LogicalTypeId::TIMESTAMP_MS: - case LogicalTypeId::TIMESTAMP_NS: - case LogicalTypeId::HASH: - case LogicalTypeId::TIME: - case LogicalTypeId::BIGINT: - ((int64_t *)data)[index] = val.value_.bigint; + case PhysicalType::INT16: + ((int16_t *)data)[index] = val.GetValueUnsafe(); break; - case LogicalTypeId::UTINYINT: - ((uint8_t *)data)[index] = val.value_.utinyint; + case PhysicalType::INT32: + ((int32_t *)data)[index] = val.GetValueUnsafe(); break; - case LogicalTypeId::USMALLINT: - ((uint16_t *)data)[index] = val.value_.usmallint; + case PhysicalType::INT64: + ((int64_t *)data)[index] = val.GetValueUnsafe(); break; - case LogicalTypeId::UINTEGER: - ((uint32_t *)data)[index] = val.value_.uinteger; + case PhysicalType::INT128: + ((hugeint_t *)data)[index] = val.GetValueUnsafe(); break; - case LogicalTypeId::UBIGINT: - ((uint64_t *)data)[index] = val.value_.ubigint; + case PhysicalType::UINT8: + ((uint8_t *)data)[index] = val.GetValueUnsafe(); break; - case LogicalTypeId::HUGEINT: - case LogicalTypeId::UUID: - ((hugeint_t *)data)[index] = val.value_.hugeint; + case PhysicalType::UINT16: + ((uint16_t *)data)[index] = val.GetValueUnsafe(); break; - case LogicalTypeId::DECIMAL: - D_ASSERT(DecimalType::GetWidth(GetType()) == DecimalType::GetWidth(val.type())); - D_ASSERT(DecimalType::GetScale(GetType()) == DecimalType::GetScale(val.type())); - switch (GetType().InternalType()) { - case PhysicalType::INT16: - ((int16_t *)data)[index] = val.value_.smallint; - break; - case PhysicalType::INT32: - ((int32_t *)data)[index] = val.value_.integer; - break; - case PhysicalType::INT64: - ((int64_t *)data)[index] = val.value_.bigint; - break; - case PhysicalType::INT128: - ((hugeint_t *)data)[index] = val.value_.hugeint; - break; - default: - throw InternalException("Widths bigger than 38 are not supported"); - } + case PhysicalType::UINT32: + ((uint32_t *)data)[index] = val.GetValueUnsafe(); break; - case LogicalTypeId::FLOAT: - ((float *)data)[index] = val.value_.float_; + case PhysicalType::UINT64: + ((uint64_t *)data)[index] = val.GetValueUnsafe(); break; - case LogicalTypeId::DOUBLE: - ((double *)data)[index] = val.value_.double_; + case PhysicalType::FLOAT: + ((float *)data)[index] = val.GetValueUnsafe(); break; - case LogicalTypeId::POINTER: - ((uintptr_t *)data)[index] = val.value_.pointer; + case PhysicalType::DOUBLE: + ((double *)data)[index] = val.GetValueUnsafe(); break; - case LogicalTypeId::INTERVAL: - ((interval_t *)data)[index] = val.value_.interval; + case PhysicalType::INTERVAL: + ((interval_t *)data)[index] = val.GetValueUnsafe(); break; - case LogicalTypeId::VARCHAR: - case LogicalTypeId::BLOB: - ((string_t *)data)[index] = StringVector::AddStringOrBlob(*this, val.str_value); + case PhysicalType::VARCHAR: + ((string_t *)data)[index] = StringVector::AddStringOrBlob(*this, StringValue::Get(val)); break; - case LogicalTypeId::MAP: - case LogicalTypeId::STRUCT: { + case PhysicalType::STRUCT: { D_ASSERT(GetVectorType() == VectorType::CONSTANT_VECTOR || GetVectorType() == VectorType::FLAT_VECTOR); auto &children = StructVector::GetEntries(*this); - D_ASSERT(val.is_null || children.size() == val.struct_value.size()); + auto &val_children = StructValue::GetChildren(val); + D_ASSERT(val.IsNull() || children.size() == val_children.size()); for (size_t i = 0; i < children.size(); i++) { auto &vec_child = children[i]; - if (!val.is_null) { - auto &struct_child = val.struct_value[i]; + if (!val.IsNull()) { + auto &struct_child = val_children[i]; vec_child->SetValue(index, struct_child); } else { vec_child->SetValue(index, Value()); @@ -40103,36 +39360,20 @@ void Vector::SetValue(idx_t index, const Value &val) { } break; } - case LogicalTypeId::LIST: { + case PhysicalType::LIST: { auto offset = ListVector::GetListSize(*this); - if (!val.list_value.empty()) { - for (idx_t i = 0; i < val.list_value.size(); i++) { - Value v(val.list_value[i]); - ListVector::PushBack(*this, v); + auto &val_children = ListValue::GetChildren(val); + if (!val_children.empty()) { + for (idx_t i = 0; i < val_children.size(); i++) { + ListVector::PushBack(*this, val_children[i]); } } //! now set the pointer auto &entry = ((list_entry_t *)data)[index]; - entry.length = val.list_value.size(); + entry.length = val_children.size(); entry.offset = offset; break; } - case LogicalTypeId::ENUM: { - switch (type.InternalType()) { - case PhysicalType::UINT8: - ((uint8_t *)data)[index] = val.value_.utinyint; - break; - case PhysicalType::UINT16: - ((uint16_t *)data)[index] = val.value_.usmallint; - break; - case PhysicalType::UINT32: - ((uint32_t *)data)[index] = val.value_.uinteger; - break; - default: - throw InternalException("ENUM can only have unsigned integers (except UINT64) as physical types"); - } - break; - } default: throw InternalException("Unimplemented type for Vector::SetValue"); } @@ -40176,6 +39417,8 @@ Value Vector::GetValue(idx_t index) const { return Value::DATE(((date_t *)data)[index]); case LogicalTypeId::TIME: return Value::TIME(((dtime_t *)data)[index]); + case LogicalTypeId::TIME_TZ: + return Value::TIMETZ(((dtime_t *)data)[index]); case LogicalTypeId::BIGINT: return Value::BIGINT(((int64_t *)data)[index]); case LogicalTypeId::UTINYINT: @@ -40189,11 +39432,13 @@ Value Vector::GetValue(idx_t index) const { case LogicalTypeId::TIMESTAMP: return Value::TIMESTAMP(((timestamp_t *)data)[index]); case LogicalTypeId::TIMESTAMP_NS: - return Value::TimestampNs(((timestamp_t *)data)[index]); + return Value::TIMESTAMPNS(((timestamp_t *)data)[index]); case LogicalTypeId::TIMESTAMP_MS: - return Value::TimestampMs(((timestamp_t *)data)[index]); + return Value::TIMESTAMPMS(((timestamp_t *)data)[index]); case LogicalTypeId::TIMESTAMP_SEC: - return Value::TimestampSec(((timestamp_t *)data)[index]); + return Value::TIMESTAMPSEC(((timestamp_t *)data)[index]); + case LogicalTypeId::TIMESTAMP_TZ: + return Value::TIMESTAMPTZ(((timestamp_t *)data)[index]); case LogicalTypeId::HUGEINT: return Value::HUGEINT(((hugeint_t *)data)[index]); case LogicalTypeId::UUID: @@ -40244,26 +39489,31 @@ Value Vector::GetValue(idx_t index) const { auto str = ((string_t *)data)[index]; return Value::BLOB((const_data_ptr_t)str.GetDataUnsafe(), str.GetSize()); } - case LogicalTypeId::MAP: + case LogicalTypeId::MAP: { + auto &child_entries = StructVector::GetEntries(*this); + Value key = child_entries[0]->GetValue(index); + Value value = child_entries[1]->GetValue(index); + return Value::MAP(move(key), move(value)); + } case LogicalTypeId::STRUCT: { - Value ret(GetType()); - ret.is_null = false; // we can derive the value schema from the vector schema auto &child_entries = StructVector::GetEntries(*this); - for (auto &struct_child : child_entries) { - ret.struct_value.push_back(struct_child->GetValue(index)); + child_list_t children; + for (idx_t child_idx = 0; child_idx < child_entries.size(); child_idx++) { + auto &struct_child = child_entries[child_idx]; + children.push_back( + make_pair(StructType::GetChildName(GetType(), child_idx), struct_child->GetValue(index))); } - return ret; + return Value::STRUCT(move(children)); } case LogicalTypeId::LIST: { - Value ret(GetType()); - ret.is_null = false; auto offlen = ((list_entry_t *)data)[index]; auto &child_vec = ListVector::GetEntry(*this); + vector children; for (idx_t i = offlen.offset; i < offlen.offset + offlen.length; i++) { - ret.list_value.push_back(child_vec.GetValue(i)); + children.push_back(child_vec.GetValue(i)); } - return ret; + return Value::LIST(ListType::GetChildType(GetType()), move(children)); } default: throw InternalException("Unimplemented type for value access"); @@ -40372,7 +39622,7 @@ void Vector::Normalify(idx_t count) { // allocate a new buffer for the vector auto old_buffer = move(buffer); auto old_data = data; - buffer = VectorBuffer::CreateStandardVector(type); + buffer = VectorBuffer::CreateStandardVector(type, MaxValue(STANDARD_VECTOR_SIZE, count)); data = buffer->GetData(); vector_type = VectorType::FLAT_VECTOR; if (is_null) { @@ -40510,7 +39760,7 @@ void Vector::Orrify(idx_t count, VectorData &data) { break; default: Normalify(count); - data.sel = &FlatVector::INCREMENTAL_SELECTION_VECTOR; + data.sel = FlatVector::IncrementalSelectionVector(count, data.owned_sel); data.data = FlatVector::GetData(*this); data.validity = FlatVector::Validity(*this); break; @@ -40701,7 +39951,10 @@ void Vector::UTFVerify(const SelectionVector &sel, idx_t count) { } void Vector::UTFVerify(idx_t count) { - UTFVerify(FlatVector::INCREMENTAL_SELECTION_VECTOR, count); + SelectionVector owned_sel; + auto flat_sel = FlatVector::IncrementalSelectionVector(count, owned_sel); + + UTFVerify(*flat_sel, count); } void Vector::Verify(const SelectionVector &sel, idx_t count) { @@ -40767,7 +40020,7 @@ void Vector::Verify(const SelectionVector &sel, idx_t count) { if (GetType().InternalType() == PhysicalType::STRUCT) { auto &child_types = StructType::GetChildTypes(GetType()); - D_ASSERT(child_types.size() > 0); + D_ASSERT(!child_types.empty()); if (GetVectorType() == VectorType::FLAT_VECTOR || GetVectorType() == VectorType::CONSTANT_VECTOR) { // create a selection vector of the non-null entries of the struct vector auto &children = StructVector::GetEntries(*this); @@ -40841,15 +40094,9 @@ void Vector::Verify(const SelectionVector &sel, idx_t count) { } void Vector::Verify(idx_t count) { - if (count > STANDARD_VECTOR_SIZE) { - SelectionVector selection_vector(count); - for (size_t i = 0; i < count; i++) { - selection_vector.set_index(i, i); - } - Verify(selection_vector, count); - } else { - Verify(FlatVector::INCREMENTAL_SELECTION_VECTOR, count); - } + SelectionVector owned_sel; + auto flat_sel = FlatVector::IncrementalSelectionVector(count, owned_sel); + Verify(*flat_sel, count); } void FlatVector::SetNull(Vector &vector, idx_t idx, bool is_null) { @@ -40877,9 +40124,20 @@ void ConstantVector::SetNull(Vector &vector, bool is_null) { } } +const SelectionVector *FlatVector::IncrementalSelectionVector(idx_t count, SelectionVector &owned_sel) { + if (count <= STANDARD_VECTOR_SIZE) { + return FlatVector::IncrementalSelectionVector(); + } + owned_sel.Initialize(count); + for (idx_t i = 0; i < count; i++) { + owned_sel.set_index(i, i); + } + return &owned_sel; +} + const SelectionVector *ConstantVector::ZeroSelectionVector(idx_t count, SelectionVector &owned_sel) { if (count <= STANDARD_VECTOR_SIZE) { - return &ConstantVector::ZERO_SELECTION_VECTOR; + return ConstantVector::ZeroSelectionVector(); } owned_sel.Initialize(count); for (idx_t i = 0; i < count; i++) { @@ -41113,7 +40371,14 @@ void TemplatedSearchInMap(Vector &list, T key, vector &offsets, bool is_k } } -void SearchString(Vector &list, string &key, vector &offsets, bool is_key_null, idx_t offset, idx_t length) { +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 SearchStringInMap(Vector &list, const string &key, vector &offsets, bool is_key_null, idx_t offset, + idx_t length) { auto &list_vector = ListVector::GetEntry(list); VectorData vector_data; list_vector.Orrify(ListVector::GetListSize(list), vector_data); @@ -41138,78 +40403,49 @@ void SearchString(Vector &list, string &key, vector &offsets, bool is_key } } -vector ListVector::Search(Vector &list, Value &key, idx_t row) { +vector ListVector::Search(Vector &list, const Value &key, idx_t row) { vector offsets; auto &list_vector = ListVector::GetEntry(list); auto &entry = ((list_entry_t *)list.GetData())[row]; - switch (list_vector.GetType().id()) { - case LogicalTypeId::SQLNULL: - if (key.is_null) { - for (idx_t i = entry.offset; i < entry.offset + entry.length; i++) { - offsets.push_back(i); - } - } - break; - case LogicalTypeId::UTINYINT: - ::duckdb::TemplatedSearchInMap(list, key.value_.utinyint, offsets, key.is_null, entry.offset, - entry.length); - break; - case LogicalTypeId::TINYINT: - ::duckdb::TemplatedSearchInMap(list, key.value_.tinyint, offsets, key.is_null, entry.offset, - entry.length); - break; - case LogicalTypeId::USMALLINT: - ::duckdb::TemplatedSearchInMap(list, key.value_.usmallint, offsets, key.is_null, entry.offset, - entry.length); - break; - case LogicalTypeId::SMALLINT: - ::duckdb::TemplatedSearchInMap(list, key.value_.smallint, offsets, key.is_null, entry.offset, - entry.length); + switch (list_vector.GetType().InternalType()) { + case PhysicalType::BOOL: + case PhysicalType::INT8: + TemplatedSearchInMap(list, key, offsets, key.IsNull(), entry.offset, entry.length); break; - case LogicalTypeId::UINTEGER: - ::duckdb::TemplatedSearchInMap(list, key.value_.uinteger, offsets, key.is_null, entry.offset, - entry.length); + case PhysicalType::INT16: + TemplatedSearchInMap(list, key, offsets, key.IsNull(), entry.offset, entry.length); break; - case LogicalTypeId::INTEGER: - ::duckdb::TemplatedSearchInMap(list, key.value_.integer, offsets, key.is_null, entry.offset, - entry.length); + case PhysicalType::INT32: + TemplatedSearchInMap(list, key, offsets, key.IsNull(), entry.offset, entry.length); break; - case LogicalTypeId::UBIGINT: - ::duckdb::TemplatedSearchInMap(list, key.value_.ubigint, offsets, key.is_null, entry.offset, - entry.length); + case PhysicalType::INT64: + TemplatedSearchInMap(list, key, offsets, key.IsNull(), entry.offset, entry.length); break; - case LogicalTypeId::BIGINT: - ::duckdb::TemplatedSearchInMap(list, key.value_.bigint, offsets, key.is_null, entry.offset, - entry.length); + case PhysicalType::INT128: + TemplatedSearchInMap(list, key, offsets, key.IsNull(), entry.offset, entry.length); break; - case LogicalTypeId::HUGEINT: - ::duckdb::TemplatedSearchInMap(list, key.value_.hugeint, offsets, key.is_null, entry.offset, - entry.length); + case PhysicalType::UINT8: + TemplatedSearchInMap(list, key, offsets, key.IsNull(), entry.offset, entry.length); break; - case LogicalTypeId::FLOAT: - ::duckdb::TemplatedSearchInMap(list, key.value_.float_, offsets, key.is_null, entry.offset, - entry.length); + case PhysicalType::UINT16: + TemplatedSearchInMap(list, key, offsets, key.IsNull(), entry.offset, entry.length); break; - case LogicalTypeId::DOUBLE: - ::duckdb::TemplatedSearchInMap(list, key.value_.double_, offsets, key.is_null, entry.offset, - entry.length); + case PhysicalType::UINT32: + TemplatedSearchInMap(list, key, offsets, key.IsNull(), entry.offset, entry.length); break; - case LogicalTypeId::DATE: - ::duckdb::TemplatedSearchInMap(list, key.value_.date, offsets, key.is_null, entry.offset, entry.length); + case PhysicalType::UINT64: + TemplatedSearchInMap(list, key, offsets, key.IsNull(), entry.offset, entry.length); break; - case LogicalTypeId::TIME: - ::duckdb::TemplatedSearchInMap(list, key.value_.time, offsets, key.is_null, entry.offset, - entry.length); + case PhysicalType::FLOAT: + TemplatedSearchInMap(list, key, offsets, key.IsNull(), entry.offset, entry.length); break; - case LogicalTypeId::TIMESTAMP: - ::duckdb::TemplatedSearchInMap(list, key.value_.timestamp, offsets, key.is_null, entry.offset, - entry.length); + case PhysicalType::DOUBLE: + TemplatedSearchInMap(list, key, offsets, key.IsNull(), entry.offset, entry.length); break; - case LogicalTypeId::BLOB: - case LogicalTypeId::VARCHAR: - ::duckdb::SearchString(list, key.str_value, offsets, key.is_null, entry.offset, entry.length); + case PhysicalType::VARCHAR: + SearchStringInMap(list, StringValue::Get(key), offsets, key.IsNull(), entry.offset, entry.length); break; default: throw InvalidTypeException(list.GetType().id(), "Invalid type for List Vector Search"); @@ -41218,13 +40454,13 @@ vector ListVector::Search(Vector &list, Value &key, idx_t row) { } Value ListVector::GetValuesFromOffsets(Vector &list, vector &offsets) { - Value ret(ListType::GetChildType(list.GetType())); - ret.is_null = false; auto &child_vec = ListVector::GetEntry(list); + vector list_values; + list_values.reserve(offsets.size()); for (auto &offset : offsets) { - ret.list_value.push_back(child_vec.GetValue(offset)); + list_values.push_back(child_vec.GetValue(offset)); } - return ret; + return Value::LIST(ListType::GetChildType(list.GetType()), move(list_values)); } idx_t ListVector::GetListSize(const Vector &vec) { @@ -41272,7 +40508,7 @@ void ListVector::Append(Vector &target, const Vector &source, const SelectionVec target_buffer.Append(source, sel, source_size, source_offset); } -void ListVector::PushBack(Vector &target, Value &insert) { +void ListVector::PushBack(Vector &target, const Value &insert) { auto &target_buffer = (VectorListBuffer &)*target.auxiliary; target_buffer.PushBack(insert); } @@ -41357,7 +40593,7 @@ void VectorListBuffer::Append(const Vector &to_append, const SelectionVector &se size += to_append_size - source_offset; } -void VectorListBuffer::PushBack(Value &insert) { +void VectorListBuffer::PushBack(const Value &insert) { if (size + 1 > capacity) { child->Resize(capacity, capacity * 2); capacity *= 2; @@ -41489,459 +40725,31 @@ const LogicalType &VectorCache::GetType() const { namespace duckdb { -const SelectionVector ConstantVector::ZERO_SELECTION_VECTOR = SelectionVector((sel_t *)ConstantVector::ZERO_VECTOR); -const SelectionVector FlatVector::INCREMENTAL_SELECTION_VECTOR; +// We disable Wexit-time-destructors here +// Otherwise we get a warning about the two selection vectors (ZERO/INCREMENTAL_SELECTION_VECTOR) +// While the SelectionVector does have a non-trivial destructor +// This only does a memory de-allocation if the selection vectors own their data (i.e. selection_data is not null) +// In the case of the FlatVector/ConstantVector, they point towards static regions of memory +// Hence in this case these cause no problems, as the destructors are non-trivial but effectively nops +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wexit-time-destructors" +#endif + +const SelectionVector *ConstantVector::ZeroSelectionVector() { + static const SelectionVector ZERO_SELECTION_VECTOR = SelectionVector((sel_t *)ConstantVector::ZERO_VECTOR); + return &ZERO_SELECTION_VECTOR; +} + +const SelectionVector *FlatVector::IncrementalSelectionVector() { + static const SelectionVector INCREMENTAL_SELECTION_VECTOR; + return &INCREMENTAL_SELECTION_VECTOR; +} + const sel_t ConstantVector::ZERO_VECTOR[STANDARD_VECTOR_SIZE] = {0}; -#if STANDARD_VECTOR_SIZE == 2 -const sel_t FlatVector::INCREMENTAL_VECTOR[] = {0, 1}; -#elif STANDARD_VECTOR_SIZE == 4 -const sel_t FlatVector::INCREMENTAL_VECTOR[] = {0, 1, 2, 3}; -#elif STANDARD_VECTOR_SIZE == 8 -const sel_t FlatVector::INCREMENTAL_VECTOR[] = {0, 1, 2, 3, 4, 5, 6, 7}; -#elif STANDARD_VECTOR_SIZE == 16 -const sel_t FlatVector::INCREMENTAL_VECTOR[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; -#elif STANDARD_VECTOR_SIZE == 32 -const sel_t FlatVector::INCREMENTAL_VECTOR[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; -#elif STANDARD_VECTOR_SIZE == 64 -const sel_t FlatVector::INCREMENTAL_VECTOR[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 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, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63}; -#elif STANDARD_VECTOR_SIZE == 128 -const sel_t FlatVector::INCREMENTAL_VECTOR[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 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, 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}; -#elif STANDARD_VECTOR_SIZE == 256 -const sel_t FlatVector::INCREMENTAL_VECTOR[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 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, 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}; -#elif STANDARD_VECTOR_SIZE == 512 -const sel_t FlatVector::INCREMENTAL_VECTOR[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 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, 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, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, - 506, 507, 508, 509, 510, 511}; -#elif STANDARD_VECTOR_SIZE == 1024 -const sel_t FlatVector::INCREMENTAL_VECTOR[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 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, 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, 485, 486, 487, 488, 489, 490, 491, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 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, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, - 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, - 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, - 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, - 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, - 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, - 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, - 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, - 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, - 703, 704, 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, - 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, - 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, - 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, - 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, - 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, - 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, - 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, - 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, - 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, - 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, - 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, - 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, - 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, - 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, - 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023}; -#elif STANDARD_VECTOR_SIZE == 2048 -const sel_t FlatVector::INCREMENTAL_VECTOR[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 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, 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, 485, 486, 487, 488, 489, 490, 491, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 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, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, - 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, - 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, - 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, - 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, - 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, - 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, - 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, - 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, - 703, 704, 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, - 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, - 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, - 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, - 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, - 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, - 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, - 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, - 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, - 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, - 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, - 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, - 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, - 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, - 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, - 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, - 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, - 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, - 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, - 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, - 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, - 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, - 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, - 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, - 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, - 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, - 1216, 1217, 1218, 1219, 1220, 1221, 1222, 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, - 1235, 1236, 1237, 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, - 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267, 1268, 1269, 1270, 1271, 1272, - 1273, 1274, 1275, 1276, 1277, 1278, 1279, 1280, 1281, 1282, 1283, 1284, 1285, 1286, 1287, 1288, 1289, 1290, 1291, - 1292, 1293, 1294, 1295, 1296, 1297, 1298, 1299, 1300, 1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, - 1311, 1312, 1313, 1314, 1315, 1316, 1317, 1318, 1319, 1320, 1321, 1322, 1323, 1324, 1325, 1326, 1327, 1328, 1329, - 1330, 1331, 1332, 1333, 1334, 1335, 1336, 1337, 1338, 1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347, 1348, - 1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359, 1360, 1361, 1362, 1363, 1364, 1365, 1366, 1367, - 1368, 1369, 1370, 1371, 1372, 1373, 1374, 1375, 1376, 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 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, 1413, 1414, 1415, 1416, 1417, 1418, 1419, 1420, 1421, 1422, 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, 1451, 1452, 1453, 1454, 1455, 1456, 1457, 1458, 1459, 1460, 1461, 1462, - 1463, 1464, 1465, 1466, 1467, 1468, 1469, 1470, 1471, 1472, 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1481, - 1482, 1483, 1484, 1485, 1486, 1487, 1488, 1489, 1490, 1491, 1492, 1493, 1494, 1495, 1496, 1497, 1498, 1499, 1500, - 1501, 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1509, 1510, 1511, 1512, 1513, 1514, 1515, 1516, 1517, 1518, 1519, - 1520, 1521, 1522, 1523, 1524, 1525, 1526, 1527, 1528, 1529, 1530, 1531, 1532, 1533, 1534, 1535, 1536, 1537, 1538, - 1539, 1540, 1541, 1542, 1543, 1544, 1545, 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553, 1554, 1555, 1556, 1557, - 1558, 1559, 1560, 1561, 1562, 1563, 1564, 1565, 1566, 1567, 1568, 1569, 1570, 1571, 1572, 1573, 1574, 1575, 1576, - 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, 1595, - 1596, 1597, 1598, 1599, 1600, 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, - 1615, 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, 1624, 1625, 1626, 1627, 1628, 1629, 1630, 1631, 1632, 1633, - 1634, 1635, 1636, 1637, 1638, 1639, 1640, 1641, 1642, 1643, 1644, 1645, 1646, 1647, 1648, 1649, 1650, 1651, 1652, - 1653, 1654, 1655, 1656, 1657, 1658, 1659, 1660, 1661, 1662, 1663, 1664, 1665, 1666, 1667, 1668, 1669, 1670, 1671, - 1672, 1673, 1674, 1675, 1676, 1677, 1678, 1679, 1680, 1681, 1682, 1683, 1684, 1685, 1686, 1687, 1688, 1689, 1690, - 1691, 1692, 1693, 1694, 1695, 1696, 1697, 1698, 1699, 1700, 1701, 1702, 1703, 1704, 1705, 1706, 1707, 1708, 1709, - 1710, 1711, 1712, 1713, 1714, 1715, 1716, 1717, 1718, 1719, 1720, 1721, 1722, 1723, 1724, 1725, 1726, 1727, 1728, - 1729, 1730, 1731, 1732, 1733, 1734, 1735, 1736, 1737, 1738, 1739, 1740, 1741, 1742, 1743, 1744, 1745, 1746, 1747, - 1748, 1749, 1750, 1751, 1752, 1753, 1754, 1755, 1756, 1757, 1758, 1759, 1760, 1761, 1762, 1763, 1764, 1765, 1766, - 1767, 1768, 1769, 1770, 1771, 1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, 1782, 1783, 1784, 1785, - 1786, 1787, 1788, 1789, 1790, 1791, 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799, 1800, 1801, 1802, 1803, 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, 1838, 1839, 1840, 1841, 1842, - 1843, 1844, 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, 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, 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, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, - 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, - 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, 2030, 2031, 2032, - 2033, 2034, 2035, 2036, 2037, 2038, 2039, 2040, 2041, 2042, 2043, 2044, 2045, 2046, 2047}; -#elif STANDARD_VECTOR_SIZE == 4096 -const sel_t FlatVector::INCREMENTAL_VECTOR[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 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, 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, 485, 486, 487, 488, 489, 490, 491, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 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, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, - 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, - 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, - 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, - 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, - 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, - 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, - 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, - 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, - 703, 704, 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, - 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, - 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, - 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, - 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, - 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, - 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, - 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, - 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, - 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, - 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, - 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, - 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, - 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, - 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, - 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, - 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, - 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, - 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, - 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, - 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, - 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, - 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, - 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, - 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, - 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, - 1216, 1217, 1218, 1219, 1220, 1221, 1222, 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, - 1235, 1236, 1237, 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, - 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267, 1268, 1269, 1270, 1271, 1272, - 1273, 1274, 1275, 1276, 1277, 1278, 1279, 1280, 1281, 1282, 1283, 1284, 1285, 1286, 1287, 1288, 1289, 1290, 1291, - 1292, 1293, 1294, 1295, 1296, 1297, 1298, 1299, 1300, 1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, - 1311, 1312, 1313, 1314, 1315, 1316, 1317, 1318, 1319, 1320, 1321, 1322, 1323, 1324, 1325, 1326, 1327, 1328, 1329, - 1330, 1331, 1332, 1333, 1334, 1335, 1336, 1337, 1338, 1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347, 1348, - 1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359, 1360, 1361, 1362, 1363, 1364, 1365, 1366, 1367, - 1368, 1369, 1370, 1371, 1372, 1373, 1374, 1375, 1376, 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 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, 1413, 1414, 1415, 1416, 1417, 1418, 1419, 1420, 1421, 1422, 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, 1451, 1452, 1453, 1454, 1455, 1456, 1457, 1458, 1459, 1460, 1461, 1462, - 1463, 1464, 1465, 1466, 1467, 1468, 1469, 1470, 1471, 1472, 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1481, - 1482, 1483, 1484, 1485, 1486, 1487, 1488, 1489, 1490, 1491, 1492, 1493, 1494, 1495, 1496, 1497, 1498, 1499, 1500, - 1501, 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1509, 1510, 1511, 1512, 1513, 1514, 1515, 1516, 1517, 1518, 1519, - 1520, 1521, 1522, 1523, 1524, 1525, 1526, 1527, 1528, 1529, 1530, 1531, 1532, 1533, 1534, 1535, 1536, 1537, 1538, - 1539, 1540, 1541, 1542, 1543, 1544, 1545, 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553, 1554, 1555, 1556, 1557, - 1558, 1559, 1560, 1561, 1562, 1563, 1564, 1565, 1566, 1567, 1568, 1569, 1570, 1571, 1572, 1573, 1574, 1575, 1576, - 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, 1595, - 1596, 1597, 1598, 1599, 1600, 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, - 1615, 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, 1624, 1625, 1626, 1627, 1628, 1629, 1630, 1631, 1632, 1633, - 1634, 1635, 1636, 1637, 1638, 1639, 1640, 1641, 1642, 1643, 1644, 1645, 1646, 1647, 1648, 1649, 1650, 1651, 1652, - 1653, 1654, 1655, 1656, 1657, 1658, 1659, 1660, 1661, 1662, 1663, 1664, 1665, 1666, 1667, 1668, 1669, 1670, 1671, - 1672, 1673, 1674, 1675, 1676, 1677, 1678, 1679, 1680, 1681, 1682, 1683, 1684, 1685, 1686, 1687, 1688, 1689, 1690, - 1691, 1692, 1693, 1694, 1695, 1696, 1697, 1698, 1699, 1700, 1701, 1702, 1703, 1704, 1705, 1706, 1707, 1708, 1709, - 1710, 1711, 1712, 1713, 1714, 1715, 1716, 1717, 1718, 1719, 1720, 1721, 1722, 1723, 1724, 1725, 1726, 1727, 1728, - 1729, 1730, 1731, 1732, 1733, 1734, 1735, 1736, 1737, 1738, 1739, 1740, 1741, 1742, 1743, 1744, 1745, 1746, 1747, - 1748, 1749, 1750, 1751, 1752, 1753, 1754, 1755, 1756, 1757, 1758, 1759, 1760, 1761, 1762, 1763, 1764, 1765, 1766, - 1767, 1768, 1769, 1770, 1771, 1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, 1782, 1783, 1784, 1785, - 1786, 1787, 1788, 1789, 1790, 1791, 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799, 1800, 1801, 1802, 1803, 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, 1838, 1839, 1840, 1841, 1842, - 1843, 1844, 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, 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, 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, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, - 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, - 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, 2030, 2031, 2032, - 2033, 2034, 2035, 2036, 2037, 2038, 2039, 2040, 2041, 2042, 2043, 2044, 2045, 2046, 2047, 2048, 2049, 2050, 2051, - 2052, 2053, 2054, 2055, 2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063, 2064, 2065, 2066, 2067, 2068, 2069, 2070, - 2071, 2072, 2073, 2074, 2075, 2076, 2077, 2078, 2079, 2080, 2081, 2082, 2083, 2084, 2085, 2086, 2087, 2088, 2089, - 2090, 2091, 2092, 2093, 2094, 2095, 2096, 2097, 2098, 2099, 2100, 2101, 2102, 2103, 2104, 2105, 2106, 2107, 2108, - 2109, 2110, 2111, 2112, 2113, 2114, 2115, 2116, 2117, 2118, 2119, 2120, 2121, 2122, 2123, 2124, 2125, 2126, 2127, - 2128, 2129, 2130, 2131, 2132, 2133, 2134, 2135, 2136, 2137, 2138, 2139, 2140, 2141, 2142, 2143, 2144, 2145, 2146, - 2147, 2148, 2149, 2150, 2151, 2152, 2153, 2154, 2155, 2156, 2157, 2158, 2159, 2160, 2161, 2162, 2163, 2164, 2165, - 2166, 2167, 2168, 2169, 2170, 2171, 2172, 2173, 2174, 2175, 2176, 2177, 2178, 2179, 2180, 2181, 2182, 2183, 2184, - 2185, 2186, 2187, 2188, 2189, 2190, 2191, 2192, 2193, 2194, 2195, 2196, 2197, 2198, 2199, 2200, 2201, 2202, 2203, - 2204, 2205, 2206, 2207, 2208, 2209, 2210, 2211, 2212, 2213, 2214, 2215, 2216, 2217, 2218, 2219, 2220, 2221, 2222, - 2223, 2224, 2225, 2226, 2227, 2228, 2229, 2230, 2231, 2232, 2233, 2234, 2235, 2236, 2237, 2238, 2239, 2240, 2241, - 2242, 2243, 2244, 2245, 2246, 2247, 2248, 2249, 2250, 2251, 2252, 2253, 2254, 2255, 2256, 2257, 2258, 2259, 2260, - 2261, 2262, 2263, 2264, 2265, 2266, 2267, 2268, 2269, 2270, 2271, 2272, 2273, 2274, 2275, 2276, 2277, 2278, 2279, - 2280, 2281, 2282, 2283, 2284, 2285, 2286, 2287, 2288, 2289, 2290, 2291, 2292, 2293, 2294, 2295, 2296, 2297, 2298, - 2299, 2300, 2301, 2302, 2303, 2304, 2305, 2306, 2307, 2308, 2309, 2310, 2311, 2312, 2313, 2314, 2315, 2316, 2317, - 2318, 2319, 2320, 2321, 2322, 2323, 2324, 2325, 2326, 2327, 2328, 2329, 2330, 2331, 2332, 2333, 2334, 2335, 2336, - 2337, 2338, 2339, 2340, 2341, 2342, 2343, 2344, 2345, 2346, 2347, 2348, 2349, 2350, 2351, 2352, 2353, 2354, 2355, - 2356, 2357, 2358, 2359, 2360, 2361, 2362, 2363, 2364, 2365, 2366, 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, - 2375, 2376, 2377, 2378, 2379, 2380, 2381, 2382, 2383, 2384, 2385, 2386, 2387, 2388, 2389, 2390, 2391, 2392, 2393, - 2394, 2395, 2396, 2397, 2398, 2399, 2400, 2401, 2402, 2403, 2404, 2405, 2406, 2407, 2408, 2409, 2410, 2411, 2412, - 2413, 2414, 2415, 2416, 2417, 2418, 2419, 2420, 2421, 2422, 2423, 2424, 2425, 2426, 2427, 2428, 2429, 2430, 2431, - 2432, 2433, 2434, 2435, 2436, 2437, 2438, 2439, 2440, 2441, 2442, 2443, 2444, 2445, 2446, 2447, 2448, 2449, 2450, - 2451, 2452, 2453, 2454, 2455, 2456, 2457, 2458, 2459, 2460, 2461, 2462, 2463, 2464, 2465, 2466, 2467, 2468, 2469, - 2470, 2471, 2472, 2473, 2474, 2475, 2476, 2477, 2478, 2479, 2480, 2481, 2482, 2483, 2484, 2485, 2486, 2487, 2488, - 2489, 2490, 2491, 2492, 2493, 2494, 2495, 2496, 2497, 2498, 2499, 2500, 2501, 2502, 2503, 2504, 2505, 2506, 2507, - 2508, 2509, 2510, 2511, 2512, 2513, 2514, 2515, 2516, 2517, 2518, 2519, 2520, 2521, 2522, 2523, 2524, 2525, 2526, - 2527, 2528, 2529, 2530, 2531, 2532, 2533, 2534, 2535, 2536, 2537, 2538, 2539, 2540, 2541, 2542, 2543, 2544, 2545, - 2546, 2547, 2548, 2549, 2550, 2551, 2552, 2553, 2554, 2555, 2556, 2557, 2558, 2559, 2560, 2561, 2562, 2563, 2564, - 2565, 2566, 2567, 2568, 2569, 2570, 2571, 2572, 2573, 2574, 2575, 2576, 2577, 2578, 2579, 2580, 2581, 2582, 2583, - 2584, 2585, 2586, 2587, 2588, 2589, 2590, 2591, 2592, 2593, 2594, 2595, 2596, 2597, 2598, 2599, 2600, 2601, 2602, - 2603, 2604, 2605, 2606, 2607, 2608, 2609, 2610, 2611, 2612, 2613, 2614, 2615, 2616, 2617, 2618, 2619, 2620, 2621, - 2622, 2623, 2624, 2625, 2626, 2627, 2628, 2629, 2630, 2631, 2632, 2633, 2634, 2635, 2636, 2637, 2638, 2639, 2640, - 2641, 2642, 2643, 2644, 2645, 2646, 2647, 2648, 2649, 2650, 2651, 2652, 2653, 2654, 2655, 2656, 2657, 2658, 2659, - 2660, 2661, 2662, 2663, 2664, 2665, 2666, 2667, 2668, 2669, 2670, 2671, 2672, 2673, 2674, 2675, 2676, 2677, 2678, - 2679, 2680, 2681, 2682, 2683, 2684, 2685, 2686, 2687, 2688, 2689, 2690, 2691, 2692, 2693, 2694, 2695, 2696, 2697, - 2698, 2699, 2700, 2701, 2702, 2703, 2704, 2705, 2706, 2707, 2708, 2709, 2710, 2711, 2712, 2713, 2714, 2715, 2716, - 2717, 2718, 2719, 2720, 2721, 2722, 2723, 2724, 2725, 2726, 2727, 2728, 2729, 2730, 2731, 2732, 2733, 2734, 2735, - 2736, 2737, 2738, 2739, 2740, 2741, 2742, 2743, 2744, 2745, 2746, 2747, 2748, 2749, 2750, 2751, 2752, 2753, 2754, - 2755, 2756, 2757, 2758, 2759, 2760, 2761, 2762, 2763, 2764, 2765, 2766, 2767, 2768, 2769, 2770, 2771, 2772, 2773, - 2774, 2775, 2776, 2777, 2778, 2779, 2780, 2781, 2782, 2783, 2784, 2785, 2786, 2787, 2788, 2789, 2790, 2791, 2792, - 2793, 2794, 2795, 2796, 2797, 2798, 2799, 2800, 2801, 2802, 2803, 2804, 2805, 2806, 2807, 2808, 2809, 2810, 2811, - 2812, 2813, 2814, 2815, 2816, 2817, 2818, 2819, 2820, 2821, 2822, 2823, 2824, 2825, 2826, 2827, 2828, 2829, 2830, - 2831, 2832, 2833, 2834, 2835, 2836, 2837, 2838, 2839, 2840, 2841, 2842, 2843, 2844, 2845, 2846, 2847, 2848, 2849, - 2850, 2851, 2852, 2853, 2854, 2855, 2856, 2857, 2858, 2859, 2860, 2861, 2862, 2863, 2864, 2865, 2866, 2867, 2868, - 2869, 2870, 2871, 2872, 2873, 2874, 2875, 2876, 2877, 2878, 2879, 2880, 2881, 2882, 2883, 2884, 2885, 2886, 2887, - 2888, 2889, 2890, 2891, 2892, 2893, 2894, 2895, 2896, 2897, 2898, 2899, 2900, 2901, 2902, 2903, 2904, 2905, 2906, - 2907, 2908, 2909, 2910, 2911, 2912, 2913, 2914, 2915, 2916, 2917, 2918, 2919, 2920, 2921, 2922, 2923, 2924, 2925, - 2926, 2927, 2928, 2929, 2930, 2931, 2932, 2933, 2934, 2935, 2936, 2937, 2938, 2939, 2940, 2941, 2942, 2943, 2944, - 2945, 2946, 2947, 2948, 2949, 2950, 2951, 2952, 2953, 2954, 2955, 2956, 2957, 2958, 2959, 2960, 2961, 2962, 2963, - 2964, 2965, 2966, 2967, 2968, 2969, 2970, 2971, 2972, 2973, 2974, 2975, 2976, 2977, 2978, 2979, 2980, 2981, 2982, - 2983, 2984, 2985, 2986, 2987, 2988, 2989, 2990, 2991, 2992, 2993, 2994, 2995, 2996, 2997, 2998, 2999, 3000, 3001, - 3002, 3003, 3004, 3005, 3006, 3007, 3008, 3009, 3010, 3011, 3012, 3013, 3014, 3015, 3016, 3017, 3018, 3019, 3020, - 3021, 3022, 3023, 3024, 3025, 3026, 3027, 3028, 3029, 3030, 3031, 3032, 3033, 3034, 3035, 3036, 3037, 3038, 3039, - 3040, 3041, 3042, 3043, 3044, 3045, 3046, 3047, 3048, 3049, 3050, 3051, 3052, 3053, 3054, 3055, 3056, 3057, 3058, - 3059, 3060, 3061, 3062, 3063, 3064, 3065, 3066, 3067, 3068, 3069, 3070, 3071, 3072, 3073, 3074, 3075, 3076, 3077, - 3078, 3079, 3080, 3081, 3082, 3083, 3084, 3085, 3086, 3087, 3088, 3089, 3090, 3091, 3092, 3093, 3094, 3095, 3096, - 3097, 3098, 3099, 3100, 3101, 3102, 3103, 3104, 3105, 3106, 3107, 3108, 3109, 3110, 3111, 3112, 3113, 3114, 3115, - 3116, 3117, 3118, 3119, 3120, 3121, 3122, 3123, 3124, 3125, 3126, 3127, 3128, 3129, 3130, 3131, 3132, 3133, 3134, - 3135, 3136, 3137, 3138, 3139, 3140, 3141, 3142, 3143, 3144, 3145, 3146, 3147, 3148, 3149, 3150, 3151, 3152, 3153, - 3154, 3155, 3156, 3157, 3158, 3159, 3160, 3161, 3162, 3163, 3164, 3165, 3166, 3167, 3168, 3169, 3170, 3171, 3172, - 3173, 3174, 3175, 3176, 3177, 3178, 3179, 3180, 3181, 3182, 3183, 3184, 3185, 3186, 3187, 3188, 3189, 3190, 3191, - 3192, 3193, 3194, 3195, 3196, 3197, 3198, 3199, 3200, 3201, 3202, 3203, 3204, 3205, 3206, 3207, 3208, 3209, 3210, - 3211, 3212, 3213, 3214, 3215, 3216, 3217, 3218, 3219, 3220, 3221, 3222, 3223, 3224, 3225, 3226, 3227, 3228, 3229, - 3230, 3231, 3232, 3233, 3234, 3235, 3236, 3237, 3238, 3239, 3240, 3241, 3242, 3243, 3244, 3245, 3246, 3247, 3248, - 3249, 3250, 3251, 3252, 3253, 3254, 3255, 3256, 3257, 3258, 3259, 3260, 3261, 3262, 3263, 3264, 3265, 3266, 3267, - 3268, 3269, 3270, 3271, 3272, 3273, 3274, 3275, 3276, 3277, 3278, 3279, 3280, 3281, 3282, 3283, 3284, 3285, 3286, - 3287, 3288, 3289, 3290, 3291, 3292, 3293, 3294, 3295, 3296, 3297, 3298, 3299, 3300, 3301, 3302, 3303, 3304, 3305, - 3306, 3307, 3308, 3309, 3310, 3311, 3312, 3313, 3314, 3315, 3316, 3317, 3318, 3319, 3320, 3321, 3322, 3323, 3324, - 3325, 3326, 3327, 3328, 3329, 3330, 3331, 3332, 3333, 3334, 3335, 3336, 3337, 3338, 3339, 3340, 3341, 3342, 3343, - 3344, 3345, 3346, 3347, 3348, 3349, 3350, 3351, 3352, 3353, 3354, 3355, 3356, 3357, 3358, 3359, 3360, 3361, 3362, - 3363, 3364, 3365, 3366, 3367, 3368, 3369, 3370, 3371, 3372, 3373, 3374, 3375, 3376, 3377, 3378, 3379, 3380, 3381, - 3382, 3383, 3384, 3385, 3386, 3387, 3388, 3389, 3390, 3391, 3392, 3393, 3394, 3395, 3396, 3397, 3398, 3399, 3400, - 3401, 3402, 3403, 3404, 3405, 3406, 3407, 3408, 3409, 3410, 3411, 3412, 3413, 3414, 3415, 3416, 3417, 3418, 3419, - 3420, 3421, 3422, 3423, 3424, 3425, 3426, 3427, 3428, 3429, 3430, 3431, 3432, 3433, 3434, 3435, 3436, 3437, 3438, - 3439, 3440, 3441, 3442, 3443, 3444, 3445, 3446, 3447, 3448, 3449, 3450, 3451, 3452, 3453, 3454, 3455, 3456, 3457, - 3458, 3459, 3460, 3461, 3462, 3463, 3464, 3465, 3466, 3467, 3468, 3469, 3470, 3471, 3472, 3473, 3474, 3475, 3476, - 3477, 3478, 3479, 3480, 3481, 3482, 3483, 3484, 3485, 3486, 3487, 3488, 3489, 3490, 3491, 3492, 3493, 3494, 3495, - 3496, 3497, 3498, 3499, 3500, 3501, 3502, 3503, 3504, 3505, 3506, 3507, 3508, 3509, 3510, 3511, 3512, 3513, 3514, - 3515, 3516, 3517, 3518, 3519, 3520, 3521, 3522, 3523, 3524, 3525, 3526, 3527, 3528, 3529, 3530, 3531, 3532, 3533, - 3534, 3535, 3536, 3537, 3538, 3539, 3540, 3541, 3542, 3543, 3544, 3545, 3546, 3547, 3548, 3549, 3550, 3551, 3552, - 3553, 3554, 3555, 3556, 3557, 3558, 3559, 3560, 3561, 3562, 3563, 3564, 3565, 3566, 3567, 3568, 3569, 3570, 3571, - 3572, 3573, 3574, 3575, 3576, 3577, 3578, 3579, 3580, 3581, 3582, 3583, 3584, 3585, 3586, 3587, 3588, 3589, 3590, - 3591, 3592, 3593, 3594, 3595, 3596, 3597, 3598, 3599, 3600, 3601, 3602, 3603, 3604, 3605, 3606, 3607, 3608, 3609, - 3610, 3611, 3612, 3613, 3614, 3615, 3616, 3617, 3618, 3619, 3620, 3621, 3622, 3623, 3624, 3625, 3626, 3627, 3628, - 3629, 3630, 3631, 3632, 3633, 3634, 3635, 3636, 3637, 3638, 3639, 3640, 3641, 3642, 3643, 3644, 3645, 3646, 3647, - 3648, 3649, 3650, 3651, 3652, 3653, 3654, 3655, 3656, 3657, 3658, 3659, 3660, 3661, 3662, 3663, 3664, 3665, 3666, - 3667, 3668, 3669, 3670, 3671, 3672, 3673, 3674, 3675, 3676, 3677, 3678, 3679, 3680, 3681, 3682, 3683, 3684, 3685, - 3686, 3687, 3688, 3689, 3690, 3691, 3692, 3693, 3694, 3695, 3696, 3697, 3698, 3699, 3700, 3701, 3702, 3703, 3704, - 3705, 3706, 3707, 3708, 3709, 3710, 3711, 3712, 3713, 3714, 3715, 3716, 3717, 3718, 3719, 3720, 3721, 3722, 3723, - 3724, 3725, 3726, 3727, 3728, 3729, 3730, 3731, 3732, 3733, 3734, 3735, 3736, 3737, 3738, 3739, 3740, 3741, 3742, - 3743, 3744, 3745, 3746, 3747, 3748, 3749, 3750, 3751, 3752, 3753, 3754, 3755, 3756, 3757, 3758, 3759, 3760, 3761, - 3762, 3763, 3764, 3765, 3766, 3767, 3768, 3769, 3770, 3771, 3772, 3773, 3774, 3775, 3776, 3777, 3778, 3779, 3780, - 3781, 3782, 3783, 3784, 3785, 3786, 3787, 3788, 3789, 3790, 3791, 3792, 3793, 3794, 3795, 3796, 3797, 3798, 3799, - 3800, 3801, 3802, 3803, 3804, 3805, 3806, 3807, 3808, 3809, 3810, 3811, 3812, 3813, 3814, 3815, 3816, 3817, 3818, - 3819, 3820, 3821, 3822, 3823, 3824, 3825, 3826, 3827, 3828, 3829, 3830, 3831, 3832, 3833, 3834, 3835, 3836, 3837, - 3838, 3839, 3840, 3841, 3842, 3843, 3844, 3845, 3846, 3847, 3848, 3849, 3850, 3851, 3852, 3853, 3854, 3855, 3856, - 3857, 3858, 3859, 3860, 3861, 3862, 3863, 3864, 3865, 3866, 3867, 3868, 3869, 3870, 3871, 3872, 3873, 3874, 3875, - 3876, 3877, 3878, 3879, 3880, 3881, 3882, 3883, 3884, 3885, 3886, 3887, 3888, 3889, 3890, 3891, 3892, 3893, 3894, - 3895, 3896, 3897, 3898, 3899, 3900, 3901, 3902, 3903, 3904, 3905, 3906, 3907, 3908, 3909, 3910, 3911, 3912, 3913, - 3914, 3915, 3916, 3917, 3918, 3919, 3920, 3921, 3922, 3923, 3924, 3925, 3926, 3927, 3928, 3929, 3930, 3931, 3932, - 3933, 3934, 3935, 3936, 3937, 3938, 3939, 3940, 3941, 3942, 3943, 3944, 3945, 3946, 3947, 3948, 3949, 3950, 3951, - 3952, 3953, 3954, 3955, 3956, 3957, 3958, 3959, 3960, 3961, 3962, 3963, 3964, 3965, 3966, 3967, 3968, 3969, 3970, - 3971, 3972, 3973, 3974, 3975, 3976, 3977, 3978, 3979, 3980, 3981, 3982, 3983, 3984, 3985, 3986, 3987, 3988, 3989, - 3990, 3991, 3992, 3993, 3994, 3995, 3996, 3997, 3998, 3999, 4000, 4001, 4002, 4003, 4004, 4005, 4006, 4007, 4008, - 4009, 4010, 4011, 4012, 4013, 4014, 4015, 4016, 4017, 4018, 4019, 4020, 4021, 4022, 4023, 4024, 4025, 4026, 4027, - 4028, 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036, 4037, 4038, 4039, 4040, 4041, 4042, 4043, 4044, 4045, 4046, - 4047, 4048, 4049, 4050, 4051, 4052, 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, - 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 4074, 4075, 4076, 4077, 4078, 4079, 4080, 4081, 4082, 4083, 4084, - 4085, 4086, 4087, 4088, 4089, 4090, 4091, 4092, 4093, 4094, 4095}; -#else -#error Unsupported VECTOR_SIZE! +#ifdef __clang__ +#pragma clang diagnostic pop #endif } // namespace duckdb @@ -41961,6 +40769,8 @@ const sel_t FlatVector::INCREMENTAL_VECTOR[] = { + + namespace duckdb { LogicalType::LogicalType() : LogicalType(LogicalTypeId::INVALID) { @@ -41974,6 +40784,14 @@ LogicalType::LogicalType(LogicalTypeId id, shared_ptr type_info_p physical_type_ = GetInternalType(); } +LogicalType::LogicalType(const LogicalType &other) + : id_(other.id_), physical_type_(other.physical_type_), type_info_(other.type_info_) { +} + +LogicalType::LogicalType(LogicalType &&other) noexcept + : id_(other.id_), physical_type_(other.physical_type_), type_info_(move(other.type_info_)) { +} + hash_t LogicalType::Hash() const { return duckdb::Hash((uint8_t)id_); } @@ -42002,6 +40820,8 @@ PhysicalType LogicalType::GetInternalType() { case LogicalTypeId::TIMESTAMP_SEC: case LogicalTypeId::TIMESTAMP_NS: case LogicalTypeId::TIMESTAMP_MS: + case LogicalTypeId::TIME_TZ: + case LogicalTypeId::TIMESTAMP_TZ: return PhysicalType::INT64; case LogicalTypeId::UBIGINT: return PhysicalType::UINT64; @@ -42072,60 +40892,74 @@ PhysicalType LogicalType::GetInternalType() { } } -const LogicalType LogicalType::INVALID = LogicalType(LogicalTypeId::INVALID); -const LogicalType LogicalType::SQLNULL = LogicalType(LogicalTypeId::SQLNULL); -const LogicalType LogicalType::BOOLEAN = LogicalType(LogicalTypeId::BOOLEAN); -const LogicalType LogicalType::TINYINT = LogicalType(LogicalTypeId::TINYINT); -const LogicalType LogicalType::UTINYINT = LogicalType(LogicalTypeId::UTINYINT); -const LogicalType LogicalType::SMALLINT = LogicalType(LogicalTypeId::SMALLINT); -const LogicalType LogicalType::USMALLINT = LogicalType(LogicalTypeId::USMALLINT); -const LogicalType LogicalType::INTEGER = LogicalType(LogicalTypeId::INTEGER); -const LogicalType LogicalType::UINTEGER = LogicalType(LogicalTypeId::UINTEGER); -const LogicalType LogicalType::BIGINT = LogicalType(LogicalTypeId::BIGINT); -const LogicalType LogicalType::UBIGINT = LogicalType(LogicalTypeId::UBIGINT); -const LogicalType LogicalType::HUGEINT = LogicalType(LogicalTypeId::HUGEINT); -const LogicalType LogicalType::UUID = LogicalType(LogicalTypeId::UUID); -const LogicalType LogicalType::FLOAT = LogicalType(LogicalTypeId::FLOAT); -const LogicalType LogicalType::DOUBLE = LogicalType(LogicalTypeId::DOUBLE); -const LogicalType LogicalType::DATE = LogicalType(LogicalTypeId::DATE); +constexpr const LogicalTypeId LogicalType::INVALID; +constexpr const LogicalTypeId LogicalType::SQLNULL; +constexpr const LogicalTypeId LogicalType::BOOLEAN; +constexpr const LogicalTypeId LogicalType::TINYINT; +constexpr const LogicalTypeId LogicalType::UTINYINT; +constexpr const LogicalTypeId LogicalType::SMALLINT; +constexpr const LogicalTypeId LogicalType::USMALLINT; +constexpr const LogicalTypeId LogicalType::INTEGER; +constexpr const LogicalTypeId LogicalType::UINTEGER; +constexpr const LogicalTypeId LogicalType::BIGINT; +constexpr const LogicalTypeId LogicalType::UBIGINT; +constexpr const LogicalTypeId LogicalType::HUGEINT; +constexpr const LogicalTypeId LogicalType::UUID; +constexpr const LogicalTypeId LogicalType::FLOAT; +constexpr const LogicalTypeId LogicalType::DOUBLE; +constexpr const LogicalTypeId LogicalType::DATE; + +constexpr const LogicalTypeId LogicalType::TIMESTAMP; +constexpr const LogicalTypeId LogicalType::TIMESTAMP_MS; +constexpr const LogicalTypeId LogicalType::TIMESTAMP_NS; +constexpr const LogicalTypeId LogicalType::TIMESTAMP_S; -const LogicalType LogicalType::TIMESTAMP = LogicalType(LogicalTypeId::TIMESTAMP); -const LogicalType LogicalType::TIMESTAMP_MS = LogicalType(LogicalTypeId::TIMESTAMP_MS); -const LogicalType LogicalType::TIMESTAMP_NS = LogicalType(LogicalTypeId::TIMESTAMP_NS); -const LogicalType LogicalType::TIMESTAMP_S = LogicalType(LogicalTypeId::TIMESTAMP_SEC); +constexpr const LogicalTypeId LogicalType::TIME; -const LogicalType LogicalType::TIME = LogicalType(LogicalTypeId::TIME); -const LogicalType LogicalType::HASH = LogicalType(LogicalTypeId::HASH); -const LogicalType LogicalType::POINTER = LogicalType(LogicalTypeId::POINTER); +constexpr const LogicalTypeId LogicalType::TIME_TZ; +constexpr const LogicalTypeId LogicalType::TIMESTAMP_TZ; -const LogicalType LogicalType::VARCHAR = LogicalType(LogicalTypeId::VARCHAR); +constexpr const LogicalTypeId LogicalType::HASH; +constexpr const LogicalTypeId LogicalType::POINTER; -const LogicalType LogicalType::BLOB = LogicalType(LogicalTypeId::BLOB); -const LogicalType LogicalType::INTERVAL = LogicalType(LogicalTypeId::INTERVAL); +constexpr const LogicalTypeId LogicalType::VARCHAR; + +constexpr const LogicalTypeId LogicalType::BLOB; +constexpr const LogicalTypeId LogicalType::INTERVAL; +constexpr const LogicalTypeId LogicalType::ROW_TYPE; // TODO these are incomplete and should maybe not exist as such -const LogicalType LogicalType::TABLE = LogicalType(LogicalTypeId::TABLE); +constexpr const LogicalTypeId LogicalType::TABLE; -const LogicalType LogicalType::ANY = LogicalType(LogicalTypeId::ANY); +constexpr const LogicalTypeId LogicalType::ANY; -const vector LogicalType::NUMERIC = {LogicalType::TINYINT, LogicalType::SMALLINT, LogicalType::INTEGER, - LogicalType::BIGINT, LogicalType::HUGEINT, LogicalType::FLOAT, - LogicalType::DOUBLE, LogicalTypeId::DECIMAL, LogicalType::UTINYINT, - LogicalType::USMALLINT, LogicalType::UINTEGER, LogicalType::UBIGINT}; +const vector LogicalType::Numeric() { + vector types = {LogicalType::TINYINT, LogicalType::SMALLINT, LogicalType::INTEGER, + LogicalType::BIGINT, LogicalType::HUGEINT, LogicalType::FLOAT, + LogicalType::DOUBLE, LogicalTypeId::DECIMAL, LogicalType::UTINYINT, + LogicalType::USMALLINT, LogicalType::UINTEGER, LogicalType::UBIGINT}; + return types; +} -const vector LogicalType::INTEGRAL = {LogicalType::TINYINT, LogicalType::SMALLINT, LogicalType::INTEGER, - LogicalType::BIGINT, LogicalType::HUGEINT, LogicalType::UTINYINT, - LogicalType::USMALLINT, LogicalType::UINTEGER, LogicalType::UBIGINT}; +const vector LogicalType::Integral() { + vector types = {LogicalType::TINYINT, LogicalType::SMALLINT, LogicalType::INTEGER, + LogicalType::BIGINT, LogicalType::HUGEINT, LogicalType::UTINYINT, + LogicalType::USMALLINT, LogicalType::UINTEGER, LogicalType::UBIGINT}; + return types; +} -const vector LogicalType::ALL_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, LogicalTypeId::MAP, LogicalType::UUID}; +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, + LogicalType::UUID}; + return types; +} -const LogicalType LOGICAL_ROW_TYPE = LogicalType::BIGINT; const PhysicalType ROW_TYPE = PhysicalType::INT64; // LCOV_EXCL_START @@ -42305,6 +41139,10 @@ string LogicalTypeIdToString(LogicalTypeId id) { return "TIMESTAMP (NS)"; case LogicalTypeId::TIMESTAMP_SEC: return "TIMESTAMP (SEC)"; + case LogicalTypeId::TIMESTAMP_TZ: + return "TIMESTAMP WITH TIME ZONE"; + case LogicalTypeId::TIME_TZ: + return "TIME WITH TIME ZONE"; case LogicalTypeId::FLOAT: return "FLOAT"; case LogicalTypeId::DOUBLE: @@ -42462,6 +41300,10 @@ LogicalTypeId TransformStringToLogicalType(const string &str) { return LogicalTypeId::UINTEGER; } else if (lower_str == "ubigint" || lower_str == "uint64") { return LogicalTypeId::UBIGINT; + } else if (lower_str == "timestamptz") { + return LogicalTypeId::TIMESTAMP_TZ; + } else if (lower_str == "timetz") { + return LogicalTypeId::TIME_TZ; } else { // This is a User Type, at this point we don't know if its one of the User Defined Types or an error // It is checked in the binder @@ -42663,13 +41505,13 @@ struct ExtraTypeInfo { ExtraTypeInfoType type; public: - virtual bool Equals(ExtraTypeInfo *other) = 0; + virtual bool Equals(ExtraTypeInfo *other) const = 0; //! Serializes a ExtraTypeInfo to a stand-alone binary blob - virtual void Serialize(Serializer &serializer) const = 0; + virtual void Serialize(FieldWriter &writer) const = 0; //! Serializes a ExtraTypeInfo to a stand-alone binary blob - static void Serialize(ExtraTypeInfo *info, Serializer &serializer); + static void Serialize(ExtraTypeInfo *info, FieldWriter &writer); //! Deserializes a blob back into an ExtraTypeInfo - static shared_ptr Deserialize(Deserializer &source); + static shared_ptr Deserialize(FieldReader &reader); }; //===--------------------------------------------------------------------===// @@ -42684,7 +41526,7 @@ struct DecimalTypeInfo : public ExtraTypeInfo { uint8_t scale; public: - bool Equals(ExtraTypeInfo *other_p) override { + bool Equals(ExtraTypeInfo *other_p) const override { if (!other_p) { return false; } @@ -42695,14 +41537,14 @@ struct DecimalTypeInfo : public ExtraTypeInfo { return width == other.width && scale == other.scale; } - void Serialize(Serializer &serializer) const override { - serializer.Write(width); - serializer.Write(scale); + void Serialize(FieldWriter &writer) const override { + writer.WriteField(width); + writer.WriteField(scale); } - static shared_ptr Deserialize(Deserializer &source) { - auto width = source.Read(); - auto scale = source.Read(); + static shared_ptr Deserialize(FieldReader &reader) { + auto width = reader.ReadRequired(); + auto scale = reader.ReadRequired(); return make_shared(width, scale); } }; @@ -42737,17 +41579,17 @@ struct StringTypeInfo : public ExtraTypeInfo { string collation; public: - bool Equals(ExtraTypeInfo *other_p) override { + bool Equals(ExtraTypeInfo *other_p) const override { // collation info has no impact on equality return true; } - void Serialize(Serializer &serializer) const override { - serializer.WriteString(collation); + void Serialize(FieldWriter &writer) const override { + writer.WriteString(collation); } - static shared_ptr Deserialize(Deserializer &source) { - auto collation = source.Read(); + static shared_ptr Deserialize(FieldReader &reader) { + auto collation = reader.ReadRequired(); return make_shared(move(collation)); } }; @@ -42779,7 +41621,7 @@ struct ListTypeInfo : public ExtraTypeInfo { LogicalType child_type; public: - bool Equals(ExtraTypeInfo *other_p) override { + bool Equals(ExtraTypeInfo *other_p) const override { if (!other_p) { return false; } @@ -42790,12 +41632,12 @@ struct ListTypeInfo : public ExtraTypeInfo { return child_type == other.child_type; } - void Serialize(Serializer &serializer) const override { - child_type.Serialize(serializer); + void Serialize(FieldWriter &writer) const override { + writer.WriteSerializable(child_type); } - static shared_ptr Deserialize(Deserializer &source) { - auto child_type = LogicalType::Deserialize(source); + static shared_ptr Deserialize(FieldReader &reader) { + auto child_type = reader.ReadRequiredSerializable(); return make_shared(move(child_type)); } }; @@ -42823,7 +41665,7 @@ struct StructTypeInfo : public ExtraTypeInfo { child_list_t child_types; public: - bool Equals(ExtraTypeInfo *other_p) override { + bool Equals(ExtraTypeInfo *other_p) const override { if (!other_p) { return false; } @@ -42834,17 +41676,19 @@ struct StructTypeInfo : public ExtraTypeInfo { return child_types == other.child_types; } - void Serialize(Serializer &serializer) const override { - serializer.Write(child_types.size()); + void Serialize(FieldWriter &writer) const override { + writer.WriteField(child_types.size()); + auto &serializer = writer.GetSerializer(); for (idx_t i = 0; i < child_types.size(); i++) { serializer.WriteString(child_types[i].first); child_types[i].second.Serialize(serializer); } } - static shared_ptr Deserialize(Deserializer &source) { + static shared_ptr Deserialize(FieldReader &reader) { child_list_t child_list; - auto child_types_size = source.Read(); + auto child_types_size = reader.ReadRequired(); + auto &source = reader.GetSource(); for (uint32_t i = 0; i < child_types_size; i++) { auto name = source.Read(); auto type = LogicalType::Deserialize(source); @@ -42882,11 +41726,31 @@ LogicalType LogicalType::STRUCT(child_list_t children) { return LogicalType(LogicalTypeId::STRUCT, 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 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)); +} + +const LogicalType &MapType::KeyType(const LogicalType &type) { + D_ASSERT(type.id() == LogicalTypeId::MAP); + return StructType::GetChildTypes(type)[0].second; +} + +const LogicalType &MapType::ValueType(const LogicalType &type) { + D_ASSERT(type.id() == LogicalTypeId::MAP); + return StructType::GetChildTypes(type)[1].second; +} + //===--------------------------------------------------------------------===// // User Type //===--------------------------------------------------------------------===// @@ -42898,7 +41762,7 @@ struct UserTypeInfo : public ExtraTypeInfo { string user_type_name; public: - bool Equals(ExtraTypeInfo *other_p) override { + bool Equals(ExtraTypeInfo *other_p) const override { if (!other_p) { return false; } @@ -42909,12 +41773,12 @@ struct UserTypeInfo : public ExtraTypeInfo { return other.user_type_name == user_type_name; } - void Serialize(Serializer &serializer) const override { - serializer.WriteString(user_type_name); + void Serialize(FieldWriter &writer) const override { + writer.WriteString(user_type_name); } - static shared_ptr Deserialize(Deserializer &source) { - auto enum_name = source.Read(); + static shared_ptr Deserialize(FieldReader &reader) { + auto enum_name = reader.ReadRequired(); return make_shared(move(enum_name)); } }; @@ -42935,16 +41799,18 @@ LogicalType LogicalType::USER(const string &user_type_name) { // Enum Type //===--------------------------------------------------------------------===// struct EnumTypeInfo : public ExtraTypeInfo { - explicit EnumTypeInfo(string enum_name_p, vector values_insert_order_p) + explicit EnumTypeInfo(string enum_name_p, Vector &values_insert_order_p, idx_t size) : ExtraTypeInfo(ExtraTypeInfoType::ENUM_TYPE_INFO), enum_name(move(enum_name_p)), - values_insert_order(std::move(values_insert_order_p)) { + values_insert_order(values_insert_order_p), size(size) { } string enum_name; - vector values_insert_order; + Vector values_insert_order; + idx_t size; TypeCatalogEntry *catalog_entry = nullptr; public: - bool Equals(ExtraTypeInfo *other_p) override { + // Equalities are only used in enums with different catalog entries + bool Equals(ExtraTypeInfo *other_p) const override { if (!other_p) { return false; } @@ -42952,30 +41818,44 @@ struct EnumTypeInfo : public ExtraTypeInfo { return false; } auto &other = (EnumTypeInfo &)*other_p; - return other.enum_name == enum_name && other.values_insert_order == values_insert_order; + + // We must check if both enums have the same size + if (other.size != size) { + return false; + } + auto other_vector_ptr = FlatVector::GetData(other.values_insert_order); + auto this_vector_ptr = FlatVector::GetData(values_insert_order); + + // Now we must check if all strings are the same + for (idx_t i = 0; i < size; i++) { + if (!Equals::Operation(other_vector_ptr[i], this_vector_ptr[i])) { + return false; + } + } + return true; } - void Serialize(Serializer &serializer) const override { - serializer.Write(values_insert_order.size()); - serializer.WriteString(enum_name); - serializer.WriteStringVector(values_insert_order); + void Serialize(FieldWriter &writer) const override { + writer.WriteField(size); + writer.WriteString(enum_name); + ((Vector &)values_insert_order).Serialize(size, writer.GetSerializer()); } }; template struct EnumTypeInfoTemplated : public EnumTypeInfo { - explicit EnumTypeInfoTemplated(const string &enum_name_p, const vector &values_insert_order_p) - : EnumTypeInfo(enum_name_p, values_insert_order_p) { - idx_t count = 0; - for (auto &value : values_insert_order) { - values[value] = count++; + explicit EnumTypeInfoTemplated(const string &enum_name_p, Vector &values_insert_order_p, idx_t size_p) + : EnumTypeInfo(enum_name_p, values_insert_order_p, size_p) { + for (idx_t count = 0; count < size_p; count++) { + values[values_insert_order_p.GetValue(count).ToString()] = count; } } - static shared_ptr Deserialize(Deserializer &source) { - auto enum_name = source.Read(); - vector values_insert_order; - source.ReadStringVector(values_insert_order); - return make_shared(move(enum_name), move(values_insert_order)); + + static shared_ptr Deserialize(FieldReader &reader, uint32_t size) { + 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); } unordered_map values; }; @@ -42987,20 +41867,19 @@ const string &EnumType::GetTypeName(const LogicalType &type) { return ((EnumTypeInfo &)*info).enum_name; } -LogicalType LogicalType::ENUM(const string &enum_name, const vector &ordered_data) { - auto size = ordered_data.size(); +LogicalType LogicalType::ENUM(const string &enum_name, Vector &ordered_data, idx_t size) { // Generate EnumTypeInfo shared_ptr info; auto enum_internal_type = EnumType::GetPhysicalType(size); switch (enum_internal_type) { case PhysicalType::UINT8: - info = make_shared>(enum_name, ordered_data); + info = make_shared>(enum_name, ordered_data, size); break; case PhysicalType::UINT16: - info = make_shared>(enum_name, ordered_data); + info = make_shared>(enum_name, ordered_data, size); break; case PhysicalType::UINT32: - info = make_shared>(enum_name, ordered_data); + info = make_shared>(enum_name, ordered_data, size); break; default: throw InternalException("Invalid Physical Type for ENUMs"); @@ -43031,22 +41910,13 @@ int64_t EnumType::GetPos(const LogicalType &type, const string &key) { } } -const string &EnumType::GetValue(const Value &val) { +const string EnumType::GetValue(const Value &val) { auto info = val.type().AuxInfo(); - vector &values_insert_order = ((EnumTypeInfo &)*info).values_insert_order; - switch (val.type().InternalType()) { - case PhysicalType::UINT8: - return values_insert_order[val.value_.utinyint]; - case PhysicalType::UINT16: - return values_insert_order[val.value_.usmallint]; - case PhysicalType::UINT32: - return values_insert_order[val.value_.uinteger]; - default: - throw InternalException("Invalid Internal Type for ENUMs"); - } + auto &values_insert_order = ((EnumTypeInfo &)*info).values_insert_order; + return StringValue::Get(values_insert_order.GetValue(val.GetValue())); } -const vector &EnumType::GetValuesInsertOrder(const LogicalType &type) { +Vector &EnumType::GetValuesInsertOrder(const LogicalType &type) { D_ASSERT(type.id() == LogicalTypeId::ENUM); auto info = type.AuxInfo(); D_ASSERT(info); @@ -43057,7 +41927,7 @@ idx_t EnumType::GetSize(const LogicalType &type) { D_ASSERT(type.id() == LogicalTypeId::ENUM); auto info = type.AuxInfo(); D_ASSERT(info); - return ((EnumTypeInfo &)*info).values_insert_order.size(); + return ((EnumTypeInfo &)*info).size; } void EnumType::SetCatalog(LogicalType &type, TypeCatalogEntry *catalog_entry) { @@ -43088,38 +41958,39 @@ PhysicalType EnumType::GetPhysicalType(idx_t size) { //===--------------------------------------------------------------------===// // Extra Type Info //===--------------------------------------------------------------------===// -void ExtraTypeInfo::Serialize(ExtraTypeInfo *info, Serializer &serializer) { +void ExtraTypeInfo::Serialize(ExtraTypeInfo *info, FieldWriter &writer) { if (!info) { - serializer.Write(ExtraTypeInfoType::INVALID_TYPE_INFO); + writer.WriteField(ExtraTypeInfoType::INVALID_TYPE_INFO); } else { - serializer.Write(info->type); - info->Serialize(serializer); + writer.WriteField(info->type); + info->Serialize(writer); } } -shared_ptr ExtraTypeInfo::Deserialize(Deserializer &source) { - auto type = source.Read(); +shared_ptr ExtraTypeInfo::Deserialize(FieldReader &reader) { + auto type = reader.ReadRequired(); switch (type) { case ExtraTypeInfoType::INVALID_TYPE_INFO: return nullptr; case ExtraTypeInfoType::DECIMAL_TYPE_INFO: - return DecimalTypeInfo::Deserialize(source); + return DecimalTypeInfo::Deserialize(reader); case ExtraTypeInfoType::STRING_TYPE_INFO: - return StringTypeInfo::Deserialize(source); + return StringTypeInfo::Deserialize(reader); case ExtraTypeInfoType::LIST_TYPE_INFO: - return ListTypeInfo::Deserialize(source); + return ListTypeInfo::Deserialize(reader); case ExtraTypeInfoType::STRUCT_TYPE_INFO: - return StructTypeInfo::Deserialize(source); + return StructTypeInfo::Deserialize(reader); case ExtraTypeInfoType::USER_TYPE_INFO: - return UserTypeInfo::Deserialize(source); + return UserTypeInfo::Deserialize(reader); case ExtraTypeInfoType::ENUM_TYPE_INFO: { - auto enum_internal_type = EnumType::GetPhysicalType(source.Read()); + auto enum_size = reader.ReadRequired(); + auto enum_internal_type = EnumType::GetPhysicalType(enum_size); switch (enum_internal_type) { case PhysicalType::UINT8: - return EnumTypeInfoTemplated::Deserialize(source); + return EnumTypeInfoTemplated::Deserialize(reader, enum_size); case PhysicalType::UINT16: - return EnumTypeInfoTemplated::Deserialize(source); + return EnumTypeInfoTemplated::Deserialize(reader, enum_size); case PhysicalType::UINT32: - return EnumTypeInfoTemplated::Deserialize(source); + return EnumTypeInfoTemplated::Deserialize(reader, enum_size); default: throw InternalException("Invalid Physical Type for ENUMs"); } @@ -43138,13 +42009,18 @@ LogicalType::~LogicalType() { } void LogicalType::Serialize(Serializer &serializer) const { - serializer.Write(id_); - ExtraTypeInfo::Serialize(type_info_.get(), serializer); + FieldWriter writer(serializer); + writer.WriteField(id_); + ExtraTypeInfo::Serialize(type_info_.get(), writer); + writer.Finalize(); } LogicalType LogicalType::Deserialize(Deserializer &source) { - auto id = source.Read(); - auto info = ExtraTypeInfo::Deserialize(source); + FieldReader reader(source); + auto id = reader.ReadRequired(); + auto info = ExtraTypeInfo::Deserialize(reader); + reader.Finalize(); + return LogicalType(id, move(info)); } @@ -43265,65 +42141,72 @@ static bool TemplatedBooleanOperation(const Value &left, const Value &right) { const auto &left_type = left.type(); const auto &right_type = right.type(); if (left_type != right_type) { - try { - LogicalType comparison_type = BoundComparisonExpression::BindComparison(left_type, right_type); - return TemplatedBooleanOperation(left.CastAs(comparison_type), right.CastAs(comparison_type)); - } catch (...) { + Value left_copy = left; + Value right_copy = right; + + LogicalType comparison_type = BoundComparisonExpression::BindComparison(left_type, right_type); + if (!left_copy.TryCastAs(comparison_type) || !right_copy.TryCastAs(comparison_type)) { return false; } + D_ASSERT(left_copy.type() == right_copy.type()); + return TemplatedBooleanOperation(left_copy, right_copy); } switch (left_type.InternalType()) { case PhysicalType::BOOL: - return OP::Operation(left.value_.boolean, right.value_.boolean); + return OP::Operation(left.GetValueUnsafe(), right.GetValueUnsafe()); case PhysicalType::INT8: - return OP::Operation(left.value_.tinyint, right.value_.tinyint); + return OP::Operation(left.GetValueUnsafe(), right.GetValueUnsafe()); case PhysicalType::INT16: - return OP::Operation(left.value_.smallint, right.value_.smallint); + return OP::Operation(left.GetValueUnsafe(), right.GetValueUnsafe()); case PhysicalType::INT32: - return OP::Operation(left.value_.integer, right.value_.integer); + return OP::Operation(left.GetValueUnsafe(), right.GetValueUnsafe()); case PhysicalType::INT64: - return OP::Operation(left.value_.bigint, right.value_.bigint); + return OP::Operation(left.GetValueUnsafe(), right.GetValueUnsafe()); case PhysicalType::UINT8: - return OP::Operation(left.value_.utinyint, right.value_.utinyint); + return OP::Operation(left.GetValueUnsafe(), right.GetValueUnsafe()); case PhysicalType::UINT16: - return OP::Operation(left.value_.usmallint, right.value_.usmallint); + return OP::Operation(left.GetValueUnsafe(), right.GetValueUnsafe()); case PhysicalType::UINT32: - return OP::Operation(left.value_.uinteger, right.value_.uinteger); + return OP::Operation(left.GetValueUnsafe(), right.GetValueUnsafe()); case PhysicalType::UINT64: - return OP::Operation(left.value_.ubigint, right.value_.ubigint); + return OP::Operation(left.GetValueUnsafe(), right.GetValueUnsafe()); case PhysicalType::INT128: - return OP::Operation(left.value_.hugeint, right.value_.hugeint); + return OP::Operation(left.GetValueUnsafe(), right.GetValueUnsafe()); case PhysicalType::FLOAT: - return OP::Operation(left.value_.float_, right.value_.float_); + return OP::Operation(left.GetValueUnsafe(), right.GetValueUnsafe()); case PhysicalType::DOUBLE: - return OP::Operation(left.value_.double_, right.value_.double_); + return OP::Operation(left.GetValueUnsafe(), right.GetValueUnsafe()); case PhysicalType::INTERVAL: - return OP::Operation(left.value_.interval, right.value_.interval); + return OP::Operation(left.GetValueUnsafe(), right.GetValueUnsafe()); case PhysicalType::VARCHAR: - return OP::Operation(left.str_value, right.str_value); + return OP::Operation(StringValue::Get(left), StringValue::Get(right)); case PhysicalType::STRUCT: { + auto &left_children = StructValue::GetChildren(left); + auto &right_children = StructValue::GetChildren(right); // this should be enforced by the type - D_ASSERT(left.struct_value.size() == right.struct_value.size()); + D_ASSERT(left_children.size() == right_children.size()); idx_t i = 0; - for (; i < left.struct_value.size() - 1; ++i) { - if (ValuePositionComparator::Definite(left.struct_value[i], right.struct_value[i])) { + for (; i < left_children.size() - 1; ++i) { + if (ValuePositionComparator::Definite(left_children[i], right_children[i])) { return true; } - if (!ValuePositionComparator::Possible(left.struct_value[i], right.struct_value[i])) { + if (!ValuePositionComparator::Possible(left_children[i], right_children[i])) { return false; } } - return ValuePositionComparator::Final(left.struct_value[i], right.struct_value[i]); + return ValuePositionComparator::Final(left_children[i], right_children[i]); } case PhysicalType::LIST: { + auto &left_children = ListValue::GetChildren(left); + auto &right_children = ListValue::GetChildren(right); for (idx_t pos = 0;; ++pos) { - if (pos == left.list_value.size() || pos == right.list_value.size()) { - return ValuePositionComparator::TieBreak(left.list_value.size(), right.list_value.size()); + if (pos == left_children.size() || pos == right_children.size()) { + return ValuePositionComparator::TieBreak(left_children.size(), right_children.size()); } - if (ValuePositionComparator::Definite(left.list_value[pos], right.list_value[pos])) { + if (ValuePositionComparator::Definite(left_children[pos], right_children[pos])) { return true; } - if (!ValuePositionComparator::Possible(left.list_value[pos], right.list_value[pos])) { + if (!ValuePositionComparator::Possible(left_children[pos], right_children[pos])) { return false; } } @@ -43335,7 +42218,7 @@ static bool TemplatedBooleanOperation(const Value &left, const Value &right) { } bool ValueOperations::Equals(const Value &left, const Value &right) { - if (left.is_null || right.is_null) { + if (left.IsNull() || right.IsNull()) { throw InternalException("Comparison on NULL values"); } return TemplatedBooleanOperation(left, right); @@ -43346,14 +42229,14 @@ bool ValueOperations::NotEquals(const Value &left, const Value &right) { } bool ValueOperations::GreaterThan(const Value &left, const Value &right) { - if (left.is_null || right.is_null) { + if (left.IsNull() || right.IsNull()) { throw InternalException("Comparison on NULL values"); } return TemplatedBooleanOperation(left, right); } bool ValueOperations::GreaterThanEquals(const Value &left, const Value &right) { - if (left.is_null || right.is_null) { + if (left.IsNull() || right.IsNull()) { throw InternalException("Comparison on NULL values"); } return TemplatedBooleanOperation(left, right); @@ -43368,10 +42251,10 @@ bool ValueOperations::LessThanEquals(const Value &left, const Value &right) { } bool ValueOperations::NotDistinctFrom(const Value &left, const Value &right) { - if (left.is_null && right.is_null) { + if (left.IsNull() && right.IsNull()) { return true; } - if (left.is_null != right.is_null) { + if (left.IsNull() != right.IsNull()) { return false; } return TemplatedBooleanOperation(left, right); @@ -43382,20 +42265,20 @@ bool ValueOperations::DistinctFrom(const Value &left, const Value &right) { } bool ValueOperations::DistinctGreaterThan(const Value &left, const Value &right) { - if (left.is_null && right.is_null) { + if (left.IsNull() && right.IsNull()) { return false; - } else if (right.is_null) { + } else if (right.IsNull()) { return false; - } else if (left.is_null) { + } else if (left.IsNull()) { return true; } return TemplatedBooleanOperation(left, right); } bool ValueOperations::DistinctGreaterThanEquals(const Value &left, const Value &right) { - if (left.is_null) { + if (left.IsNull()) { return true; - } else if (right.is_null) { + } else if (right.IsNull()) { return false; } return TemplatedBooleanOperation(left, right); @@ -43410,297 +42293,6 @@ bool ValueOperations::DistinctLessThanEquals(const Value &left, const Value &rig } } // namespace duckdb - - - - - -namespace duckdb { - -hash_t ValueOperations::Hash(const Value &op) { - if (op.is_null) { - return 0; - } - switch (op.type().InternalType()) { - case PhysicalType::BOOL: - return duckdb::Hash(op.value_.boolean); - case PhysicalType::INT8: - return duckdb::Hash(op.value_.tinyint); - case PhysicalType::INT16: - return duckdb::Hash(op.value_.smallint); - case PhysicalType::INT32: - return duckdb::Hash(op.value_.integer); - case PhysicalType::INT64: - return duckdb::Hash(op.value_.bigint); - case PhysicalType::UINT8: - return duckdb::Hash(op.value_.utinyint); - case PhysicalType::UINT16: - return duckdb::Hash(op.value_.usmallint); - case PhysicalType::UINT32: - return duckdb::Hash(op.value_.uinteger); - case PhysicalType::UINT64: - return duckdb::Hash(op.value_.ubigint); - case PhysicalType::INT128: - return duckdb::Hash(op.value_.hugeint); - case PhysicalType::FLOAT: - return duckdb::Hash(op.value_.float_); - case PhysicalType::DOUBLE: - return duckdb::Hash(op.value_.double_); - case PhysicalType::INTERVAL: - return duckdb::Hash(op.value_.interval); - case PhysicalType::VARCHAR: - return duckdb::Hash(op.str_value.c_str()); - case PhysicalType::LIST: { - hash_t hash = 0; - for (auto &entry : op.list_value) { - hash ^= ValueOperations::Hash(entry); - } - return hash; - } - case PhysicalType::STRUCT: { - hash_t hash = 0; - for (auto &entry : op.struct_value) { - hash ^= ValueOperations::Hash(entry); - } - return hash; - } - default: - throw InternalException("Unimplemented type for value hash"); - } -} - -} // namespace duckdb - - - - - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/operator/subtract.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - -namespace duckdb { - -struct SubtractOperator { - template - static inline TR Operation(TA left, TB right) { - return left - right; - } -}; - -template <> -float SubtractOperator::Operation(float left, float right); -template <> -double SubtractOperator::Operation(double left, double right); -template <> -interval_t SubtractOperator::Operation(interval_t left, interval_t right); -template <> -int64_t SubtractOperator::Operation(date_t left, date_t right); -template <> -date_t SubtractOperator::Operation(date_t left, int32_t right); -template <> -date_t SubtractOperator::Operation(date_t left, interval_t right); -template <> -timestamp_t SubtractOperator::Operation(timestamp_t left, interval_t right); -template <> -interval_t SubtractOperator::Operation(timestamp_t left, timestamp_t right); - -struct TrySubtractOperator { - template - static inline bool Operation(TA left, TB right, TR &result) { - throw InternalException("Unimplemented type for TrySubtractOperator"); - } -}; - -template <> -bool TrySubtractOperator::Operation(uint8_t left, uint8_t right, uint8_t &result); -template <> -bool TrySubtractOperator::Operation(uint16_t left, uint16_t right, uint16_t &result); -template <> -bool TrySubtractOperator::Operation(uint32_t left, uint32_t right, uint32_t &result); -template <> -bool TrySubtractOperator::Operation(uint64_t left, uint64_t right, uint64_t &result); - -template <> -bool TrySubtractOperator::Operation(int8_t left, int8_t right, int8_t &result); -template <> -bool TrySubtractOperator::Operation(int16_t left, int16_t right, int16_t &result); -template <> -bool TrySubtractOperator::Operation(int32_t left, int32_t right, int32_t &result); -template <> -bool TrySubtractOperator::Operation(int64_t left, int64_t right, int64_t &result); - -struct SubtractOperatorOverflowCheck { - template - 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, - right); - } - return result; - } -}; - -struct TryDecimalSubtract { - template - static inline bool Operation(TA left, TB right, TR &result) { - throw InternalException("Unimplemented type for TryDecimalSubtract"); - } -}; - -template <> -bool TryDecimalSubtract::Operation(int16_t left, int16_t right, int16_t &result); -template <> -bool TryDecimalSubtract::Operation(int32_t left, int32_t right, int32_t &result); -template <> -bool TryDecimalSubtract::Operation(int64_t left, int64_t right, int64_t &result); -template <> -bool TryDecimalSubtract::Operation(hugeint_t left, hugeint_t right, hugeint_t &result); - -struct DecimalSubtractOverflowCheck { - template - static inline TR Operation(TA left, TB right) { - TR result; - if (!TryDecimalSubtract::Operation(left, right, result)) { - throw OutOfRangeException("Overflow in subtract of DECIMAL(18) (%d - %d). You might want to add an " - "explicit cast to a bigger decimal.", - left, right); - } - return result; - } -}; - -template <> -hugeint_t DecimalSubtractOverflowCheck::Operation(hugeint_t left, hugeint_t right); - -struct SubtractTimeOperator { - template - static TR Operation(TA left, TB right); -}; - -template <> -dtime_t SubtractTimeOperator::Operation(dtime_t left, interval_t right); - -} // namespace duckdb - - -namespace duckdb { - -template -static Value BinaryValueOperation(const Value &left, const Value &right) { - auto left_type = left.type(); - auto right_type = right.type(); - LogicalType result_type = left_type; - if (left_type != right_type) { - result_type = LogicalType::MaxLogicalType(left.type(), right.type()); - Value left_cast = left.CastAs(result_type); - Value right_cast = right.CastAs(result_type); - return BinaryValueOperation(left_cast, right_cast); - } - if (left.is_null || right.is_null) { - return Value().CastAs(result_type); - } - if (TypeIsIntegral(result_type.InternalType())) { - hugeint_t left_hugeint; - hugeint_t right_hugeint; - switch (result_type.InternalType()) { - case PhysicalType::INT8: - left_hugeint = Hugeint::Convert(left.value_.tinyint); - right_hugeint = Hugeint::Convert(right.value_.tinyint); - break; - case PhysicalType::INT16: - left_hugeint = Hugeint::Convert(left.value_.smallint); - right_hugeint = Hugeint::Convert(right.value_.smallint); - break; - case PhysicalType::INT32: - left_hugeint = Hugeint::Convert(left.value_.integer); - right_hugeint = Hugeint::Convert(right.value_.integer); - break; - case PhysicalType::INT64: - left_hugeint = Hugeint::Convert(left.value_.bigint); - right_hugeint = Hugeint::Convert(right.value_.bigint); - break; - case PhysicalType::UINT8: - left_hugeint = Hugeint::Convert(left.value_.utinyint); - right_hugeint = Hugeint::Convert(right.value_.utinyint); - break; - case PhysicalType::UINT16: - left_hugeint = Hugeint::Convert(left.value_.usmallint); - right_hugeint = Hugeint::Convert(right.value_.usmallint); - break; - case PhysicalType::UINT32: - left_hugeint = Hugeint::Convert(left.value_.uinteger); - right_hugeint = Hugeint::Convert(right.value_.uinteger); - break; - case PhysicalType::UINT64: - left_hugeint = Hugeint::Convert(left.value_.ubigint); - right_hugeint = Hugeint::Convert(right.value_.ubigint); - break; - case PhysicalType::INT128: - left_hugeint = left.value_.hugeint; - right_hugeint = right.value_.hugeint; - break; - default: - throw NotImplementedException("Unimplemented type for value binary op"); - } - // integer addition - return Value::Numeric(result_type, - OP::template Operation(left_hugeint, right_hugeint)); - } else if (result_type.InternalType() == PhysicalType::FLOAT) { - return Value::FLOAT( - OP::template Operation(left.GetValue(), right.GetValue())); - } else if (result_type.InternalType() == PhysicalType::DOUBLE) { - return Value::DOUBLE( - OP::template Operation(left.GetValue(), right.GetValue())); - } else { - throw NotImplementedException("Unimplemented type for value binary op"); - } -} - -//===--------------------------------------------------------------------===// -// Numeric Operations -//===--------------------------------------------------------------------===// -Value ValueOperations::Add(const Value &left, const Value &right) { - return BinaryValueOperation(left, right); -} - -Value ValueOperations::Subtract(const Value &left, const Value &right) { - return BinaryValueOperation(left, right); -} - -Value ValueOperations::Multiply(const Value &left, const Value &right) { - return BinaryValueOperation(left, right); -} - -Value ValueOperations::Modulo(const Value &left, const Value &right) { - if (right == 0) { - return Value(right.type()); - } else { - return BinaryValueOperation(left, right); - } -} - -Value ValueOperations::Divide(const Value &left, const Value &right) { - if (right == 0) { - return Value(right.type()); - } else { - return BinaryValueOperation(left, right); - } -} - -} // namespace duckdb //===--------------------------------------------------------------------===// // boolean_operators.cpp // Description: This file contains the implementation of the boolean @@ -44331,7 +42923,7 @@ DistinctSelectGenericLoopSwitch(LEFT_TYPE *__restrict ldata, RIGHT_TYPE *__restr const SelectionVector *__restrict lsel, const SelectionVector *__restrict rsel, const SelectionVector *__restrict result_sel, idx_t count, ValidityMask &lmask, ValidityMask &rmask, SelectionVector *true_sel, SelectionVector *false_sel) { - if (!lmask.AllValid() || rmask.AllValid()) { + if (!lmask.AllValid() || !rmask.AllValid()) { return DistinctSelectGenericLoopSelSwitch( ldata, rdata, lsel, rsel, result_sel, count, lmask, rmask, true_sel, false_sel); } else { @@ -44461,8 +43053,9 @@ static idx_t DistinctSelectConstant(Vector &left, Vector &right, const Selection template static idx_t DistinctSelect(Vector &left, Vector &right, idx_t vcount, const SelectionVector *sel, idx_t count, SelectionVector *true_sel, SelectionVector *false_sel) { + SelectionVector owned_sel; if (!sel) { - sel = &FlatVector::INCREMENTAL_SELECTION_VECTOR; + sel = FlatVector::IncrementalSelectionVector(count, owned_sel); } if (left.GetVectorType() == VectorType::CONSTANT_VECTOR && right.GetVectorType() == VectorType::CONSTANT_VECTOR) { return DistinctSelectConstant(left, right, sel, count, true_sel, false_sel); @@ -44798,8 +43391,9 @@ template static idx_t DistinctSelectNested(Vector &left, Vector &right, idx_t vcount, const SelectionVector *sel, idx_t count, SelectionVector *true_sel, SelectionVector *false_sel) { // We need multiple, real selections + SelectionVector owned_sel; if (!sel) { - sel = &FlatVector::INCREMENTAL_SELECTION_VECTOR; + sel = FlatVector::IncrementalSelectionVector(count, owned_sel); } SelectionVector true_vec; @@ -45918,9 +44512,11 @@ static bool StringCastSwitch(Vector &source, Vector &result, idx_t count, bool s return VectorTryCastErrorLoop(source, result, count, strict, error_message); case LogicalTypeId::TIME: + case LogicalTypeId::TIME_TZ: return VectorTryCastErrorLoop(source, result, count, strict, error_message); case LogicalTypeId::TIMESTAMP: + case LogicalTypeId::TIMESTAMP_TZ: return VectorTryCastErrorLoop(source, result, count, strict, error_message); case LogicalTypeId::TIMESTAMP_NS: @@ -45953,6 +44549,7 @@ static bool DateCastSwitch(Vector &source, Vector &result, idx_t count, string * VectorStringCast(source, result, count); return true; case LogicalTypeId::TIMESTAMP: + case LogicalTypeId::TIMESTAMP_TZ: // date to timestamp return VectorTryCastLoop(source, result, count, error_message); default: @@ -45967,6 +44564,26 @@ static bool TimeCastSwitch(Vector &source, Vector &result, idx_t count, string * // time to varchar VectorStringCast(source, result, count); return true; + case LogicalTypeId::TIME_TZ: + // time to time with time zone + UnaryExecutor::Execute(source, result, count); + return true; + default: + return TryVectorNullCast(source, result, count, error_message); + } +} + +static bool TimeTzCastSwitch(Vector &source, Vector &result, idx_t count, string *error_message) { + // now switch on the result type + switch (result.GetType().id()) { + case LogicalTypeId::VARCHAR: + // time with time zone to varchar + VectorStringCast(source, result, count); + return true; + case LogicalTypeId::TIME: + // time with time zone to time + UnaryExecutor::Execute(source, result, count); + return true; default: return TryVectorNullCast(source, result, count, error_message); } @@ -45984,9 +44601,14 @@ static bool TimestampCastSwitch(Vector &source, Vector &result, idx_t count, str UnaryExecutor::Execute(source, result, count); break; case LogicalTypeId::TIME: + case LogicalTypeId::TIME_TZ: // timestamp to time UnaryExecutor::Execute(source, result, count); break; + case LogicalTypeId::TIMESTAMP_TZ: + // timestamp (us) to timestamp with time zone + UnaryExecutor::Execute(source, result, count); + break; case LogicalTypeId::TIMESTAMP_NS: // timestamp (us) to timestamp (ns) UnaryExecutor::Execute(source, result, count); @@ -46005,6 +44627,32 @@ static bool TimestampCastSwitch(Vector &source, Vector &result, idx_t count, str return true; } +static bool TimestampTzCastSwitch(Vector &source, Vector &result, idx_t count, string *error_message) { + // now switch on the result type + switch (result.GetType().id()) { + case LogicalTypeId::VARCHAR: + // timestamp with time zone to varchar + VectorStringCast(source, result, count); + break; + case LogicalTypeId::DATE: + // timestamp with time zone to date + UnaryExecutor::Execute(source, result, count); + break; + case LogicalTypeId::TIME: + case LogicalTypeId::TIME_TZ: + // timestamp with time zone to time + UnaryExecutor::Execute(source, result, count); + break; + case LogicalTypeId::TIMESTAMP: + // timestamp with time zone to timestamp (us) + UnaryExecutor::Execute(source, result, count); + break; + default: + return TryVectorNullCast(source, result, count, error_message); + } + return true; +} + static bool TimestampNsCastSwitch(Vector &source, Vector &result, idx_t count, string *error_message) { // now switch on the result type switch (result.GetType().id()) { @@ -46157,7 +44805,9 @@ void FillEnum(Vector &source, Vector &result, idx_t count) { result.SetVectorType(VectorType::FLAT_VECTOR); - auto str_vec = EnumType::GetValuesInsertOrder(source.GetType()); + auto &str_vec = EnumType::GetValuesInsertOrder(source.GetType()); + auto str_vec_ptr = FlatVector::GetData(str_vec); + auto res_enum_type = result.GetType(); VectorData vdata; @@ -46176,7 +44826,7 @@ void FillEnum(Vector &source, Vector &result, idx_t count) { result_mask.SetInvalid(i); continue; } - auto str = str_vec[source_data[src_idx]]; + auto str = str_vec_ptr[source_data[src_idx]].GetString(); auto key = EnumType::GetPos(res_enum_type, str); if (key == -1) { // key doesn't exist on result enum @@ -46204,7 +44854,42 @@ void FillEnumResultTemplate(Vector &source, Vector &result, idx_t count) { } } -static bool EnumCastSwitch(Vector &source, Vector &result, idx_t count, string *error_message) { +void EnumToVarchar(Vector &source, Vector &result, idx_t count, PhysicalType enum_physical_type) { + if (source.GetVectorType() == VectorType::CONSTANT_VECTOR) { + result.SetVectorType(source.GetVectorType()); + } else { + result.SetVectorType(VectorType::FLAT_VECTOR); + } + auto &str_vec = EnumType::GetValuesInsertOrder(source.GetType()); + auto str_vec_ptr = FlatVector::GetData(str_vec); + auto res_vec_ptr = FlatVector::GetData(result); + + for (idx_t i = 0; i < count; i++) { + auto src_val = source.GetValue(i); + if (src_val.IsNull()) { + result.SetValue(i, Value()); + continue; + } + + uint64_t enum_idx; + switch (enum_physical_type) { + case PhysicalType::UINT8: + enum_idx = UTinyIntValue::Get(src_val); + break; + case PhysicalType::UINT16: + enum_idx = USmallIntValue::Get(src_val); + break; + case PhysicalType::UINT32: + enum_idx = UIntegerValue::Get(src_val); + break; + default: + throw InternalException("ENUM can only have unsigned integers (except UINT64) as physical types"); + } + res_vec_ptr[i] = str_vec_ptr[enum_idx]; + } +} + +static bool EnumCastSwitch(Vector &source, Vector &result, idx_t count, string *error_message, bool strict) { auto enum_physical_type = source.GetType().InternalType(); switch (result.GetType().id()) { case LogicalTypeId::ENUM: { @@ -46225,38 +44910,17 @@ static bool EnumCastSwitch(Vector &source, Vector &result, idx_t count, string * break; } case LogicalTypeId::VARCHAR: { - if (source.GetVectorType() == VectorType::CONSTANT_VECTOR) { - result.SetVectorType(source.GetVectorType()); - } else { - result.SetVectorType(VectorType::FLAT_VECTOR); - } - for (idx_t i = 0; i < count; i++) { - auto src_val = source.GetValue(i); - if (src_val.is_null) { - result.SetValue(i, Value()); - continue; - } - auto str_vec = EnumType::GetValuesInsertOrder(source.GetType()); - uint64_t enum_idx; - switch (enum_physical_type) { - case PhysicalType::UINT8: - enum_idx = src_val.value_.utinyint; - break; - case PhysicalType::UINT16: - enum_idx = src_val.value_.usmallint; - break; - case PhysicalType::UINT32: - enum_idx = src_val.value_.uinteger; - break; - default: - throw InternalException("ENUM can only have unsigned integers (except UINT64) as physical types"); - } - result.SetValue(i, Value(str_vec[enum_idx])); - } + EnumToVarchar(source, result, count, enum_physical_type); + break; + } + default: { + // Cast to varchar + Vector varchar_cast(LogicalType::VARCHAR, count); + EnumToVarchar(source, varchar_cast, count, enum_physical_type); + // Try to cast from varchar to whatever we wanted before + VectorOperations::TryCast(varchar_cast, result, count, error_message, strict); break; } - default: - throw InternalException("Cast from Enum is not allowed"); } return true; } @@ -46345,8 +45009,12 @@ bool VectorOperations::TryCast(Vector &source, Vector &result, idx_t count, stri return DateCastSwitch(source, result, count, error_message); case LogicalTypeId::TIME: return TimeCastSwitch(source, result, count, error_message); + case LogicalTypeId::TIME_TZ: + return TimeTzCastSwitch(source, result, count, error_message); case LogicalTypeId::TIMESTAMP: return TimestampCastSwitch(source, result, count, error_message); + case LogicalTypeId::TIMESTAMP_TZ: + return TimestampTzCastSwitch(source, result, count, error_message); case LogicalTypeId::TIMESTAMP_NS: return TimestampNsCastSwitch(source, result, count, error_message); case LogicalTypeId::TIMESTAMP_MS: @@ -46371,7 +45039,7 @@ bool VectorOperations::TryCast(Vector &source, Vector &result, idx_t count, stri case LogicalTypeId::LIST: return ListCastSwitch(source, result, count, error_message); case LogicalTypeId::ENUM: - return EnumCastSwitch(source, result, count, error_message); + return EnumCastSwitch(source, result, count, error_message, strict); default: return TryVectorNullCast(source, result, count, error_message); } @@ -46622,8 +45290,9 @@ void VectorOperations::Copy(const Vector &source, Vector &target, idx_t source_c break; } case VectorType::FLAT_VECTOR: { - VectorOperations::Copy(source, target, FlatVector::INCREMENTAL_SELECTION_VECTOR, source_count, source_offset, - target_offset); + SelectionVector owned_sel; + auto sel = FlatVector::IncrementalSelectionVector(source_count, owned_sel); + VectorOperations::Copy(source, target, *sel, source_count, source_offset, target_offset); break; } case VectorType::SEQUENCE_VECTOR: { @@ -46632,8 +45301,9 @@ void VectorOperations::Copy(const Vector &source, Vector &target, idx_t source_c Vector flattened(source.GetType()); VectorOperations::GenerateSequence(flattened, source_count, start, increment); - VectorOperations::Copy(flattened, target, FlatVector::INCREMENTAL_SELECTION_VECTOR, source_count, source_offset, - target_offset); + SelectionVector owned_sel; + auto sel = FlatVector::IncrementalSelectionVector(source_count, owned_sel); + VectorOperations::Copy(flattened, target, *sel, source_count, source_offset, target_offset); break; } default: @@ -47083,6 +45753,7 @@ void VectorOperations::ReadFromStorage(data_ptr_t source, idx_t count, Vector &r + namespace duckdb { // bunch of wrappers to allow registering protocol handlers @@ -47164,6 +45835,10 @@ class VirtualFileSystem : public FileSystem { sub_systems.push_back(move(fs)); } + void RegisterSubSystem(FileCompressionType compression_type, unique_ptr fs) override { + compressed_fs[compression_type] = move(fs); + } + std::string GetName() const override { return "VirtualFileSystem"; } @@ -47180,6 +45855,7 @@ class VirtualFileSystem : public FileSystem { private: vector> sub_systems; + map> compressed_fs; const unique_ptr default_fs; }; @@ -47193,6 +45869,7 @@ class VirtualFileSystem : public FileSystem { namespace duckdb { VirtualFileSystem::VirtualFileSystem() : default_fs(FileSystem::CreateLocal()) { + RegisterSubSystem(FileCompressionType::GZIP, make_unique()); } unique_ptr VirtualFileSystem::OpenFile(const string &path, uint8_t flags, FileLockType lock, @@ -47202,6 +45879,8 @@ unique_ptr VirtualFileSystem::OpenFile(const string &path, uint8_t f auto lower_path = StringUtil::Lower(path); if (StringUtil::EndsWith(lower_path, ".gz")) { compression = FileCompressionType::GZIP; + } else if (StringUtil::EndsWith(lower_path, ".zst")) { + compression = FileCompressionType::ZSTD; } else { compression = FileCompressionType::UNCOMPRESSED; } @@ -47211,13 +45890,12 @@ unique_ptr VirtualFileSystem::OpenFile(const string &path, uint8_t f if (file_handle->GetType() == FileType::FILE_TYPE_FIFO) { file_handle = PipeFileSystem::OpenPipe(move(file_handle)); } else if (compression != FileCompressionType::UNCOMPRESSED) { - switch (compression) { - case FileCompressionType::GZIP: - file_handle = GZipFileSystem::OpenCompressedFile(move(file_handle)); - break; - default: - throw NotImplementedException("Unimplemented compression type"); + 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); } return file_handle; } @@ -47225,6 +45903,59 @@ unique_ptr VirtualFileSystem::OpenFile(const string &path, uint8_t f } // namespace duckdb +namespace duckdb { + +#ifdef DUCKDB_WINDOWS + +std::wstring WindowsUtil::UTF8ToUnicode(const char *input) { + idx_t result_size; + + result_size = MultiByteToWideChar(CP_UTF8, 0, input, -1, nullptr, 0); + if (result_size == 0) { + throw IOException("Failure in MultiByteToWideChar"); + } + auto buffer = unique_ptr(new wchar_t[result_size]); + result_size = MultiByteToWideChar(CP_UTF8, 0, input, -1, buffer.get(), result_size); + if (result_size == 0) { + throw IOException("Failure in MultiByteToWideChar"); + } + return std::wstring(buffer.get(), result_size); +} + +static string WideCharToMultiByteWrapper(LPCWSTR input, uint32_t code_page) { + idx_t result_size; + + result_size = WideCharToMultiByte(code_page, 0, input, -1, 0, 0, 0, 0); + if (result_size == 0) { + throw IOException("Failure in WideCharToMultiByte"); + } + auto buffer = unique_ptr(new char[result_size]); + result_size = WideCharToMultiByte(code_page, 0, input, -1, buffer.get(), result_size, 0, 0); + if (result_size == 0) { + throw IOException("Failure in WideCharToMultiByte"); + } + return string(buffer.get(), result_size - 1); +} + +string WindowsUtil::UnicodeToUTF8(LPCWSTR input) { + return WideCharToMultiByteWrapper(input, CP_UTF8); +} + +static string WindowsUnicodeToMBCS(LPCWSTR unicode_text, int use_ansi) { + uint32_t code_page = use_ansi ? CP_ACP : CP_OEMCP; + return WideCharToMultiByteWrapper(unicode_text, code_page); +} + +string WindowsUtil::UTF8ToMBCS(const char *input, bool use_ansi) { + auto unicode = WindowsUtil::UTF8ToUnicode(input); + return WindowsUnicodeToMBCS(unicode.c_str(), use_ansi); +} + +#endif + +} // namespace duckdb + + //===----------------------------------------------------------------------===// // DuckDB // @@ -47801,7 +46532,7 @@ idx_t GroupedAggregateHashTable::FindOrCreateGroupsInternal(DataChunk &groups, V auto hash_salts_ptr = FlatVector::GetData(hash_salts); // we start out with all entries [0, 1, 2, ..., groups.size()] - const SelectionVector *sel_vector = &FlatVector::INCREMENTAL_SELECTION_VECTOR; + const SelectionVector *sel_vector = FlatVector::IncrementalSelectionVector(); idx_t remaining_entries = groups.size(); @@ -47932,8 +46663,8 @@ void GroupedAggregateHashTable::FlushMove(Vector &source_addresses, Vector &sour for (idx_t i = 0; i < groups.ColumnCount(); i++) { auto &column = groups.data[i]; const auto col_offset = layout.GetOffsets()[i]; - RowOperations::Gather(source_addresses, FlatVector::INCREMENTAL_SELECTION_VECTOR, column, - FlatVector::INCREMENTAL_SELECTION_VECTOR, count, col_offset, i); + RowOperations::Gather(source_addresses, *FlatVector::IncrementalSelectionVector(), column, + *FlatVector::IncrementalSelectionVector(), count, col_offset, i); } SelectionVector new_groups(STANDARD_VECTOR_SIZE); @@ -48060,8 +46791,8 @@ idx_t GroupedAggregateHashTable::Scan(idx_t &scan_position, DataChunk &result) { for (idx_t i = 0; i < group_cols; i++) { auto &column = result.data[i]; const auto col_offset = layout.GetOffsets()[i]; - RowOperations::Gather(addresses, FlatVector::INCREMENTAL_SELECTION_VECTOR, column, - FlatVector::INCREMENTAL_SELECTION_VECTOR, result.size(), col_offset, i); + RowOperations::Gather(addresses, *FlatVector::IncrementalSelectionVector(), column, + *FlatVector::IncrementalSelectionVector(), result.size(), col_offset, i); } RowOperations::FinalizeStates(layout, addresses, result, group_cols); @@ -48071,7 +46802,9 @@ idx_t GroupedAggregateHashTable::Scan(idx_t &scan_position, DataChunk &result) { } void GroupedAggregateHashTable::Finalize() { - D_ASSERT(!is_finalized); + if (is_finalized) { + return; + } // early release hashes, not needed for partition/scan hashes_hdl.reset(); @@ -48343,7 +47076,7 @@ class LogicalCreateIndex : public LogicalOperator { protected: void ResolveTypes() override { - types.push_back(LogicalType::BIGINT); + types.emplace_back(LogicalType::BIGINT); } }; } // namespace duckdb @@ -49066,8 +47799,9 @@ static idx_t NestedSelectOperation(Vector &left, Vector &right, const SelectionV // a selection vector in a single pass. But to implement progressive comparisons, // we have to make multiple passes, so we need to keep track of the original input positions // and then scatter the output selections when we are done. + SelectionVector owned_sel; if (!sel) { - sel = &FlatVector::INCREMENTAL_SELECTION_VECTOR; + sel = FlatVector::IncrementalSelectionVector(vcount, owned_sel); } VectorData lvdata, rvdata; @@ -49087,7 +47821,9 @@ static idx_t NestedSelectOperation(Vector &left, Vector &right, const SelectionV // If everything was NULL, fill in false_sel with sel if (count == 0) { - ScatterSelection(false_sel, no_match_count, sel, FlatVector::INCREMENTAL_SELECTION_VECTOR); + SelectionVector owned_flat_sel; + auto flat_sel = FlatVector::IncrementalSelectionVector(vcount, owned_sel); + ScatterSelection(false_sel, no_match_count, sel, *flat_sel); return count; } @@ -49554,7 +48290,7 @@ unique_ptr ExpressionExecutor::InitializeState(const BoundRefer void ExpressionExecutor::Execute(const BoundReferenceExpression &expr, ExpressionState *state, const SelectionVector *sel, idx_t count, Vector &result) { - D_ASSERT(expr.index != INVALID_INDEX); + D_ASSERT(expr.index != DConstants::INVALID_INDEX); D_ASSERT(expr.index < chunk->ColumnCount()); if (sel) { result.Slice(chunk->data[expr.index], *sel, count); @@ -49644,6 +48380,7 @@ void ExpressionExecutor::ExecuteExpression(idx_t expr_idx, Vector &result) { Value ExpressionExecutor::EvaluateScalar(const Expression &expr) { D_ASSERT(expr.IsFoldable()); + D_ASSERT(expr.IsScalar()); // use an ExpressionExecutor to execute the expression ExpressionExecutor executor(expr); @@ -49820,8 +48557,10 @@ idx_t ExpressionExecutor::DefaultSelect(const Expression &expr, ExpressionState VectorData idata; intermediate.Orrify(count, idata); + + SelectionVector owned_sel; if (!sel) { - sel = &FlatVector::INCREMENTAL_SELECTION_VECTOR; + sel = FlatVector::IncrementalSelectionVector(count, owned_sel); } if (!idata.validity.AllValid()) { return DefaultSelectSwitch(idata, sel, count, true_sel, false_sel); @@ -50081,7 +48820,7 @@ bool ART::Insert(IndexLock &lock, DataChunk &input, Vector &row_ids) { // now insert the elements into the index row_ids.Normalify(input.size()); auto row_identifiers = FlatVector::GetData(row_ids); - idx_t failed_index = INVALID_INDEX; + idx_t failed_index = DConstants::INVALID_INDEX; for (idx_t i = 0; i < input.size(); i++) { if (!keys[i]) { continue; @@ -50094,7 +48833,7 @@ bool ART::Insert(IndexLock &lock, DataChunk &input, Vector &row_ids) { break; } } - if (failed_index != INVALID_INDEX) { + if (failed_index != DConstants::INVALID_INDEX) { // failed to insert because of constraint violation: remove previously inserted entries // generate keys again keys.clear(); @@ -50228,7 +48967,7 @@ bool ART::Insert(unique_ptr &node, unique_ptr value, unsigned depth, // Recurse idx_t pos = node->GetChildPos(key[depth]); - if (pos != INVALID_INDEX) { + if (pos != DConstants::INVALID_INDEX) { auto child = node->GetChild(pos); return Insert(*child, move(value), depth + 1, row_id); } @@ -50297,7 +49036,7 @@ void ART::Erase(unique_ptr &node, Key &key, unsigned depth, row_t row_id) depth += node->prefix_length; } idx_t pos = node->GetChildPos(key[depth]); - if (pos != INVALID_INDEX) { + if (pos != DConstants::INVALID_INDEX) { auto child = node->GetChild(pos); D_ASSERT(child); @@ -50324,32 +49063,31 @@ static unique_ptr CreateKey(ART &art, PhysicalType type, Value &value) { D_ASSERT(type == value.type().InternalType()); switch (type) { case PhysicalType::BOOL: - return Key::CreateKey(value.value_.boolean, art.is_little_endian); + return Key::CreateKey(value, art.is_little_endian); case PhysicalType::INT8: - return Key::CreateKey(value.value_.tinyint, art.is_little_endian); + return Key::CreateKey(value, art.is_little_endian); case PhysicalType::INT16: - return Key::CreateKey(value.value_.smallint, art.is_little_endian); + return Key::CreateKey(value, art.is_little_endian); case PhysicalType::INT32: - return Key::CreateKey(value.value_.integer, art.is_little_endian); + return Key::CreateKey(value, art.is_little_endian); case PhysicalType::INT64: - return Key::CreateKey(value.value_.bigint, art.is_little_endian); + return Key::CreateKey(value, art.is_little_endian); case PhysicalType::UINT8: - return Key::CreateKey(value.value_.utinyint, art.is_little_endian); + return Key::CreateKey(value, art.is_little_endian); case PhysicalType::UINT16: - return Key::CreateKey(value.value_.usmallint, art.is_little_endian); + return Key::CreateKey(value, art.is_little_endian); case PhysicalType::UINT32: - return Key::CreateKey(value.value_.uinteger, art.is_little_endian); + return Key::CreateKey(value, art.is_little_endian); case PhysicalType::UINT64: - return Key::CreateKey(value.value_.ubigint, art.is_little_endian); + return Key::CreateKey(value, art.is_little_endian); case PhysicalType::INT128: - return Key::CreateKey(value.value_.hugeint, art.is_little_endian); + return Key::CreateKey(value, art.is_little_endian); case PhysicalType::FLOAT: - return Key::CreateKey(value.value_.float_, art.is_little_endian); + return Key::CreateKey(value, art.is_little_endian); case PhysicalType::DOUBLE: - return Key::CreateKey(value.value_.double_, art.is_little_endian); + return Key::CreateKey(value, art.is_little_endian); case PhysicalType::VARCHAR: - return Key::CreateKey(string_t(value.str_value.c_str(), value.str_value.size()), - art.is_little_endian); + return Key::CreateKey(value, art.is_little_endian); default: throw InternalException("Invalid type for index"); } @@ -50405,7 +49143,7 @@ Node *ART::Lookup(unique_ptr &node, Key &key, unsigned depth) { depth += node_val->prefix_length; } idx_t pos = node_val->GetChildPos(key[depth]); - if (pos == INVALID_INDEX) { + if (pos == DConstants::INVALID_INDEX) { return nullptr; } node_val = node_val->GetChild(pos)->get(); @@ -50475,9 +49213,9 @@ bool ART::IteratorNext(Iterator &it) { // Find next node top.pos = node->GetNextPos(top.pos); - if (top.pos != INVALID_INDEX) { + if (top.pos != DConstants::INVALID_INDEX) { // next node found: go there - it.SetEntry(it.depth, IteratorEntry(node->GetChild(top.pos)->get(), INVALID_INDEX)); + it.SetEntry(it.depth, IteratorEntry(node->GetChild(top.pos)->get(), DConstants::INVALID_INDEX)); it.depth++; } else { // no node found: move up the tree @@ -50556,7 +49294,7 @@ bool ART::Bound(unique_ptr &n, Key &key, Iterator &it, bool inclusive) { return IteratorNext(it); } else { // Greater - top.pos = INVALID_INDEX; + top.pos = DConstants::INVALID_INDEX; return IteratorNext(it); } } @@ -50564,7 +49302,7 @@ bool ART::Bound(unique_ptr &n, Key &key, Iterator &it, bool inclusive) { depth += node->prefix_length; top.pos = node->GetChildGreaterEqual(key[depth], equal); - if (top.pos == INVALID_INDEX) { + if (top.pos == DConstants::INVALID_INDEX) { // Find min leaf top.pos = node->GetMin(); } @@ -50688,7 +49426,7 @@ bool ART::Scan(Transaction &transaction, DataTable &table, IndexScanState &table vector row_ids; bool success = true; - if (state->values[1].is_null) { + if (state->values[1].IsNull()) { lock_guard l(lock); // single predicate switch (state->expressions[0]) { @@ -50834,14 +49572,14 @@ void Leaf::Insert(row_t row_id) { } void Leaf::Remove(row_t row_id) { - idx_t entry_offset = INVALID_INDEX; + idx_t entry_offset = DConstants::INVALID_INDEX; for (idx_t i = 0; i < num_elements; i++) { if (row_ids[i] == row_id) { entry_offset = i; break; } } - if (entry_offset == INVALID_INDEX) { + if (entry_offset == DConstants::INVALID_INDEX) { return; } num_elements--; @@ -50978,11 +49716,11 @@ idx_t Node16::GetChildGreaterEqual(uint8_t k, bool &equal) { } idx_t Node16::GetNextPos(idx_t pos) { - if (pos == INVALID_INDEX) { + if (pos == DConstants::INVALID_INDEX) { return 0; } pos++; - return pos < count ? pos : INVALID_INDEX; + return pos < count ? pos : DConstants::INVALID_INDEX; } unique_ptr *Node16::GetChild(idx_t pos) { @@ -51062,7 +49800,7 @@ idx_t Node256::GetChildPos(uint8_t k) { if (child[k]) { return k; } else { - return INVALID_INDEX; + return DConstants::INVALID_INDEX; } } @@ -51077,7 +49815,7 @@ idx_t Node256::GetChildGreaterEqual(uint8_t k, bool &equal) { return pos; } } - return INVALID_INDEX; + return DConstants::INVALID_INDEX; } idx_t Node256::GetMin() { @@ -51086,11 +49824,11 @@ idx_t Node256::GetMin() { return i; } } - return INVALID_INDEX; + return DConstants::INVALID_INDEX; } idx_t Node256::GetNextPos(idx_t pos) { - for (pos == INVALID_INDEX ? pos = 0 : pos++; pos < 256; pos++) { + for (pos == DConstants::INVALID_INDEX ? pos = 0 : pos++; pos < 256; pos++) { if (child[pos]) { return pos; } @@ -51168,11 +49906,11 @@ idx_t Node4::GetMin() { } idx_t Node4::GetNextPos(idx_t pos) { - if (pos == INVALID_INDEX) { + if (pos == DConstants::INVALID_INDEX) { return 0; } pos++; - return pos < count ? pos : INVALID_INDEX; + return pos < count ? pos : DConstants::INVALID_INDEX; } unique_ptr *Node4::GetChild(idx_t pos) { @@ -51233,7 +49971,6 @@ void Node4::Erase(ART &art, unique_ptr &node, int pos) { auto new_length = node->prefix_length + childref->prefix_length + 1; //! have to allocate space in our prefix array unique_ptr new_prefix = unique_ptr(new uint8_t[new_length]); - ; //! first move the existing prefix (if any) for (uint32_t i = 0; i < childref->prefix_length; i++) { @@ -51267,7 +50004,7 @@ Node48::Node48(ART &art, size_t compression_length) : Node(art, NodeType::N48, c idx_t Node48::GetChildPos(uint8_t k) { if (child_index[k] == Node::EMPTY_MARKER) { - return INVALID_INDEX; + return DConstants::INVALID_INDEX; } else { return k; } @@ -51288,7 +50025,7 @@ idx_t Node48::GetChildGreaterEqual(uint8_t k, bool &equal) { } idx_t Node48::GetNextPos(idx_t pos) { - for (pos == INVALID_INDEX ? pos = 0 : pos++; pos < 256; pos++) { + for (pos == DConstants::INVALID_INDEX ? pos = 0 : pos++; pos < 256; pos++) { if (child_index[pos] != Node::EMPTY_MARKER) { return pos; } @@ -51307,7 +50044,7 @@ idx_t Node48::GetMin() { return i; } } - return INVALID_INDEX; + return DConstants::INVALID_INDEX; } void Node48::Insert(ART &art, unique_ptr &node, uint8_t key_byte, unique_ptr &child) { @@ -51696,7 +50433,7 @@ idx_t JoinHashTable::PrepareKeys(DataChunk &keys, unique_ptr &key_ key_data = keys.Orrify(); // figure out which keys are NULL, and create a selection vector out of them - current_sel = &FlatVector::INCREMENTAL_SELECTION_VECTOR; + current_sel = FlatVector::IncrementalSelectionVector(); idx_t added_count = keys.size(); if (build_side && IsRightOuterJoin(join_type)) { // in case of a right or full outer join, we cannot remove NULL keys from the build side @@ -52004,7 +50741,7 @@ void ScanStructure::GatherResult(Vector &result, const SelectionVector &result_v void ScanStructure::GatherResult(Vector &result, const SelectionVector &sel_vector, const idx_t count, const idx_t col_idx) { - GatherResult(result, FlatVector::INCREMENTAL_SELECTION_VECTOR, sel_vector, count, col_idx); + GatherResult(result, *FlatVector::IncrementalSelectionVector(), sel_vector, count, col_idx); } void ScanStructure::NextInnerJoin(DataChunk &keys, DataChunk &left, DataChunk &result) { @@ -52327,7 +51064,7 @@ void JoinHashTable::ScanFullOuter(DataChunk &result, JoinHTScanState &state) { result.SetCardinality(found_entries); if (found_entries > 0) { idx_t left_column_count = result.ColumnCount() - build_types.size(); - const auto &sel_vector = FlatVector::INCREMENTAL_SELECTION_VECTOR; + const auto &sel_vector = *FlatVector::IncrementalSelectionVector(); // set the left side as a constant NULL for (idx_t i = 0; i < left_column_count; i++) { Vector &vec = result.data[i]; @@ -52365,399 +51102,6 @@ idx_t JoinHashTable::FillWithHTOffsets(data_ptr_t *key_locations, JoinHTScanStat } return key_count; } -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/execution/merge_join.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - - - -namespace duckdb { - -struct MergeOrder { - SelectionVector order; - idx_t count; - VectorData vdata; -}; - -enum MergeInfoType : uint8_t { SCALAR_MERGE_INFO = 1, CHUNK_MERGE_INFO = 2 }; - -struct MergeInfo { - MergeInfo(MergeInfoType info_type, LogicalType type) : info_type(info_type), type(type) { - } - MergeInfoType info_type; - LogicalType type; -}; - -struct ScalarMergeInfo : public MergeInfo { - MergeOrder ℴ - idx_t &pos; - SelectionVector result; - - ScalarMergeInfo(MergeOrder &order, LogicalType type, idx_t &pos) - : MergeInfo(MergeInfoType::SCALAR_MERGE_INFO, type), order(order), pos(pos), result(STANDARD_VECTOR_SIZE) { - } -}; - -struct ChunkMergeInfo : public MergeInfo { - ChunkCollection &data_chunks; - vector &order_info; - bool found_match[STANDARD_VECTOR_SIZE]; - - ChunkMergeInfo(ChunkCollection &data_chunks, vector &order_info) - : MergeInfo(MergeInfoType::CHUNK_MERGE_INFO, data_chunks.Types()[0]), data_chunks(data_chunks), - order_info(order_info) { - memset(found_match, 0, sizeof(found_match)); - } -}; - -struct MergeJoinComplex { - struct LessThan { - template - static idx_t Operation(ScalarMergeInfo &l, ScalarMergeInfo &r); - }; - struct LessThanEquals { - template - static idx_t Operation(ScalarMergeInfo &l, ScalarMergeInfo &r); - }; - struct GreaterThan { - template - static idx_t Operation(ScalarMergeInfo &l, ScalarMergeInfo &r) { - return LessThan::Operation(r, l); - } - }; - struct GreaterThanEquals { - template - static idx_t Operation(ScalarMergeInfo &l, ScalarMergeInfo &r) { - return LessThanEquals::Operation(r, l); - } - }; - - static idx_t Perform(MergeInfo &l, MergeInfo &r, ExpressionType comparison_type); -}; - -struct MergeJoinSimple { - struct LessThan { - template - static idx_t Operation(ScalarMergeInfo &l, ChunkMergeInfo &r); - }; - struct LessThanEquals { - template - static idx_t Operation(ScalarMergeInfo &l, ChunkMergeInfo &r); - }; - struct GreaterThan { - template - static idx_t Operation(ScalarMergeInfo &l, ChunkMergeInfo &r); - }; - struct GreaterThanEquals { - template - static idx_t Operation(ScalarMergeInfo &l, ChunkMergeInfo &r); - }; - - static idx_t Perform(MergeInfo &l, MergeInfo &r, ExpressionType comparison); -}; - -#define INSTANTIATE_MERGEJOIN_TEMPLATES(MJCLASS, OPNAME, L, R) \ - template idx_t MJCLASS::OPNAME::Operation(L & l, R & r); \ - template idx_t MJCLASS::OPNAME::Operation(L & l, R & r); \ - template idx_t MJCLASS::OPNAME::Operation(L & l, R & r); \ - template idx_t MJCLASS::OPNAME::Operation(L & l, R & r); \ - template idx_t MJCLASS::OPNAME::Operation(L & l, R & r); \ - template idx_t MJCLASS::OPNAME::Operation(L & l, R & r); \ - template idx_t MJCLASS::OPNAME::Operation(L & l, R & r); \ - template idx_t MJCLASS::OPNAME::Operation(L & l, R & r); \ - template idx_t MJCLASS::OPNAME::Operation(L & l, R & r); \ - template idx_t MJCLASS::OPNAME::Operation(L & l, R & r); \ - template idx_t MJCLASS::OPNAME::Operation(L & l, R & r); \ - template idx_t MJCLASS::OPNAME::Operation(L & l, R & r); \ - template idx_t MJCLASS::OPNAME::Operation(L & l, R & r); - -} // namespace duckdb - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/expression/comparison_expression.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -namespace duckdb { -//! ComparisonExpression represents a boolean comparison (e.g. =, >=, <>). Always returns a boolean -//! and has two children. -class ComparisonExpression : public ParsedExpression { -public: - ComparisonExpression(ExpressionType type, unique_ptr left, unique_ptr right); - - unique_ptr left; - unique_ptr right; - -public: - string ToString() const override; - - static bool Equals(const ComparisonExpression *a, const ComparisonExpression *b); - - unique_ptr Copy() const override; - - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(ExpressionType type, Deserializer &source); -}; -} // namespace duckdb - - -namespace duckdb { - -template -static idx_t MergeJoinSwitch(L_ARG &l, R_ARG &r) { - switch (l.type.InternalType()) { - case PhysicalType::BOOL: - case PhysicalType::INT8: - return MJ::template Operation(l, r); - case PhysicalType::INT16: - return MJ::template Operation(l, r); - case PhysicalType::INT32: - return MJ::template Operation(l, r); - case PhysicalType::INT64: - return MJ::template Operation(l, r); - case PhysicalType::UINT8: - return MJ::template Operation(l, r); - case PhysicalType::UINT16: - return MJ::template Operation(l, r); - case PhysicalType::UINT32: - return MJ::template Operation(l, r); - case PhysicalType::UINT64: - return MJ::template Operation(l, r); - case PhysicalType::INT128: - return MJ::template Operation(l, r); - case PhysicalType::FLOAT: - return MJ::template Operation(l, r); - case PhysicalType::DOUBLE: - return MJ::template Operation(l, r); - case PhysicalType::INTERVAL: - return MJ::template Operation(l, r); - case PhysicalType::VARCHAR: - return MJ::template Operation(l, r); - default: - throw InternalException("Type not implemented for merge join!"); - } -} - -template -static idx_t MergeJoinComparisonSwitch(L_ARG &l, R_ARG &r, ExpressionType comparison_type) { - switch (comparison_type) { - case ExpressionType::COMPARE_LESSTHAN: - return MergeJoinSwitch(l, r); - case ExpressionType::COMPARE_LESSTHANOREQUALTO: - return MergeJoinSwitch(l, r); - case ExpressionType::COMPARE_GREATERTHAN: - return MergeJoinSwitch(l, r); - case ExpressionType::COMPARE_GREATERTHANOREQUALTO: - return MergeJoinSwitch(l, r); - default: - throw InternalException("Unimplemented comparison type for merge join!"); - } -} - -idx_t MergeJoinComplex::Perform(MergeInfo &l, MergeInfo &r, ExpressionType comparison_type) { - D_ASSERT(l.info_type == MergeInfoType::SCALAR_MERGE_INFO && r.info_type == MergeInfoType::SCALAR_MERGE_INFO); - auto &left = (ScalarMergeInfo &)l; - auto &right = (ScalarMergeInfo &)r; - D_ASSERT(left.type == right.type); - if (left.order.count == 0 || right.order.count == 0) { - return 0; - } - return MergeJoinComparisonSwitch(left, right, comparison_type); -} - -idx_t MergeJoinSimple::Perform(MergeInfo &l, MergeInfo &r, ExpressionType comparison_type) { - D_ASSERT(l.info_type == MergeInfoType::SCALAR_MERGE_INFO && r.info_type == MergeInfoType::CHUNK_MERGE_INFO); - auto &left = (ScalarMergeInfo &)l; - auto &right = (ChunkMergeInfo &)r; - D_ASSERT(left.type == right.type); - if (left.order.count == 0 || right.data_chunks.Count() == 0) { - return 0; - } - return MergeJoinComparisonSwitch(left, right, comparison_type); -} - -} // namespace duckdb - - - - - -namespace duckdb { - -template -idx_t MergeJoinComplexLessThan(ScalarMergeInfo &l, ScalarMergeInfo &r) { - if (r.pos >= r.order.count) { - return 0; - } - auto ldata = (T *)l.order.vdata.data; - auto rdata = (T *)r.order.vdata.data; - auto &lorder = l.order.order; - auto &rorder = r.order.order; - idx_t result_count = 0; - while (true) { - if (l.pos < l.order.count) { - auto lidx = lorder.get_index(l.pos); - auto ridx = rorder.get_index(r.pos); - auto dlidx = l.order.vdata.sel->get_index(lidx); - auto dridx = r.order.vdata.sel->get_index(ridx); - if (OP::Operation(ldata[dlidx], rdata[dridx])) { - // left side smaller: found match - l.result.set_index(result_count, lidx); - r.result.set_index(result_count, ridx); - result_count++; - // move left side forward - l.pos++; - if (result_count == STANDARD_VECTOR_SIZE) { - // out of space! - break; - } - continue; - } - } - // right side smaller or equal, or left side exhausted: move - // right pointer forward reset left side to start - l.pos = 0; - r.pos++; - if (r.pos == r.order.count) { - break; - } - } - return result_count; -} - -template -idx_t MergeJoinComplex::LessThan::Operation(ScalarMergeInfo &l, ScalarMergeInfo &r) { - return MergeJoinComplexLessThan(l, r); -} - -template -idx_t MergeJoinComplex::LessThanEquals::Operation(ScalarMergeInfo &l, ScalarMergeInfo &r) { - return MergeJoinComplexLessThan(l, r); -} - -INSTANTIATE_MERGEJOIN_TEMPLATES(MergeJoinComplex, LessThan, ScalarMergeInfo, ScalarMergeInfo) -INSTANTIATE_MERGEJOIN_TEMPLATES(MergeJoinComplex, LessThanEquals, ScalarMergeInfo, ScalarMergeInfo) - -} // namespace duckdb - - - - - -namespace duckdb { - -template -static idx_t MergeJoinSimpleGreaterThan(ScalarMergeInfo &l, ChunkMergeInfo &r) { - auto ldata = (T *)l.order.vdata.data; - auto &lorder = l.order.order; - l.pos = l.order.count; - for (idx_t chunk_idx = 0; chunk_idx < r.order_info.size(); chunk_idx++) { - // we only care about the SMALLEST value in each of the RHS - // because we want to figure out if they are greater than [or equal] to ANY value - // get the smallest value from the RHS - auto &rorder = r.order_info[chunk_idx]; - auto rdata = (T *)rorder.vdata.data; - auto min_r_value = rdata[rorder.vdata.sel->get_index(rorder.order.get_index(0))]; - // now we start from the current lpos value and check if we found a new value that is [>= OR >] the min RHS - // value - while (true) { - auto lidx = lorder.get_index(l.pos - 1); - auto dlidx = l.order.vdata.sel->get_index(lidx); - if (OP::Operation(ldata[dlidx], min_r_value)) { - // found a match for lpos, set it in the found_match vector - r.found_match[lidx] = true; - l.pos--; - if (l.pos == 0) { - // early out: we exhausted the entire LHS and they all match - return 0; - } - } else { - // we found no match: any subsequent value from the LHS we scan now will be smaller and thus also not - // match move to the next RHS chunk - break; - } - } - } - return 0; -} -template -idx_t MergeJoinSimple::GreaterThan::Operation(ScalarMergeInfo &l, ChunkMergeInfo &r) { - return MergeJoinSimpleGreaterThan(l, r); -} - -template -idx_t MergeJoinSimple::GreaterThanEquals::Operation(ScalarMergeInfo &l, ChunkMergeInfo &r) { - return MergeJoinSimpleGreaterThan(l, r); -} - -template -static idx_t MergeJoinSimpleLessThan(ScalarMergeInfo &l, ChunkMergeInfo &r) { - auto ldata = (T *)l.order.vdata.data; - auto &lorder = l.order.order; - l.pos = 0; - for (idx_t chunk_idx = 0; chunk_idx < r.order_info.size(); chunk_idx++) { - // we only care about the BIGGEST value in each of the RHS - // because we want to figure out if they are less than [or equal] to ANY value - // get the biggest value from the RHS - auto &rorder = r.order_info[chunk_idx]; - auto rdata = (T *)rorder.vdata.data; - auto max_r_value = rdata[rorder.vdata.sel->get_index(rorder.order.get_index(rorder.count - 1))]; - // now we start from the current lpos value and check if we found a new value that is [<= OR <] the max RHS - // value - while (true) { - auto lidx = lorder.get_index(l.pos); - auto dlidx = l.order.vdata.sel->get_index(lidx); - if (OP::Operation(ldata[dlidx], max_r_value)) { - // found a match for lpos, set it in the found_match vector - r.found_match[lidx] = true; - l.pos++; - if (l.pos == l.order.count) { - // early out: we exhausted the entire LHS and they all match - return 0; - } - } else { - // we found no match: any subsequent value from the LHS we scan now will be bigger and thus also not - // match move to the next RHS chunk - break; - } - } - } - return 0; -} - -template -idx_t MergeJoinSimple::LessThan::Operation(ScalarMergeInfo &l, ChunkMergeInfo &r) { - return MergeJoinSimpleLessThan(l, r); -} - -template -idx_t MergeJoinSimple::LessThanEquals::Operation(ScalarMergeInfo &l, ChunkMergeInfo &r) { - return MergeJoinSimpleLessThan(l, r); -} - -INSTANTIATE_MERGEJOIN_TEMPLATES(MergeJoinSimple, LessThan, ScalarMergeInfo, ChunkMergeInfo) -INSTANTIATE_MERGEJOIN_TEMPLATES(MergeJoinSimple, LessThanEquals, ScalarMergeInfo, ChunkMergeInfo) -INSTANTIATE_MERGEJOIN_TEMPLATES(MergeJoinSimple, GreaterThan, ScalarMergeInfo, ChunkMergeInfo) -INSTANTIATE_MERGEJOIN_TEMPLATES(MergeJoinSimple, GreaterThanEquals, ScalarMergeInfo, ChunkMergeInfo) - } // namespace duckdb //===----------------------------------------------------------------------===// @@ -53626,20 +51970,20 @@ class NumericStatistics : public BaseStatistics { public: void Merge(const BaseStatistics &other) override; - bool IsConstant() override; + bool IsConstant() const override; - FilterPropagateResult CheckZonemap(ExpressionType comparison_type, const Value &constant); + FilterPropagateResult CheckZonemap(ExpressionType comparison_type, const Value &constant) const; - unique_ptr Copy() override; - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(Deserializer &source, LogicalType type); - void Verify(Vector &vector, const SelectionVector &sel, idx_t count) override; + unique_ptr Copy() const override; + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(FieldReader &reader, LogicalType type); + void Verify(Vector &vector, const SelectionVector &sel, idx_t count) const override; - string ToString() override; + string ToString() const override; private: template - void TemplatedVerify(Vector &vector, const SelectionVector &sel, idx_t count); + void TemplatedVerify(Vector &vector, const SelectionVector &sel, idx_t count) const; public: template @@ -53653,31 +51997,12 @@ class NumericStatistics : public BaseStatistics { } template - static inline void Update(SegmentStatistics &stats, T new_value); + static inline void Update(SegmentStatistics &stats, T new_value) { + auto &nstats = (NumericStatistics &)*stats.statistics; + UpdateValue(new_value, nstats.min.GetReferenceUnsafe(), nstats.max.GetReferenceUnsafe()); + } }; -template <> -void NumericStatistics::Update(SegmentStatistics &stats, int8_t new_value); -template <> -void NumericStatistics::Update(SegmentStatistics &stats, int16_t new_value); -template <> -void NumericStatistics::Update(SegmentStatistics &stats, int32_t new_value); -template <> -void NumericStatistics::Update(SegmentStatistics &stats, int64_t new_value); -template <> -void NumericStatistics::Update(SegmentStatistics &stats, uint8_t new_value); -template <> -void NumericStatistics::Update(SegmentStatistics &stats, uint16_t new_value); -template <> -void NumericStatistics::Update(SegmentStatistics &stats, uint32_t new_value); -template <> -void NumericStatistics::Update(SegmentStatistics &stats, uint64_t new_value); -template <> -void NumericStatistics::Update(SegmentStatistics &stats, hugeint_t new_value); -template <> -void NumericStatistics::Update(SegmentStatistics &stats, float new_value); -template <> -void NumericStatistics::Update(SegmentStatistics &stats, double new_value); template <> void NumericStatistics::Update(SegmentStatistics &stats, interval_t new_value); template <> @@ -53700,7 +52025,7 @@ PhysicalPerfectHashAggregate::PhysicalPerfectHashAggregate(ClientContext &contex for (auto &stats : group_stats) { D_ASSERT(stats); auto &nstats = (NumericStatistics &)*stats; - D_ASSERT(!nstats.min.is_null); + D_ASSERT(!nstats.min.IsNull()); group_minima.push_back(move(nstats.min)); } for (auto &expr : groups) { @@ -53943,7 +52268,6 @@ class PhysicalSimpleAggregate : public PhysicalOperator { } bool ParallelSink() const override { - // we can only parallelize if all aggregates are combinable return true; } }; @@ -54090,7 +52414,6 @@ SinkResultType PhysicalSimpleAggregate::Sink(ExecutionContext &context, GlobalSi DataChunk &payload_chunk = sink.payload_chunk; sink.child_executor.SetChunk(input); - payload_chunk.SetCardinality(input); for (idx_t aggr_idx = 0; aggr_idx < aggregates.size(); aggr_idx++) { DataChunk filtered_input; auto &aggregate = (BoundAggregateExpression &)*aggregates[aggr_idx]; @@ -54105,6 +52428,8 @@ SinkResultType PhysicalSimpleAggregate::Sink(ExecutionContext &context, GlobalSi filtered_input.Slice(input, true_sel, count); sink.child_executor.SetChunk(filtered_input); payload_chunk.SetCardinality(count); + } else { + payload_chunk.SetCardinality(input); } // resolve the child expressions of the aggregate (if any) if (!aggregate.children.empty()) { @@ -54143,8 +52468,9 @@ void PhysicalSimpleAggregate::Combine(ExecutionContext &context, GlobalSinkState aggregate.function.combine(source_state, dest_state, 1); } + auto &client_profiler = QueryProfiler::Get(context.client); context.thread.profiler.Flush(this, &source.child_executor, "child_executor", 0); - context.client.profiler->Flush(context.thread.profiler); + client_profiler.Flush(context.thread.profiler); } SinkFinalizeType PhysicalSimpleAggregate::Finalize(Pipeline &pipeline, Event &event, ClientContext &context, @@ -54220,6 +52546,149 @@ string PhysicalSimpleAggregate::ParamsToString() const { +namespace duckdb { + +//! PhysicalStreamingWindow implements streaming window functions (i.e. with an empty OVER clause) +class PhysicalStreamingWindow : public PhysicalOperator { +public: + PhysicalStreamingWindow(vector types, vector> select_list, + idx_t estimated_cardinality, + PhysicalOperatorType type = PhysicalOperatorType::STREAMING_WINDOW); + + //! The projection list of the WINDOW statement + vector> select_list; + +public: + unique_ptr GetOperatorState(ClientContext &context) const override; + + OperatorResultType Execute(ExecutionContext &context, DataChunk &input, DataChunk &chunk, + OperatorState &state) const override; + + string ParamsToString() const override; +}; + +} // namespace duckdb + + + + + + + +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)) { +} + +class StreamingWindowState : public OperatorState { +public: + StreamingWindowState() : initialized(false), row_number(1) { + } + + void Initialize(DataChunk &input, const vector> &expressions) { + for (idx_t expr_idx = 0; expr_idx < expressions.size(); expr_idx++) { + auto &expr = *expressions[expr_idx]; + switch (expr.GetExpressionType()) { + case ExpressionType::WINDOW_FIRST_VALUE: { + auto &wexpr = (BoundWindowExpression &)expr; + auto &ref = (BoundReferenceExpression &)*wexpr.children[0]; + const_vectors.push_back(make_unique(input.data[ref.index].GetValue(0))); + break; + } + case ExpressionType::WINDOW_PERCENT_RANK: { + const_vectors.push_back(make_unique(Value((double)0))); + break; + } + case ExpressionType::WINDOW_RANK: + case ExpressionType::WINDOW_RANK_DENSE: { + const_vectors.push_back(make_unique(Value((int64_t)1))); + break; + } + default: + const_vectors.push_back(nullptr); + } + } + initialized = true; + } + +public: + bool initialized; + int64_t row_number; + vector> const_vectors; +}; + +unique_ptr PhysicalStreamingWindow::GetOperatorState(ClientContext &context) const { + return make_unique(); +} + +OperatorResultType PhysicalStreamingWindow::Execute(ExecutionContext &context, DataChunk &input, DataChunk &chunk, + OperatorState &state_p) const { + auto &state = (StreamingWindowState &)state_p; + if (!state.initialized) { + state.Initialize(input, select_list); + } + // Put payload columns in place + for (idx_t col_idx = 0; col_idx < input.data.size(); col_idx++) { + chunk.data[col_idx].Reference(input.data[col_idx]); + } + // Compute window function + const idx_t count = input.size(); + for (idx_t expr_idx = 0; expr_idx < select_list.size(); expr_idx++) { + idx_t col_idx = input.data.size() + expr_idx; + auto &expr = *select_list[expr_idx]; + switch (expr.GetExpressionType()) { + case ExpressionType::WINDOW_FIRST_VALUE: + case ExpressionType::WINDOW_PERCENT_RANK: + case ExpressionType::WINDOW_RANK: + case ExpressionType::WINDOW_RANK_DENSE: { + // Reference constant vector + chunk.data[col_idx].Reference(*state.const_vectors[expr_idx]); + break; + } + case ExpressionType::WINDOW_ROW_NUMBER: { + // Set row numbers + auto rdata = FlatVector::GetData(chunk.data[col_idx]); + for (idx_t i = 0; i < count; i++) { + rdata[i] = state.row_number + i; + } + break; + } + default: + throw NotImplementedException("%s for StreamingWindow", ExpressionTypeToString(expr.GetExpressionType())); + } + } + state.row_number += count; + chunk.SetCardinality(count); + return OperatorResultType::NEED_MORE_INPUT; +} + +string PhysicalStreamingWindow::ParamsToString() const { + string result; + for (idx_t i = 0; i < select_list.size(); i++) { + if (i > 0) { + result += "\n"; + } + result += select_list[i]->GetName(); + } + return result; +} + +} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/execution/operator/aggregate/physical_window.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + namespace duckdb { @@ -54337,6 +52806,8 @@ class WindowSegmentTree { Vector statep; //! The frame boundaries, used for the window functions FrameBounds frame; + //! The active data in the inputs. Used for the window functions + FrameBounds active; //! Reused result state container for the window functions Vector statev; @@ -54438,108 +52909,6 @@ PhysicalWindow::PhysicalWindow(vector types, vector -class BitArray { -public: - using bits_t = std::vector; - - static const auto BITS_PER_WORD = std::numeric_limits::digits; - static const auto ZEROS = std::numeric_limits::min(); - static const auto ONES = std::numeric_limits::max(); - - class reference { // NOLINT - public: - friend BitArray; - - reference(const reference &r) = default; - - reference &operator=(bool x) noexcept { - auto b = parent.Block(pos); - auto s = parent.Shift(pos); - auto w = parent.GetBlock(b); - if (parent.TestBit(w, s) != x) { - parent.SetBlock(b, parent.FlipBit(w, s)); - } - return *this; - } - - reference &operator=(const reference &r) noexcept { - return *this = bool(r); - } - - explicit operator bool() const noexcept { - return parent[pos]; - } - - bool operator~() const noexcept { - return !parent[pos]; - } - - private: - explicit reference(BitArray &parent_p, size_t pos_p) : parent(parent_p), pos(pos_p) { - } - - BitArray &parent; - size_t pos; - }; - - static size_t Block(const size_t &pos) { - return pos / BITS_PER_WORD; - } - - static unsigned Shift(const size_t &pos) { - return pos % BITS_PER_WORD; - } - - static bool TestBit(W w, unsigned s) { - return (w >> s) & 0x01; - } - - static W SetBit(W w, unsigned s) { - return w | (W(1) << s); - } - - static W ClearBit(W w, unsigned s) { - return w & ~(W(1) << s); - } - - static W FlipBit(W w, unsigned s) { - return w ^ (W(1) << s); - } - - explicit BitArray(const size_t &count, const W &init = 0) - : bits(count ? Block(count - 1) + 1 : 0, init), count(count) { - } - - size_t Count() const { - return count; - } - - const W &GetBlock(size_t b) const { - return bits[b]; - } - - W &GetBlock(size_t b) { - return bits[b]; - } - - void SetBlock(size_t b, const W &block) { - GetBlock(b) = block; - } - - bool operator[](size_t pos) const { - return TestBit(GetBlock(Block(pos)), Shift(pos)); - } - - reference operator[](size_t pos) { - return reference(*this, pos); - } - -private: - bits_t bits; - size_t count; -}; - template struct ChunkIterator { @@ -54549,7 +52918,7 @@ struct ChunkIterator { Update(0); } - void Update(idx_t r) { + inline void Update(idx_t r) { if (r >= chunk_end) { ch_idx = collection.LocateChunk(r); auto &ch = collection.GetChunk(ch_idx); @@ -54561,11 +52930,11 @@ struct ChunkIterator { } } - bool IsValid(idx_t r) { + inline bool IsValid(idx_t r) { return validity->RowIsValid(r - chunk_begin); } - INPUT_TYPE GetValue(idx_t r) { + inline INPUT_TYPE GetValue(idx_t r) { return data[r - chunk_begin]; } @@ -54579,115 +52948,89 @@ struct ChunkIterator { ValidityMask *validity; }; -template -static void MaskTypedColumn(MASK_TYPE &mask, ChunkCollection &over_collection, const idx_t c) { +template +static void MaskTypedColumn(ValidityMask &mask, ChunkCollection &over_collection, const idx_t c) { ChunkIterator ci(over_collection, c); // Record the first value idx_t r = 0; auto prev_valid = ci.IsValid(r); auto prev = ci.GetValue(r); - ++r; // Process complete blocks - const auto row_count = over_collection.Count(); - const auto complete_block_count = mask.Block(row_count); - for (idx_t b = mask.Block(r); b < complete_block_count; ++b) { - auto block = mask.GetBlock(b); + const auto count = over_collection.Count(); + const auto entry_count = mask.EntryCount(count); + for (idx_t entry_idx = 0; entry_idx < entry_count; ++entry_idx) { + auto validity_entry = mask.GetValidityEntry(entry_idx); // Skip the block if it is all boundaries. - if (block == mask.ONES) { - r -= (r % mask.BITS_PER_WORD); - r += mask.BITS_PER_WORD; + idx_t next = MinValue(r + ValidityMask::BITS_PER_VALUE, count); + if (ValidityMask::AllValid(validity_entry)) { + r = next; continue; } // Scan the rows in the complete block - for (unsigned shift = mask.Shift(r); shift < mask.BITS_PER_WORD; ++shift, ++r) { + idx_t start = r; + for (; r < next; ++r) { // Update the chunk for this row ci.Update(r); auto curr_valid = ci.IsValid(r); auto curr = ci.GetValue(r); - if (!mask.TestBit(block, shift)) { + if (!ValidityMask::RowIsValid(validity_entry, r - start)) { if (curr_valid != prev_valid || (curr_valid && !Equals::Operation(curr, prev))) { - block = mask.SetBit(block, shift); + mask.SetValidUnsafe(r); } } prev_valid = curr_valid; prev = curr; } - mask.SetBlock(b, block); - } - - // Finish last ragged block - if (r < row_count) { - auto block = mask.GetBlock(complete_block_count); - if (block != mask.ONES) { - for (unsigned shift = mask.Shift(r); r < row_count; ++shift, ++r) { - // Update the chunk for this row - ci.Update(r); - - auto curr_valid = ci.IsValid(r); - auto curr = ci.GetValue(r); - if (!mask.TestBit(block, shift)) { - if (curr_valid != prev_valid || (curr_valid && !Equals::Operation(curr, prev))) { - block = mask.SetBit(block, shift); - } - } - prev_valid = curr_valid; - prev = curr; - } - mask.SetBlock(complete_block_count, block); - } } } -template -static void MaskColumn(BitArray &mask, ChunkCollection &over_collection, const idx_t c) { - using MASK_TYPE = BitArray; - +static void MaskColumn(ValidityMask &mask, ChunkCollection &over_collection, const idx_t c) { auto &vector = over_collection.GetChunk(0).data[c]; switch (vector.GetType().InternalType()) { case PhysicalType::BOOL: case PhysicalType::INT8: - MaskTypedColumn(mask, over_collection, c); + MaskTypedColumn(mask, over_collection, c); break; case PhysicalType::INT16: - MaskTypedColumn(mask, over_collection, c); + MaskTypedColumn(mask, over_collection, c); break; case PhysicalType::INT32: - MaskTypedColumn(mask, over_collection, c); + MaskTypedColumn(mask, over_collection, c); break; case PhysicalType::INT64: - MaskTypedColumn(mask, over_collection, c); + MaskTypedColumn(mask, over_collection, c); break; case PhysicalType::UINT8: - MaskTypedColumn(mask, over_collection, c); + MaskTypedColumn(mask, over_collection, c); break; case PhysicalType::UINT16: - MaskTypedColumn(mask, over_collection, c); + MaskTypedColumn(mask, over_collection, c); break; case PhysicalType::UINT32: - MaskTypedColumn(mask, over_collection, c); + MaskTypedColumn(mask, over_collection, c); break; case PhysicalType::UINT64: - MaskTypedColumn(mask, over_collection, c); + MaskTypedColumn(mask, over_collection, c); break; case PhysicalType::INT128: - MaskTypedColumn(mask, over_collection, c); + MaskTypedColumn(mask, over_collection, c); break; case PhysicalType::FLOAT: - MaskTypedColumn(mask, over_collection, c); + MaskTypedColumn(mask, over_collection, c); break; case PhysicalType::DOUBLE: - MaskTypedColumn(mask, over_collection, c); + MaskTypedColumn(mask, over_collection, c); break; case PhysicalType::VARCHAR: - MaskTypedColumn(mask, over_collection, c); + MaskTypedColumn(mask, over_collection, c); break; case PhysicalType::INTERVAL: - MaskTypedColumn(mask, over_collection, c); + MaskTypedColumn(mask, over_collection, c); break; default: throw NotImplementedException("Type for comparison"); @@ -54695,20 +53038,28 @@ static void MaskColumn(BitArray &mask, ChunkCollection &over_collection, cons } } -template -static idx_t FindNextStart(const BitArray &mask, idx_t l, const idx_t r) { +static idx_t FindNextStart(const ValidityMask &mask, idx_t l, const idx_t r, idx_t &n) { + if (mask.AllValid()) { + auto start = MinValue(l + n - 1, r); + n -= MinValue(n, r - l); + return start; + } + while (l < r) { // If l is aligned with the start of a block, and the block is blank, then skip forward one block. - const auto block = mask.GetBlock(mask.Block(l)); - auto shift = mask.Shift(l); - if (!block && !shift) { - l += mask.BITS_PER_WORD; + idx_t entry_idx; + idx_t shift; + mask.GetEntryIndex(l, entry_idx, shift); + + const auto block = mask.GetValidityEntry(entry_idx); + if (mask.NoneValid(block) && !shift) { + l += ValidityMask::BITS_PER_VALUE; continue; } // Loop over the block - for (; shift < mask.BITS_PER_WORD; ++shift, ++l) { - if (mask.TestBit(block, shift)) { + for (; shift < ValidityMask::BITS_PER_VALUE && l < r; ++shift, ++l) { + if (mask.RowIsValid(block, shift) && --n == 0) { return MinValue(l, r); } } @@ -54718,23 +53069,31 @@ static idx_t FindNextStart(const BitArray &mask, idx_t l, const idx_t r) { return r; } -template -static idx_t FindPrevStart(const BitArray &mask, const idx_t l, idx_t r) { +static idx_t FindPrevStart(const ValidityMask &mask, const idx_t l, idx_t r, idx_t &n) { + if (mask.AllValid()) { + auto start = (r <= l + n) ? l : r - n; + n -= r - start; + return start; + } + while (l < r) { // If r is aligned with the start of a block, and the previous block is blank, // then skip backwards one block. - const auto block = mask.GetBlock(mask.Block(r - 1)); - auto shift = mask.Shift(r); - if (!block && !shift) { + idx_t entry_idx; + idx_t shift; + mask.GetEntryIndex(r - 1, entry_idx, shift); + + const auto block = mask.GetValidityEntry(entry_idx); + if (mask.NoneValid(block) && (shift + 1 == ValidityMask::BITS_PER_VALUE)) { // r is nonzero (> l) and word aligned, so this will not underflow. - r -= mask.BITS_PER_WORD; + r -= ValidityMask::BITS_PER_VALUE; continue; } // Loop backwards over the block // shift is probing r-1 >= l >= 0 - for (shift = mask.Shift(r - 1) + 1; shift-- > 0; --r) { - if (mask.TestBit(block, shift)) { + for (++shift; shift-- > 0; --r) { + if (mask.RowIsValid(block, shift) && --n == 0) { return MaxValue(l, r - 1); } } @@ -54890,7 +53249,7 @@ static void ScanSortedPartition(WindowOperatorState &state, ChunkCollection &inp payload_types.insert(payload_types.end(), over_types.begin(), over_types.end()); // scan the sorted row data - SortedDataScanner scanner(*global_sort_state.sorted_blocks[0]->payload_data, global_sort_state); + PayloadScanner scanner(*global_sort_state.sorted_blocks[0]->payload_data, global_sort_state); for (;;) { DataChunk payload_chunk; payload_chunk.Initialize(payload_types); @@ -55156,8 +53515,8 @@ static idx_t FindOrderedRangeBound(ChunkCollection &over, const idx_t order_col, static void UpdateWindowBoundaries(WindowBoundariesState &bounds, const idx_t input_size, const idx_t row_idx, ChunkCollection &over_collection, ChunkCollection &boundary_start_collection, - ChunkCollection &boundary_end_collection, const BitArray &partition_mask, - const BitArray &order_mask) { + ChunkCollection &boundary_end_collection, const ValidityMask &partition_mask, + const ValidityMask &order_mask) { // RANGE sorting parameters const auto order_col = bounds.partition_count; @@ -55165,8 +53524,8 @@ static void UpdateWindowBoundaries(WindowBoundariesState &bounds, const idx_t in if (bounds.partition_count + bounds.order_count > 0) { // determine partition and peer group boundaries to ultimately figure out window size - bounds.is_same_partition = !partition_mask[row_idx]; - bounds.is_peer = !order_mask[row_idx]; + bounds.is_same_partition = !partition_mask.RowIsValidUnsafe(row_idx); + bounds.is_peer = !order_mask.RowIsValidUnsafe(row_idx); // when the partition changes, recompute the boundaries if (!bounds.is_same_partition) { @@ -55176,7 +53535,8 @@ static void UpdateWindowBoundaries(WindowBoundariesState &bounds, const idx_t in // find end of partition bounds.partition_end = input_size; if (bounds.partition_count) { - bounds.partition_end = FindNextStart(partition_mask, bounds.partition_start + 1, input_size); + idx_t n = 1; + bounds.partition_end = FindNextStart(partition_mask, bounds.partition_start + 1, input_size, n); } // Find valid ordering values for the new partition @@ -55187,14 +53547,16 @@ static void UpdateWindowBoundaries(WindowBoundariesState &bounds, const idx_t in if ((bounds.valid_start < bounds.valid_end) && bounds.has_preceding_range) { // Exclude any leading NULLs if (CellIsNull(over_collection, order_col, bounds.valid_start)) { - bounds.valid_start = FindNextStart(order_mask, bounds.valid_start + 1, bounds.valid_end); + idx_t n = 1; + bounds.valid_start = FindNextStart(order_mask, bounds.valid_start + 1, bounds.valid_end, n); } } if ((bounds.valid_start < bounds.valid_end) && bounds.has_following_range) { // Exclude any trailing NULLs if (CellIsNull(over_collection, order_col, bounds.valid_end - 1)) { - bounds.valid_end = FindPrevStart(order_mask, bounds.valid_start, bounds.valid_end); + idx_t n = 1; + bounds.valid_end = FindPrevStart(order_mask, bounds.valid_start, bounds.valid_end, n); } } @@ -55205,7 +53567,8 @@ static void UpdateWindowBoundaries(WindowBoundariesState &bounds, const idx_t in if (bounds.needs_peer) { bounds.peer_end = bounds.partition_end; if (bounds.order_count) { - bounds.peer_end = FindNextStart(order_mask, bounds.peer_start + 1, bounds.partition_end); + idx_t n = 1; + bounds.peer_end = FindNextStart(order_mask, bounds.peer_start + 1, bounds.partition_end, n); } } @@ -55327,8 +53690,8 @@ static void UpdateWindowBoundaries(WindowBoundariesState &bounds, const idx_t in } static void ComputeWindowExpression(BoundWindowExpression *wexpr, ChunkCollection &input, ChunkCollection &output, - ChunkCollection &over, const BitArray &partition_mask, - const BitArray &order_mask, WindowAggregationMode mode) { + ChunkCollection &over, const ValidityMask &partition_mask, + const ValidityMask &order_mask, WindowAggregationMode mode) { // TODO we could evaluate those expressions in parallel @@ -55365,6 +53728,42 @@ static void ComputeWindowExpression(BoundWindowExpression *wexpr, ChunkCollectio MaterializeExpression(wexpr->end_expr.get(), input, boundary_end_collection, wexpr->end_expr->IsScalar()); } + // Set up a validity mask for IGNORE NULLS + ValidityMask ignore_nulls; + if (wexpr->ignore_nulls) { + switch (wexpr->type) { + case ExpressionType::WINDOW_LEAD: + case ExpressionType::WINDOW_LAG: + case ExpressionType::WINDOW_FIRST_VALUE: + case ExpressionType::WINDOW_LAST_VALUE: + case ExpressionType::WINDOW_NTH_VALUE: { + idx_t pos = 0; + for (auto &chunk : payload_collection.Chunks()) { + const auto count = chunk->size(); + VectorData vdata; + chunk->data[0].Orrify(count, vdata); + if (!vdata.validity.AllValid()) { + // Lazily materialise the contents when we find the first NULL + if (ignore_nulls.AllValid()) { + ignore_nulls.Initialize(payload_collection.Count()); + } + // Write to the current position + // Chunks in a collection are full, so we don't have to worry about raggedness + auto dst = ignore_nulls.GetData() + ignore_nulls.EntryCount(pos); + auto src = vdata.validity.GetData(); + for (auto entry_count = vdata.validity.EntryCount(count); entry_count-- > 0;) { + *dst++ = *src++; + } + } + pos += count; + } + break; + } + default: + break; + } + } + // build a segment tree for frame-adhering aggregates // see http://www.vldb.org/pvldb/vol8/p1058-leis.pdf unique_ptr segment_tree = nullptr; @@ -55492,7 +53891,18 @@ static void ComputeWindowExpression(BoundWindowExpression *wexpr, ChunkCollectio val_idx -= offset; } - if (val_idx >= int64_t(bounds.partition_start) && val_idx < int64_t(bounds.partition_end)) { + idx_t delta = 0; + if (val_idx < (int64_t)row_idx) { + // Count backwards + delta = idx_t(row_idx - val_idx); + val_idx = FindPrevStart(ignore_nulls, bounds.partition_start, row_idx, delta); + } else if (val_idx > (int64_t)row_idx) { + delta = idx_t(val_idx - row_idx); + val_idx = FindNextStart(ignore_nulls, row_idx + 1, bounds.partition_end, delta); + } + // else offset is zero, so don't move. + + if (!delta) { payload_collection.CopyCell(0, val_idx, result, output_offset); } else if (wexpr->default_expr) { const auto source_row = wexpr->default_expr->IsScalar() ? 0 : row_idx; @@ -55502,12 +53912,18 @@ static void ComputeWindowExpression(BoundWindowExpression *wexpr, ChunkCollectio } break; } - case ExpressionType::WINDOW_FIRST_VALUE: - payload_collection.CopyCell(0, bounds.window_start, result, output_offset); + case ExpressionType::WINDOW_FIRST_VALUE: { + idx_t n = 1; + const auto first_idx = FindNextStart(ignore_nulls, bounds.window_start, bounds.window_end, n); + payload_collection.CopyCell(0, first_idx, result, output_offset); break; - case ExpressionType::WINDOW_LAST_VALUE: - payload_collection.CopyCell(0, bounds.window_end - 1, result, output_offset); + } + case ExpressionType::WINDOW_LAST_VALUE: { + idx_t n = 1; + payload_collection.CopyCell(0, FindPrevStart(ignore_nulls, bounds.window_start, bounds.window_end, n), + result, output_offset); break; + } case ExpressionType::WINDOW_NTH_VALUE: { D_ASSERT(payload_collection.ColumnCount() == 2); // Returns value evaluated at the row that is the n'th row of the window frame (counting from 1); @@ -55516,11 +53932,16 @@ static void ComputeWindowExpression(BoundWindowExpression *wexpr, ChunkCollectio FlatVector::SetNull(result, output_offset, true); } else { auto n_param = GetCell(payload_collection, 1, row_idx); - int64_t n_total = bounds.window_end - bounds.window_start; - if (0 < n_param && n_param <= n_total) { - payload_collection.CopyCell(0, bounds.window_start + n_param - 1, result, output_offset); - } else { + if (n_param < 1) { FlatVector::SetNull(result, output_offset, true); + } else { + auto n = idx_t(n_param); + const auto nth_index = FindNextStart(ignore_nulls, bounds.window_start, bounds.window_end, n); + if (!n) { + payload_collection.CopyCell(0, nth_index, result, output_offset); + } else { + FlatVector::SetNull(result, output_offset, true); + } } } break; @@ -55547,25 +53968,26 @@ static void ComputeWindowExpressions(WindowExpressions &window_exprs, ChunkColle auto over_expr = window_exprs[0]; // Set bits for the start of each partition - BitArray partition_bits(input.Count()); - partition_bits[0] = true; + vector partition_bits(ValidityMask::EntryCount(input.Count()), 0); + ValidityMask partition_mask(partition_bits.data()); + partition_mask.SetValid(0); for (idx_t c = 0; c < over_expr->partitions.size(); ++c) { - MaskColumn(partition_bits, over, c); + MaskColumn(partition_mask, over, c); } // Set bits for the start of each peer group. // Partitions also break peer groups, so start with the partition bits. const auto sort_col_count = over_expr->partitions.size() + over_expr->orders.size(); - auto order_bits = partition_bits; + ValidityMask order_mask(partition_mask, input.Count()); for (idx_t c = over_expr->partitions.size(); c < sort_col_count; ++c) { - MaskColumn(order_bits, over, c); + MaskColumn(order_mask, over, c); } // Compute the functions columnwise for (idx_t expr_idx = 0; expr_idx < window_exprs.size(); ++expr_idx) { ChunkCollection output; - ComputeWindowExpression(window_exprs[expr_idx], input, output, over, partition_bits, order_bits, mode); + ComputeWindowExpression(window_exprs[expr_idx], input, output, over, partition_mask, order_mask, mode); window_results.Fuse(output); } } @@ -55927,6 +54349,113 @@ PhysicalExecute::PhysicalExecute(PhysicalOperator *plan) : PhysicalOperator(PhysicalOperatorType::EXECUTE, plan->types, -1), plan(plan) { } +} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/execution/operator/helper/physical_explain_analyze.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { + +class PhysicalExplainAnalyze : public PhysicalOperator { +public: + PhysicalExplainAnalyze(vector types) + : PhysicalOperator(PhysicalOperatorType::EXPLAIN_ANALYZE, move(types), 1) { + } + +public: + // Source interface + unique_ptr GetGlobalSourceState(ClientContext &context) const override; + void GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate, + LocalSourceState &lstate) const override; + +public: + // Sink Interface + SinkResultType Sink(ExecutionContext &context, GlobalSinkState &state, LocalSinkState &lstate, + DataChunk &input) const override; + SinkFinalizeType Finalize(Pipeline &pipeline, Event &event, ClientContext &context, + GlobalSinkState &gstate) const override; + + unique_ptr GetGlobalSinkState(ClientContext &context) const override; + + bool IsSink() const override { + return true; + } + + bool ParallelSink() const override { + return true; + } +}; + +} // namespace duckdb + + + + +namespace duckdb { + +//===--------------------------------------------------------------------===// +// Sink +//===--------------------------------------------------------------------===// +class ExplainAnalyzeStateGlobalState : public GlobalSinkState { +public: + string analyzed_plan; +}; + +SinkResultType PhysicalExplainAnalyze::Sink(ExecutionContext &context, GlobalSinkState &state, LocalSinkState &lstate, + DataChunk &input) const { + return SinkResultType::NEED_MORE_INPUT; +} + +SinkFinalizeType PhysicalExplainAnalyze::Finalize(Pipeline &pipeline, Event &event, ClientContext &context, + GlobalSinkState &gstate_p) const { + auto &gstate = (ExplainAnalyzeStateGlobalState &)gstate_p; + auto &profiler = QueryProfiler::Get(context); + gstate.analyzed_plan = profiler.ToString(); + return SinkFinalizeType::READY; +} + +unique_ptr PhysicalExplainAnalyze::GetGlobalSinkState(ClientContext &context) const { + return make_unique(); +} + +//===--------------------------------------------------------------------===// +// Source +//===--------------------------------------------------------------------===// +class ExplainAnalyzeState : public GlobalSourceState { +public: + ExplainAnalyzeState() : finished(false) { + } + + bool finished; +}; + +unique_ptr PhysicalExplainAnalyze::GetGlobalSourceState(ClientContext &context) const { + return make_unique(); +} + +void PhysicalExplainAnalyze::GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &source_state, + LocalSourceState &lstate) const { + auto &state = (ExplainAnalyzeState &)source_state; + auto &gstate = (ExplainAnalyzeStateGlobalState &)*sink_state; + if (state.finished) { + return; + } + chunk.SetValue(0, 0, Value("analyzed_plan")); + chunk.SetValue(1, 0, Value(gstate.analyzed_plan)); + chunk.SetCardinality(1); + + state.finished = true; +} + } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB @@ -55976,6 +54505,9 @@ class PhysicalLimit : public PhysicalOperator { bool SinkOrderMatters() const override { return true; } + + static bool HandleOffset(DataChunk &input, idx_t ¤t_offset, idx_t offset, idx_t limit); + static Value GetDelimiter(DataChunk &input, Expression *expr); }; } // namespace duckdb @@ -55994,8 +54526,8 @@ namespace duckdb { class LimitGlobalState : public GlobalSinkState { public: explicit LimitGlobalState(const PhysicalLimit &op) : current_offset(0) { - this->limit = op.limit_expression ? INVALID_INDEX : op.limit_value; - this->offset = op.offset_expression ? INVALID_INDEX : op.offset_value; + this->limit = op.limit_expression ? DConstants::INVALID_INDEX : op.limit_value; + this->offset = op.offset_expression ? DConstants::INVALID_INDEX : op.offset_value; } idx_t current_offset; @@ -56004,25 +54536,6 @@ class LimitGlobalState : public GlobalSinkState { ChunkCollection data; }; -uint64_t GetDelimiter(DataChunk &input, Expression *expr, uint64_t original_value) { - DataChunk limit_chunk; - vector types {expr->return_type}; - limit_chunk.Initialize(types); - ExpressionExecutor limit_executor(expr); - auto input_size = input.size(); - input.SetCardinality(1); - limit_executor.Execute(input, limit_chunk); - input.SetCardinality(input_size); - auto limit_value = limit_chunk.GetValue(0, 0); - if (limit_value.is_null) { - return original_value; - } - if (limit_value.value_.ubigint > 1ULL << 62ULL) { - throw BinderException("Max value %lld for LIMIT/OFFSET is %lld", original_value, 1ULL << 62ULL); - } - return limit_value.value_.ubigint; -} - unique_ptr PhysicalLimit::GetGlobalSinkState(ClientContext &context) const { return make_unique(*this); } @@ -56034,7 +54547,7 @@ SinkResultType PhysicalLimit::Sink(ExecutionContext &context, GlobalSinkState &g auto &limit = state.limit; auto &offset = state.offset; - if (limit != INVALID_INDEX && offset != INVALID_INDEX) { + if (limit != DConstants::INVALID_INDEX && offset != DConstants::INVALID_INDEX) { idx_t max_element = limit + offset; if ((limit == 0 || state.current_offset >= max_element) && !(limit_expression || offset_expression)) { return SinkResultType::FINISHED; @@ -56042,23 +54555,76 @@ SinkResultType PhysicalLimit::Sink(ExecutionContext &context, GlobalSinkState &g } // get the next chunk from the child - if (limit == INVALID_INDEX) { - limit = GetDelimiter(input, limit_expression.get(), 1ULL << 62ULL); + if (limit == DConstants::INVALID_INDEX) { + limit = 1ULL << 62ULL; + Value val = GetDelimiter(input, limit_expression.get()); + if (!val.IsNull()) { + limit = val.GetValue(); + } + if (limit > 1ULL << 62ULL) { + throw BinderException("Max value %lld for LIMIT/OFFSET is %lld", limit, 1ULL << 62ULL); + } } - if (offset == INVALID_INDEX) { - offset = GetDelimiter(input, offset_expression.get(), 0); + if (offset == DConstants::INVALID_INDEX) { + offset = 0; + Value val = GetDelimiter(input, offset_expression.get()); + if (!val.IsNull()) { + offset = val.GetValue(); + } + if (offset > 1ULL << 62ULL) { + throw BinderException("Max value %lld for LIMIT/OFFSET is %lld", offset, 1ULL << 62ULL); + } } idx_t max_element = limit + offset; - idx_t input_size = input.size(); if (limit == 0 || state.current_offset >= max_element) { return SinkResultType::FINISHED; } - if (state.current_offset < offset) { + if (!HandleOffset(input, state.current_offset, offset, limit)) { + return SinkResultType::NEED_MORE_INPUT; + } + + state.data.Append(input); + return SinkResultType::NEED_MORE_INPUT; +} + +//===--------------------------------------------------------------------===// +// Source +//===--------------------------------------------------------------------===// +class LimitOperatorState : public GlobalSourceState { +public: + LimitOperatorState() : chunk_idx(0) { + } + + idx_t chunk_idx; +}; + +unique_ptr PhysicalLimit::GetGlobalSourceState(ClientContext &context) const { + return make_unique(); +} + +void PhysicalLimit::GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate_p, + LocalSourceState &lstate) const { + auto &gstate = (LimitGlobalState &)*sink_state; + auto &state = (LimitOperatorState &)gstate_p; + if (state.chunk_idx >= gstate.data.ChunkCount()) { + return; + } + chunk.Reference(gstate.data.GetChunk(state.chunk_idx)); + state.chunk_idx++; +} + +bool PhysicalLimit::HandleOffset(DataChunk &input, idx_t ¤t_offset, idx_t offset, idx_t limit) { + idx_t max_element = limit + offset; + if (limit == DConstants::INVALID_INDEX) { + max_element = DConstants::INVALID_INDEX; + } + idx_t input_size = input.size(); + if (current_offset < offset) { // we are not yet at the offset point - if (state.current_offset + input.size() > offset) { + if (current_offset + input.size() > offset) { // however we will reach it in this chunk // we have to copy part of the chunk with an offset - idx_t start_position = offset - state.current_offset; + idx_t start_position = offset - current_offset; auto chunk_count = MinValue(limit, input.size() - start_position); SelectionVector sel(STANDARD_VECTOR_SIZE); for (idx_t i = 0; i < chunk_count; i++) { @@ -56067,15 +54633,15 @@ SinkResultType PhysicalLimit::Sink(ExecutionContext &context, GlobalSinkState &g // set up a slice of the input chunks input.Slice(input, sel, chunk_count); } else { - state.current_offset += input_size; - return SinkResultType::NEED_MORE_INPUT; + current_offset += input_size; + return false; } } else { // have to copy either the entire chunk or part of it idx_t chunk_count; - if (state.current_offset + input.size() >= max_element) { + if (current_offset + input.size() >= max_element) { // have to limit the count of the chunk - chunk_count = max_element - state.current_offset; + chunk_count = max_element - current_offset; } else { // we copy the entire chunk chunk_count = input.size(); @@ -56085,7 +54651,154 @@ SinkResultType PhysicalLimit::Sink(ExecutionContext &context, GlobalSinkState &g input.SetCardinality(chunk_count); } - state.current_offset += input_size; + current_offset += input_size; + return true; +} + +Value PhysicalLimit::GetDelimiter(DataChunk &input, Expression *expr) { + DataChunk limit_chunk; + vector types {expr->return_type}; + limit_chunk.Initialize(types); + ExpressionExecutor limit_executor(expr); + auto input_size = input.size(); + input.SetCardinality(1); + limit_executor.Execute(input, limit_chunk); + input.SetCardinality(input_size); + auto limit_value = limit_chunk.GetValue(0, 0); + return limit_value; +} + +} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/execution/operator/helper/physical_limit_percent.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { + +//! PhyisicalLimitPercent represents the LIMIT PERCENT operator +class PhysicalLimitPercent : public PhysicalOperator { +public: + 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)) { + } + + double limit_percent; + idx_t offset_value; + unique_ptr limit_expression; + unique_ptr offset_expression; + +public: + // Source interface + unique_ptr GetGlobalSourceState(ClientContext &context) const override; + void GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate, + LocalSourceState &lstate) const override; + +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; + } + + bool SinkOrderMatters() const override { + return true; + } +}; + +} // namespace duckdb + + + + + + + + +namespace duckdb { + +//===--------------------------------------------------------------------===// +// Sink +//===--------------------------------------------------------------------===// +class LimitPercentGlobalState : public GlobalSinkState { +public: + explicit LimitPercentGlobalState(const PhysicalLimitPercent &op) : current_offset(0) { + if (!op.limit_expression) { + this->limit_percent = op.limit_percent; + is_limit_percent_delimited = true; + } else { + this->limit_percent = 100.0; + } + + if (!op.offset_expression) { + this->offset = op.offset_value; + is_offset_delimited = true; + } else { + this->offset = 0; + } + } + + idx_t current_offset; + double limit_percent; + idx_t offset; + ChunkCollection data; + + bool is_limit_percent_delimited = false; + bool is_offset_delimited = false; +}; + +unique_ptr PhysicalLimitPercent::GetGlobalSinkState(ClientContext &context) const { + return make_unique(*this); +} + +SinkResultType PhysicalLimitPercent::Sink(ExecutionContext &context, GlobalSinkState &gstate, LocalSinkState &lstate, + DataChunk &input) const { + D_ASSERT(input.size() > 0); + auto &state = (LimitPercentGlobalState &)gstate; + auto &limit_percent = state.limit_percent; + auto &offset = state.offset; + + // get the next chunk from the child + if (!state.is_limit_percent_delimited) { + Value val = PhysicalLimit::GetDelimiter(input, limit_expression.get()); + if (!val.IsNull()) { + limit_percent = val.GetValue(); + } + if (limit_percent < 0.0) { + throw BinderException("Percentage value(%f) can't be negative", limit_percent); + } + state.is_limit_percent_delimited = true; + } + if (!state.is_offset_delimited) { + Value val = PhysicalLimit::GetDelimiter(input, offset_expression.get()); + if (!val.IsNull()) { + offset = val.GetValue(); + } + if (offset > 1ULL << 62ULL) { + throw BinderException("Max value %lld for LIMIT/OFFSET is %lld", offset, 1ULL << 62ULL); + } + state.is_offset_delimited = true; + } + + if (!PhysicalLimit::HandleOffset(input, state.current_offset, offset, DConstants::INVALID_INDEX)) { + return SinkResultType::NEED_MORE_INPUT; + } + state.data.Append(input); return SinkResultType::NEED_MORE_INPUT; } @@ -56093,27 +54806,49 @@ SinkResultType PhysicalLimit::Sink(ExecutionContext &context, GlobalSinkState &g //===--------------------------------------------------------------------===// // Source //===--------------------------------------------------------------------===// -class LimitOperatorState : public GlobalSourceState { +class LimitPercentOperatorState : public GlobalSourceState { public: - LimitOperatorState() : chunk_idx(0) { + LimitPercentOperatorState() : chunk_idx(0), limit(DConstants::INVALID_INDEX), current_offset(0) { } idx_t chunk_idx; + idx_t limit; + idx_t current_offset; }; -unique_ptr PhysicalLimit::GetGlobalSourceState(ClientContext &context) const { - return make_unique(); +unique_ptr PhysicalLimitPercent::GetGlobalSourceState(ClientContext &context) const { + return make_unique(); } -void PhysicalLimit::GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate_p, - LocalSourceState &lstate) const { - auto &gstate = (LimitGlobalState &)*sink_state; - auto &state = (LimitOperatorState &)gstate_p; - if (state.chunk_idx >= gstate.data.ChunkCount()) { +void PhysicalLimitPercent::GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate_p, + LocalSourceState &lstate) const { + auto &gstate = (LimitPercentGlobalState &)*sink_state; + auto &state = (LimitPercentOperatorState &)gstate_p; + auto &limit_percent = gstate.limit_percent; + auto &offset = gstate.offset; + auto &limit = state.limit; + auto ¤t_offset = state.current_offset; + + if (gstate.is_limit_percent_delimited && limit == DConstants::INVALID_INDEX) { + idx_t count = gstate.data.Count(); + if (count > 0) { + count += offset; + } + limit = MinValue((idx_t)(limit_percent / 100 * count), count); + if (limit == 0) { + return; + } + } + + if (current_offset >= limit || state.chunk_idx >= gstate.data.ChunkCount()) { return; } - chunk.Reference(gstate.data.GetChunk(state.chunk_idx)); + + DataChunk &input = gstate.data.GetChunk(state.chunk_idx); state.chunk_idx++; + if (PhysicalLimit::HandleOffset(input, current_offset, 0, limit)) { + chunk.Reference(input); + } } } // namespace duckdb @@ -56142,13 +54877,17 @@ void PhysicalLimit::GetData(ExecutionContext &context, DataChunk &chunk, GlobalS namespace duckdb { +enum class LoadType { LOAD, INSTALL, FORCE_INSTALL }; + struct LoadInfo : public ParseInfo { std::string filename; + LoadType load_type; public: unique_ptr Copy() const { auto result = make_unique(); result->filename = filename; + result->load_type = load_type; return result; } }; @@ -56176,73 +54915,52 @@ class PhysicalLoad : public PhysicalOperator { } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/extension_helper.hpp +// +// +//===----------------------------------------------------------------------===// +#include -#ifndef _WIN32 -#include -#else -#define RTLD_LAZY 0 -#define RTLD_LOCAL 0 -#endif - namespace duckdb { +class DuckDB; -#ifdef _WIN32 +enum class ExtensionLoadResult : uint8_t { LOADED_EXTENSION = 0, EXTENSION_UNKNOWN = 1, NOT_LOADED = 2 }; -void *dlopen(const char *file, int mode) { - D_ASSERT(file); - return (void *)LoadLibrary(file); -} +class ExtensionHelper { +public: + static void LoadAllExtensions(DuckDB &db); -void *dlsym(void *handle, const char *name) { - D_ASSERT(handle); - return (void *)GetProcAddress((HINSTANCE)handle, name); -} -#endif + static ExtensionLoadResult LoadExtension(DuckDB &db, const std::string &extension); -void PhysicalLoad::GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate_p, - LocalSourceState &lstate) const { - auto &fs = FileSystem::GetFileSystem(context.client); - auto filename = fs.ConvertSeparators(info->filename); - if (!fs.FileExists(filename)) { - throw InvalidInputException("File %s not found", filename); - } - auto lib_hdl = dlopen(filename.c_str(), RTLD_LAZY | RTLD_LOCAL); - if (!lib_hdl) { - throw InvalidInputException("File %s could not be loaded", filename); - } + static void InstallExtension(DatabaseInstance &db, const string &extension, bool force_install); + static void LoadExternalExtension(DatabaseInstance &db, const string &extension); - auto basename = fs.ExtractBaseName(filename); - auto init_fun_name = basename + "_init"; - auto version_fun_name = basename + "_version"; +private: + static const vector PathComponents(); - void (*init_fun)(DatabaseInstance &); - const char *(*version_fun)(void); +private: + static ExtensionLoadResult LoadExtensionInternal(DuckDB &db, const std::string &extension, bool initial_load); +}; - *(void **)(&init_fun) = dlsym(lib_hdl, init_fun_name.c_str()); - if (init_fun == nullptr) { - throw InvalidInputException("File %s did not contain initialization function %s", filename, init_fun_name); - } +} // namespace duckdb - *(void **)(&version_fun) = dlsym(lib_hdl, version_fun_name.c_str()); - if (init_fun == nullptr) { - throw InvalidInputException("File %s did not contain version function %s", filename, version_fun_name); - } - auto extension_version = std::string((*version_fun)()); - auto engine_version = DuckDB::LibraryVersion(); - if (extension_version != engine_version) { - throw InvalidInputException("Extension %s version (%s) does not match DuckDB version (%s)", filename, - extension_version, engine_version); - } - try { - (*init_fun)(*context.client.db); - } catch (Exception &e) { - throw InvalidInputException("Initialization function %s from file %s threw an exception: %s", init_fun_name, - filename, e.what()); +namespace duckdb { + +void PhysicalLoad::GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate_p, + LocalSourceState &lstate) const { + auto &db = DatabaseInstance::GetDatabase(context.client); + if (info->load_type == LoadType::INSTALL || info->load_type == LoadType::FORCE_INSTALL) { + ExtensionHelper::InstallExtension(db, info->filename, info->load_type == LoadType::FORCE_INSTALL); + } else { + ExtensionHelper::LoadExternalExtension(db, info->filename); } } @@ -56652,27 +55370,6 @@ string PhysicalReservoirSample::ParamsToString() const { -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/enums/set_scope.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -namespace duckdb { - -enum class SetScope : uint8_t { - LOCAL = 0, /* Not implemented*/ - SESSION = 1, - GLOBAL = 2 -}; - -} // namespace duckdb //===----------------------------------------------------------------------===// @@ -56715,10 +55412,6 @@ class PhysicalSet : public PhysicalOperator { const std::string name; const Value value; const SetScope scope; - -private: - //! Returns the normalized key name. - string ValidateInput(ExecutionContext &context) const; }; } // namespace duckdb @@ -56732,38 +55425,70 @@ namespace duckdb { void PhysicalSet::GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate, LocalSourceState &lstate) const { - D_ASSERT(scope == SetScope::GLOBAL || scope == SetScope::SESSION); - - auto normalized_name = ValidateInput(context); - if (scope == SetScope::GLOBAL) { - context.client.db->config.set_variables[normalized_name] = value; - } else { - context.client.set_variables[normalized_name] = value; + 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; + for (idx_t i = 0, option_count = DBConfig::GetOptionCount(); i < option_count; i++) { + potential_names.emplace_back(DBConfig::GetOptionByIndex(i)->name); + } + 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")); + } + //! it is! + auto &extension_option = entry->second; + auto &target_type = extension_option.type; + Value target_value = value.CastAs(target_type); + if (extension_option.set_function) { + extension_option.set_function(context.client, scope, target_value); + } + if (scope == SetScope::GLOBAL) { + config.set_variables[name] = move(target_value); + } else { + auto &client_config = ClientConfig::GetConfig(context.client); + client_config.set_variables[name] = move(target_value); + } + return; } -} - -string PhysicalSet::ValidateInput(ExecutionContext &context) const { - CaseInsensitiveStringEquality case_insensitive_streq; - if (case_insensitive_streq(name, "search_path") || case_insensitive_streq(name, "schema")) { - auto paths = StringUtil::SplitWithQuote(value.str_value, ','); - - // The PG doc says: - // > SET SCHEMA 'value' is an alias for SET search_path TO value. - // > Only one schema can be specified using this syntax. - if (case_insensitive_streq(name, "schema") && paths.size() > 1) { - throw CatalogException("SET schema can set only 1 schema. This has %d", paths.size()); + 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; } + } - for (const auto &path : paths) { - if (!context.client.db->GetCatalog().GetSchema(context.client, StringUtil::Lower(path), true)) { - throw CatalogException("SET %s: No schema named %s found.", name, path); - } + Value input = value.CastAs(option->parameter_type); + switch (variable_scope) { + case SetScope::GLOBAL: { + if (!option->set_global) { + throw CatalogException("option \"%s\" cannot be set globally", name); } - - return "search_path"; + auto &db = DatabaseInstance::GetDatabase(context.client); + auto &config = DBConfig::GetConfig(context.client); + option->set_global(&db, config, input); + break; + } + case SetScope::SESSION: + if (!option->set_local) { + throw CatalogException("option \"%s\" cannot be set locally", name); + } + option->set_local(context.client, input); + break; + default: + throw InternalException("Unsupported SetScope for variable"); } - - return name; } } // namespace duckdb @@ -57356,7 +56081,7 @@ bool PerfectHashJoinExecutor::FillSelectionVectorSwitchBuild(Vector &source, Sel template bool PerfectHashJoinExecutor::TemplatedFillSelectionVectorBuild(Vector &source, SelectionVector &sel_vec, SelectionVector &seq_sel_vec, idx_t count) { - if (perfect_join_statistics.build_min.is_null || perfect_join_statistics.build_max.is_null) { + if (perfect_join_statistics.build_min.IsNull() || perfect_join_statistics.build_max.IsNull()) { return false; } auto min_value = perfect_join_statistics.build_min.GetValueUnsafe(); @@ -58475,8 +57200,9 @@ SinkResultType PhysicalHashJoin::Sink(ExecutionContext &context, GlobalSinkState void PhysicalHashJoin::Combine(ExecutionContext &context, GlobalSinkState &gstate, LocalSinkState &lstate) const { auto &state = (HashJoinLocalState &)lstate; + auto &client_profiler = QueryProfiler::Get(context.client); context.thread.profiler.Flush(this, &state.build_executor, "build_executor", 1); - context.client.profiler->Flush(context.thread.profiler); + client_profiler.Flush(context.thread.profiler); } //===--------------------------------------------------------------------===// @@ -58771,6 +57497,7 @@ struct TableScanBindData : public FunctionData { //! The table scan function represents a sequential scan over one of DuckDB's base tables. struct TableScanFunction { static TableFunction GetFunction(); + static TableCatalogEntry *GetTableEntry(const TableFunction &function, const FunctionData *bind_data); }; } // namespace duckdb @@ -58889,7 +57616,7 @@ void PhysicalIndexJoin::Output(ExecutionContext &context, DataChunk &input, Data } state.rhs_chunk.Reset(); ColumnFetchState fetch_state; - Vector row_ids(LOGICAL_ROW_TYPE, (data_ptr_t)&fetch_rows[0]); + 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, fetch_state); } @@ -58921,7 +57648,7 @@ void PhysicalIndexJoin::GetRHSMatches(ExecutionContext &context, DataChunk &inpu auto equal_value = state.join_keys.GetValue(0, i); auto index_state = art.InitializeScanSinglePredicate(transaction, equal_value, ExpressionType::COMPARE_EQUAL); state.rhs_rows[i].clear(); - if (!equal_value.is_null) { + if (!equal_value.IsNull()) { if (fetch_types.empty()) { IndexLock lock; index->InitializeLock(lock); @@ -59239,8 +57966,10 @@ SinkResultType PhysicalNestedLoopJoin::Sink(ExecutionContext &context, GlobalSin void PhysicalNestedLoopJoin::Combine(ExecutionContext &context, GlobalSinkState &gstate, LocalSinkState &lstate) const { auto &state = (NestedLoopJoinLocalState &)lstate; + auto &client_profiler = QueryProfiler::Get(context.client); + context.thread.profiler.Flush(this, &state.rhs_executor, "rhs_executor", 1); - context.client.profiler->Flush(context.thread.profiler); + client_profiler.Flush(context.thread.profiler); } SinkFinalizeType PhysicalNestedLoopJoin::Finalize(Pipeline &pipeline, Event &event, ClientContext &context, @@ -59510,6 +58239,8 @@ void PhysicalNestedLoopJoin::GetData(ExecutionContext &context, DataChunk &chunk namespace duckdb { +class MergeJoinGlobalState; + //! PhysicalPiecewiseMergeJoin represents a piecewise merge loop join between //! two tables class PhysicalPiecewiseMergeJoin : public PhysicalComparisonJoin { @@ -59519,6 +58250,8 @@ class PhysicalPiecewiseMergeJoin : public PhysicalComparisonJoin { idx_t estimated_cardinality); vector join_key_types; + vector lhs_orders; + vector rhs_orders; public: // Operator Interface @@ -59557,6 +58290,9 @@ class PhysicalPiecewiseMergeJoin : public PhysicalComparisonJoin { SinkFinalizeType Finalize(Pipeline &pipeline, Event &event, ClientContext &context, GlobalSinkState &gstate) const override; + //! Schedules tasks to merge sort the RHS data during the Finalize phase + static void ScheduleMergeTasks(Pipeline &pipeline, Event &event, MergeJoinGlobalState &state); + bool IsSink() const override { return true; } @@ -59581,6 +58317,11 @@ class PhysicalPiecewiseMergeJoin : public PhysicalComparisonJoin { + + + + + namespace duckdb { PhysicalPiecewiseMergeJoin::PhysicalPiecewiseMergeJoin(LogicalOperator &op, unique_ptr left, @@ -59591,10 +58332,27 @@ PhysicalPiecewiseMergeJoin::PhysicalPiecewiseMergeJoin(LogicalOperator &op, uniq // for now we only support one condition! D_ASSERT(conditions.size() == 1); for (auto &cond : conditions) { - // COMPARE NOT EQUAL not supported with merge join - D_ASSERT(cond.comparison != ExpressionType::COMPARE_NOTEQUAL); D_ASSERT(cond.left->return_type == cond.right->return_type); join_key_types.push_back(cond.left->return_type); + + // Convert the conditions to sort orders + auto left = cond.left->Copy(); + auto right = cond.right->Copy(); + 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))); + 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))); + break; + default: + // COMPARE NOT EQUAL not supported with merge join + throw NotImplementedException("Unimplemented join type for merge join"); + } } children.push_back(move(left)); children.push_back(move(right)); @@ -59603,112 +58361,242 @@ PhysicalPiecewiseMergeJoin::PhysicalPiecewiseMergeJoin(LogicalOperator &op, uniq //===--------------------------------------------------------------------===// // Sink //===--------------------------------------------------------------------===// -class MergeJoinLocalState : public LocalSinkState { +class MergeJoinGlobalState : public GlobalSinkState { public: - explicit MergeJoinLocalState(const vector &conditions) { - vector condition_types; - for (auto &cond : conditions) { - rhs_executor.AddExpression(*cond.right); - condition_types.push_back(cond.right->return_type); - } - join_keys.Initialize(condition_types); + MergeJoinGlobalState(BufferManager &buffer_manager, const vector &orders, RowLayout &rhs_layout) + : rhs_global_sort_state(buffer_manager, orders, rhs_layout), rhs_has_null(0), rhs_count(0), + memory_per_thread(0) { } - //! The chunk holding the right condition - DataChunk join_keys; - //! The executor of the RHS condition - ExpressionExecutor rhs_executor; -}; - -class MergeJoinGlobalState : public GlobalSinkState { -public: - MergeJoinGlobalState() : has_null(false), right_outer_position(0) { + inline idx_t Count() const { + return rhs_count; } - mutex mj_lock; - //! The materialized data of the RHS - ChunkCollection right_chunks; - //! The materialized join keys of the RHS - ChunkCollection right_conditions; - //! The join orders of the RHS - vector right_orders; - //! Whether or not the RHS of the nested loop join has NULL values - bool has_null; + //! The lock for updating the global state + mutex lock; + //! Global sort state + GlobalSortState rhs_global_sort_state; + //! Whether or not the RHS has NULL values + idx_t rhs_has_null; + //! The total number of rows in the RHS + idx_t rhs_count; //! A bool indicating for each tuple in the RHS if they found a match (only used in FULL OUTER JOIN) - unique_ptr right_found_match; - //! The position in the RHS in the final scan of the FULL OUTER JOIN - idx_t right_outer_position; + unique_ptr rhs_found_match; + //! Memory usage per thread + idx_t memory_per_thread; }; unique_ptr PhysicalPiecewiseMergeJoin::GetGlobalSinkState(ClientContext &context) const { - return make_unique(); + // Get the payload layout from the rhs types + RowLayout rhs_layout; + auto types = children[1]->types; + rhs_layout.Initialize(types); + auto state = make_unique(BufferManager::GetBufferManager(context), rhs_orders, rhs_layout); + // Set external (can be force with the PRAGMA) + auto &config = ClientConfig::GetConfig(context); + state->rhs_global_sort_state.external = config.force_external; + // Memory usage per thread should scale with max mem / num threads + // We take 1/4th of this, to be conservative + idx_t max_memory = BufferManager::GetBufferManager(context).GetMaxMemory(); + idx_t num_threads = TaskScheduler::GetScheduler(context).NumberOfThreads(); + state->memory_per_thread = (max_memory / num_threads) / 4; + return move(state); +} + +static idx_t CountValid(Vector &v, const idx_t count) { + idx_t valid = 0; + + VectorData vdata; + v.Orrify(count, vdata); + if (vdata.validity.AllValid()) { + return count; + } + switch (v.GetVectorType()) { + case VectorType::FLAT_VECTOR: + valid += vdata.validity.CountValid(count); + break; + case VectorType::CONSTANT_VECTOR: + valid += vdata.validity.CountValid(1) * count; + break; + default: + for (idx_t i = 0; i < count; ++i) { + const auto row_idx = vdata.sel->get_index(i); + valid += int(vdata.validity.RowIsValid(row_idx)); + } + break; + } + + return valid; } +class MergeJoinLocalState : public LocalSinkState { +public: + explicit MergeJoinLocalState() : rhs_has_null(0), rhs_count(0) { + } + + //! The local sort state + LocalSortState rhs_local_sort_state; + //! Local copy of the sorting expression executor + ExpressionExecutor rhs_executor; + //! Holds a vector of incoming sorting columns + DataChunk rhs_keys; + //! Whether or not the RHS has NULL values + idx_t rhs_has_null; + //! The total number of rows in the RHS + idx_t rhs_count; +}; + unique_ptr PhysicalPiecewiseMergeJoin::GetLocalSinkState(ExecutionContext &context) const { - return make_unique(conditions); + auto result = make_unique(); + // Initialize order clause expression executor and DataChunk + vector types; + for (auto &order : rhs_orders) { + types.push_back(order.expression->return_type); + result->rhs_executor.AddExpression(*order.expression); + } + result->rhs_keys.Initialize(types); + return move(result); } -SinkResultType PhysicalPiecewiseMergeJoin::Sink(ExecutionContext &context, GlobalSinkState &state, - LocalSinkState &lstate, DataChunk &input) const { - auto &gstate = (MergeJoinGlobalState &)state; - auto &mj_state = (MergeJoinLocalState &)lstate; +SinkResultType PhysicalPiecewiseMergeJoin::Sink(ExecutionContext &context, GlobalSinkState &gstate_p, + LocalSinkState &lstate_p, DataChunk &input) const { + auto &gstate = (MergeJoinGlobalState &)gstate_p; + auto &lstate = (MergeJoinLocalState &)lstate_p; - // resolve the join keys for this chunk - mj_state.rhs_executor.SetChunk(input); + auto &global_sort_state = gstate.rhs_global_sort_state; + auto &local_sort_state = lstate.rhs_local_sort_state; - mj_state.join_keys.Reset(); - mj_state.join_keys.SetCardinality(input); - for (idx_t k = 0; k < conditions.size(); k++) { - // resolve the join key - mj_state.rhs_executor.ExecuteExpression(k, mj_state.join_keys.data[k]); + // Initialize local state (if necessary) + if (!local_sort_state.initialized) { + local_sort_state.Initialize(global_sort_state, BufferManager::GetBufferManager(context.client)); + } + + // Obtain sorting columns + auto &join_keys = lstate.rhs_keys; + join_keys.Reset(); + lstate.rhs_executor.Execute(input, join_keys); + + // Count the NULLs so we can exclude them later + // TODO: Sort any comparison NULLs to the end using an initial sort column + const auto count = join_keys.size(); + for (auto &key : join_keys.data) { + lstate.rhs_has_null += (count - CountValid(key, count)); + } + lstate.rhs_count += count; + + // Sink the data into the local sort state + local_sort_state.SinkChunk(join_keys, input); + + // When sorting data reaches a certain size, we sort it + if (local_sort_state.SizeInBytes() >= gstate.memory_per_thread) { + local_sort_state.Sort(global_sort_state, true); } - // append the join keys and the chunk to the chunk collection - lock_guard mj_guard(gstate.mj_lock); - gstate.right_chunks.Append(input); - gstate.right_conditions.Append(mj_state.join_keys); return SinkResultType::NEED_MORE_INPUT; } -void PhysicalPiecewiseMergeJoin::Combine(ExecutionContext &context, GlobalSinkState &gstate, - LocalSinkState &lstate) const { - auto &state = (MergeJoinLocalState &)lstate; - context.thread.profiler.Flush(this, &state.rhs_executor, "rhs_executor", 1); - context.client.profiler->Flush(context.thread.profiler); +void PhysicalPiecewiseMergeJoin::Combine(ExecutionContext &context, GlobalSinkState &gstate_p, + LocalSinkState &lstate_p) const { + auto &gstate = (MergeJoinGlobalState &)gstate_p; + auto &lstate = (MergeJoinLocalState &)lstate_p; + gstate.rhs_global_sort_state.AddLocalState(lstate.rhs_local_sort_state); + lock_guard locked(gstate.lock); + gstate.rhs_has_null += lstate.rhs_has_null; + gstate.rhs_count += lstate.rhs_count; + auto &client_profiler = QueryProfiler::Get(context.client); + + context.thread.profiler.Flush(this, &lstate.rhs_executor, "rhs_executor", 1); + client_profiler.Flush(context.thread.profiler); } //===--------------------------------------------------------------------===// // Finalize //===--------------------------------------------------------------------===// -static void OrderVector(Vector &vector, idx_t count, MergeOrder &order); +class MergeJoinFinalizeTask : public ExecutorTask { +public: + MergeJoinFinalizeTask(shared_ptr event_p, ClientContext &context, MergeJoinGlobalState &state) + : ExecutorTask(context), event(move(event_p)), context(context), state(state) { + } + + TaskExecutionResult ExecuteTask(TaskExecutionMode mode) override { + // Initialize merge sorted and iterate until done + auto &global_sort_state = state.rhs_global_sort_state; + MergeSorter merge_sorter(global_sort_state, BufferManager::GetBufferManager(context)); + merge_sorter.PerformInMergeRound(); + event->FinishTask(); + + return TaskExecutionResult::TASK_FINISHED; + } + +private: + shared_ptr event; + ClientContext &context; + MergeJoinGlobalState &state; +}; + +class MergeJoinFinalizeEvent : public Event { +public: + MergeJoinFinalizeEvent(MergeJoinGlobalState &gstate_p, Pipeline &pipeline_p) + : Event(pipeline_p.executor), gstate(gstate_p), pipeline(pipeline_p) { + } + + MergeJoinGlobalState &gstate; + Pipeline &pipeline; + +public: + void Schedule() override { + auto &context = pipeline.GetClientContext(); + + // Schedule tasks equal to the number of threads, which will each merge multiple partitions + auto &ts = TaskScheduler::GetScheduler(context); + idx_t num_threads = ts.NumberOfThreads(); + + vector> merge_tasks; + for (idx_t tnum = 0; tnum < num_threads; tnum++) { + merge_tasks.push_back(make_unique(shared_from_this(), context, gstate)); + } + SetTasks(move(merge_tasks)); + } + + void FinishEvent() override { + auto &global_sort_state = gstate.rhs_global_sort_state; + + global_sort_state.CompleteMergeRound(true); + if (global_sort_state.sorted_blocks.size() > 1) { + // Multiple blocks remaining: Schedule the next round + PhysicalPiecewiseMergeJoin::ScheduleMergeTasks(pipeline, *this, gstate); + } + } +}; + +void PhysicalPiecewiseMergeJoin::ScheduleMergeTasks(Pipeline &pipeline, Event &event, MergeJoinGlobalState &gstate) { + // Initialize global sort state for a round of merging + gstate.rhs_global_sort_state.InitializeMergeRound(); + auto new_event = make_shared(gstate, pipeline); + event.InsertEvent(move(new_event)); +} SinkFinalizeType PhysicalPiecewiseMergeJoin::Finalize(Pipeline &pipeline, Event &event, ClientContext &context, GlobalSinkState &gstate_p) const { auto &gstate = (MergeJoinGlobalState &)gstate_p; - if (gstate.right_conditions.ChunkCount() > 0) { - // now order all the chunks - gstate.right_orders.resize(gstate.right_conditions.ChunkCount()); - for (idx_t i = 0; i < gstate.right_conditions.ChunkCount(); i++) { - auto &chunk_to_order = gstate.right_conditions.GetChunk(i); - D_ASSERT(chunk_to_order.ColumnCount() == 1); - for (idx_t col_idx = 0; col_idx < chunk_to_order.ColumnCount(); col_idx++) { - OrderVector(chunk_to_order.data[col_idx], chunk_to_order.size(), gstate.right_orders[i]); - if (gstate.right_orders[i].count < chunk_to_order.size()) { - // the amount of entries in the order vector is smaller than the amount of entries in the vector - // this only happens if there are NULL values in the right-hand side - // hence we set the has_null to true (this is required for the MARK join) - gstate.has_null = true; - } - } - } - } + auto &global_sort_state = gstate.rhs_global_sort_state; + if (IsRightOuterJoin(join_type)) { // for FULL/RIGHT OUTER JOIN, initialize found_match to false for every tuple - gstate.right_found_match = unique_ptr(new bool[gstate.right_chunks.Count()]); - memset(gstate.right_found_match.get(), 0, sizeof(bool) * gstate.right_chunks.Count()); + gstate.rhs_found_match = unique_ptr(new bool[gstate.Count()]); + memset(gstate.rhs_found_match.get(), 0, sizeof(bool) * gstate.Count()); } - if (gstate.right_chunks.Count() == 0 && EmptyResultIfRHSIsEmpty()) { + if (global_sort_state.sorted_blocks.empty() && EmptyResultIfRHSIsEmpty()) { + // Empty input! return SinkFinalizeType::NO_OUTPUT_POSSIBLE; } + + // Prepare for merge sort phase + global_sort_state.PrepareMergePhase(); + + // Start the merge phase or finish if a merge is not necessary + if (global_sort_state.sorted_blocks.size() > 1) { + PhysicalPiecewiseMergeJoin::ScheduleMergeTasks(pipeline, event, gstate); + } return SinkFinalizeType::READY; } @@ -59717,43 +58605,75 @@ SinkFinalizeType PhysicalPiecewiseMergeJoin::Finalize(Pipeline &pipeline, Event //===--------------------------------------------------------------------===// class PiecewiseMergeJoinState : public OperatorState { public: - explicit PiecewiseMergeJoinState(const PhysicalPiecewiseMergeJoin &op) - : op(op), first_fetch(true), finished(true), left_position(0), right_position(0), right_chunk_index(0) { + explicit PiecewiseMergeJoinState(const PhysicalPiecewiseMergeJoin &op, BufferManager &buffer_manager, + bool force_external) + : op(op), buffer_manager(buffer_manager), force_external(force_external), left_position(0), first_fetch(true), + finished(true), right_position(0), right_chunk_index(0) { vector condition_types; for (auto &cond : op.conditions) { lhs_executor.AddExpression(*cond.left); condition_types.push_back(cond.left->return_type); } - join_keys.Initialize(condition_types); + lhs_keys.Initialize(condition_types); if (IsLeftOuterJoin(op.join_type)) { - left_found_match = unique_ptr(new bool[STANDARD_VECTOR_SIZE]); - memset(left_found_match.get(), 0, sizeof(bool) * STANDARD_VECTOR_SIZE); + lhs_found_match = unique_ptr(new bool[STANDARD_VECTOR_SIZE]); + memset(lhs_found_match.get(), 0, sizeof(bool) * STANDARD_VECTOR_SIZE); } + lhs_layout.Initialize(op.children[0]->types); } const PhysicalPiecewiseMergeJoin &op; + BufferManager &buffer_manager; + bool force_external; + + // Block sorting + DataChunk lhs_keys; + ExpressionExecutor lhs_executor; + unique_ptr lhs_found_match; + RowLayout lhs_layout; + unique_ptr lhs_local_state; + unique_ptr lhs_global_state; + idx_t lhs_count; + idx_t lhs_has_null; + + // Simple scans + idx_t left_position; + + // Complex scans bool first_fetch; bool finished; - idx_t left_position; idx_t right_position; idx_t right_chunk_index; - DataChunk left_chunk; - DataChunk join_keys; - MergeOrder left_orders; - //! The executor of the RHS condition - ExpressionExecutor lhs_executor; - unique_ptr left_found_match; + idx_t right_base; public: void ResolveJoinKeys(DataChunk &input) { // resolve the join keys for the input - join_keys.Reset(); - lhs_executor.SetChunk(input); - join_keys.SetCardinality(input); - for (idx_t k = 0; k < op.conditions.size(); k++) { - lhs_executor.ExecuteExpression(k, join_keys.data[k]); - // sort by join key - OrderVector(join_keys.data[k], join_keys.size(), left_orders); + lhs_keys.Reset(); + lhs_executor.Execute(input, lhs_keys); + + // Count the NULLs so we can exclude them later + // TODO: Sort any multi-comparison NULLs to the end using an initial sort column + lhs_count = lhs_keys.size(); + for (auto &key : lhs_keys.data) { + lhs_has_null = lhs_count - CountValid(key, lhs_count); + break; + } + + // sort by join key + lhs_global_state = make_unique(buffer_manager, op.lhs_orders, lhs_layout); + lhs_local_state = make_unique(); + lhs_local_state->Initialize(*lhs_global_state, buffer_manager); + lhs_local_state->SinkChunk(lhs_keys, input); + + // Set external (can be force with the PRAGMA) + lhs_global_state->external = force_external; + lhs_global_state->AddLocalState(*lhs_local_state); + lhs_global_state->PrepareMergePhase(); + while (lhs_global_state->sorted_blocks.size() > 1) { + MergeSorter merge_sorter(*lhs_global_state, buffer_manager); + merge_sorter.PerformInMergeRound(); + lhs_global_state->CompleteMergeRound(); } } @@ -59763,7 +58683,176 @@ class PiecewiseMergeJoinState : public OperatorState { }; unique_ptr PhysicalPiecewiseMergeJoin::GetOperatorState(ClientContext &context) const { - return make_unique(*this); + auto &buffer_manager = BufferManager::GetBufferManager(context); + auto &config = ClientConfig::GetConfig(context); + return make_unique(*this, buffer_manager, config.force_external); +} + +static inline idx_t SortedBlockNotNull(const idx_t base, const idx_t count, const idx_t not_null) { + return MinValue(base + count, MaxValue(base, not_null)) - base; +} + +static int MergeJoinComparisonValue(ExpressionType comparison) { + switch (comparison) { + case ExpressionType::COMPARE_LESSTHAN: + case ExpressionType::COMPARE_GREATERTHAN: + return -1; + case ExpressionType::COMPARE_LESSTHANOREQUALTO: + case ExpressionType::COMPARE_GREATERTHANOREQUALTO: + return 0; + default: + throw InternalException("Unimplemented comparison type for merge join!"); + } +} + +struct BlockMergeInfo { + GlobalSortState &state; + //! The block being scanned + const idx_t block_idx; + //! The start position being read from the block + const idx_t base_idx; + //! The number of not-NULL values in the block (they are at the end) + const idx_t not_null; + //! The current offset in the block + idx_t &entry_idx; + SelectionVector result; + + BlockMergeInfo(GlobalSortState &state, idx_t block_idx, idx_t base_idx, idx_t &entry_idx, idx_t not_null) + : state(state), block_idx(block_idx), base_idx(base_idx), not_null(not_null), entry_idx(entry_idx), + result(STANDARD_VECTOR_SIZE) { + } +}; + +static void SliceSortedPayload(DataChunk &payload, BlockMergeInfo &info, const idx_t result_count, const idx_t vcount, + const idx_t left_cols = 0) { + // There should only be one sorted block if they have been sorted + D_ASSERT(info.state.sorted_blocks.size() == 1); + SBScanState read_state(info.state.buffer_manager, info.state); + read_state.sb = info.state.sorted_blocks[0].get(); + auto &sorted_data = *read_state.sb->payload_data; + + // We have to create pointers for the entire block + // because unswizzle works on ranges not selections. + read_state.SetIndices(info.block_idx, info.base_idx); + read_state.PinData(sorted_data); + const auto data_ptr = read_state.DataPtr(sorted_data); + const auto next = vcount - info.base_idx; + + // Set up a batch of pointers to scan data from + Vector addresses(LogicalType::POINTER, next); + auto data_pointers = FlatVector::GetData(addresses); + + // Set up the data pointers + data_ptr_t row_ptr = data_ptr; + const idx_t &row_width = sorted_data.layout.GetRowWidth(); + for (idx_t i = 0; i < next; ++i) { + data_pointers[i] = row_ptr; + row_ptr += row_width; + } + // Unswizzle the offsets back to pointers (if needed) + if (!sorted_data.layout.AllConstant() && info.state.external) { + RowOperations::UnswizzlePointers(sorted_data.layout, data_ptr, read_state.payload_heap_handle->Ptr(), next); + } + + // Deserialize the payload data + for (idx_t col_idx = 0; col_idx < sorted_data.layout.ColumnCount(); col_idx++) { + const auto col_offset = sorted_data.layout.GetOffsets()[col_idx]; + RowOperations::Gather(addresses, info.result, payload.data[left_cols + col_idx], + *FlatVector::IncrementalSelectionVector(), result_count, col_offset, col_idx); + } +} + +static void MergeJoinPinSortingBlock(SBScanState &scan, const idx_t block_idx) { + scan.SetIndices(block_idx, 0); + scan.PinRadix(block_idx); + + auto &sd = *scan.sb->blob_sorting_data; + if (block_idx < sd.data_blocks.size()) { + scan.PinData(sd); + } +} + +static data_ptr_t MergeJoinRadixPtr(SBScanState &scan, const idx_t entry_idx) { + scan.entry_idx = entry_idx; + return scan.RadixPtr(); +} + +static idx_t MergeJoinSimpleBlocks(PiecewiseMergeJoinState &lstate, MergeJoinGlobalState &rstate, bool *found_match, + const ExpressionType comparison) { + const auto cmp = MergeJoinComparisonValue(comparison); + + // The sort parameters should all be the same + auto &lsort = *lstate.lhs_global_state; + auto &rsort = rstate.rhs_global_sort_state; + D_ASSERT(lsort.sort_layout.all_constant == rsort.sort_layout.all_constant); + const auto all_constant = lsort.sort_layout.all_constant; + D_ASSERT(lsort.external == rsort.external); + const auto external = lsort.external; + + // There should only be one sorted block if they have been sorted + D_ASSERT(lsort.sorted_blocks.size() == 1); + SBScanState lread(lsort.buffer_manager, lsort); + lread.sb = lsort.sorted_blocks[0].get(); + + const idx_t l_block_idx = 0; + idx_t l_entry_idx = 0; + const auto lhs_not_null = lstate.lhs_count - lstate.lhs_has_null; + MergeJoinPinSortingBlock(lread, l_block_idx); + auto l_ptr = MergeJoinRadixPtr(lread, l_entry_idx); + + D_ASSERT(rsort.sorted_blocks.size() == 1); + SBScanState rread(rsort.buffer_manager, rsort); + rread.sb = rsort.sorted_blocks[0].get(); + + const auto cmp_size = lsort.sort_layout.comparison_size; + const auto entry_size = lsort.sort_layout.entry_size; + + idx_t right_base = 0; + for (idx_t r_block_idx = 0; r_block_idx < rread.sb->radix_sorting_data.size(); r_block_idx++) { + // we only care about the BIGGEST value in each of the RHS data blocks + // because we want to figure out if the LHS values are less than [or equal] to ANY value + // get the biggest value from the RHS chunk + MergeJoinPinSortingBlock(rread, r_block_idx); + + auto &rblock = rread.sb->radix_sorting_data[r_block_idx]; + const auto r_not_null = SortedBlockNotNull(right_base, rblock.count, rstate.rhs_count - rstate.rhs_has_null); + if (r_not_null == 0) { + break; + } + const auto r_entry_idx = r_not_null - 1; + right_base += rblock.count; + + auto r_ptr = MergeJoinRadixPtr(rread, r_entry_idx); + + // now we start from the current lpos value and check if we found a new value that is [<= OR <] the max RHS + // value + while (true) { + int comp_res; + if (all_constant) { + comp_res = FastMemcmp(l_ptr, r_ptr, cmp_size); + } else { + lread.entry_idx = l_entry_idx; + rread.entry_idx = r_entry_idx; + comp_res = Comparators::CompareTuple(lread, rread, l_ptr, r_ptr, lsort.sort_layout, external); + } + + if (comp_res <= cmp) { + // found a match for lpos, set it in the found_match vector + found_match[l_entry_idx] = true; + l_entry_idx++; + l_ptr += entry_size; + if (l_entry_idx >= lhs_not_null) { + // early out: we exhausted the entire LHS and they all match + return 0; + } + } else { + // we found no match: any subsequent value from the LHS we scan now will be bigger and thus also not + // match move to the next RHS chunk + break; + } + } + } + return 0; } void PhysicalPiecewiseMergeJoin::ResolveSimpleJoin(ExecutionContext &context, DataChunk &input, DataChunk &chunk, @@ -59773,37 +58862,138 @@ void PhysicalPiecewiseMergeJoin::ResolveSimpleJoin(ExecutionContext &context, Da state.ResolveJoinKeys(input); - ScalarMergeInfo left_info(state.left_orders, state.join_keys.data[0].GetType(), state.left_position); - ChunkMergeInfo right_info(gstate.right_conditions, gstate.right_orders); - // perform the actual join - MergeJoinSimple::Perform(left_info, right_info, conditions[0].comparison); + bool found_match[STANDARD_VECTOR_SIZE]; + memset(found_match, 0, sizeof(found_match)); + MergeJoinSimpleBlocks(state, gstate, found_match, conditions[0].comparison); + + // extract the sorted payload + idx_t left_position = 0; + const auto lhs_not_null = state.lhs_count - state.lhs_has_null; + BlockMergeInfo left_info(*state.lhs_global_state, 0, 0, left_position, lhs_not_null); + left_info.result.Initialize(nullptr); + + DataChunk payload; + payload.Initialize(input.GetTypes()); + SliceSortedPayload(payload, left_info, state.lhs_count, state.lhs_count); + payload.SetCardinality(state.lhs_count); - // now construct the result based ont he join result + // now construct the result based on the join result switch (join_type) { - case JoinType::MARK: - PhysicalJoin::ConstructMarkJoinResult(state.join_keys, input, chunk, right_info.found_match, gstate.has_null); + case JoinType::MARK: { + // The only part of the join keys that is actually used is the validity mask. + // Since the payload is sorted, we can just set the tail end of the validity masks to invalid. + for (auto &key : state.lhs_keys.data) { + key.Normalify(state.lhs_keys.size()); + auto &mask = FlatVector::Validity(key); + if (mask.AllValid()) { + continue; + } + mask.SetAllValid(lhs_not_null); + for (idx_t i = lhs_not_null; i < state.lhs_count; ++i) { + mask.SetInvalid(i); + } + } + // So we make a set of keys that have the validity mask set for the + PhysicalJoin::ConstructMarkJoinResult(state.lhs_keys, payload, chunk, found_match, gstate.rhs_has_null); break; + } case JoinType::SEMI: - PhysicalJoin::ConstructSemiJoinResult(input, chunk, right_info.found_match); + PhysicalJoin::ConstructSemiJoinResult(payload, chunk, found_match); break; case JoinType::ANTI: - PhysicalJoin::ConstructAntiJoinResult(input, chunk, right_info.found_match); + PhysicalJoin::ConstructAntiJoinResult(payload, chunk, found_match); break; default: throw NotImplementedException("Unimplemented join type for merge join"); } } +static idx_t MergeJoinComplexBlocks(BlockMergeInfo &l, BlockMergeInfo &r, const ExpressionType comparison) { + const auto cmp = MergeJoinComparisonValue(comparison); + + // The sort parameters should all be the same + D_ASSERT(l.state.sort_layout.all_constant == r.state.sort_layout.all_constant); + const auto all_constant = r.state.sort_layout.all_constant; + D_ASSERT(l.state.external == r.state.external); + const auto external = l.state.external; + + // There should only be one sorted block if they have been sorted + D_ASSERT(l.state.sorted_blocks.size() == 1); + SBScanState lread(l.state.buffer_manager, l.state); + lread.sb = l.state.sorted_blocks[0].get(); + D_ASSERT(lread.sb->radix_sorting_data.size() == 1); + MergeJoinPinSortingBlock(lread, l.block_idx); + auto l_start = MergeJoinRadixPtr(lread, 0); + auto l_ptr = MergeJoinRadixPtr(lread, l.entry_idx); + + D_ASSERT(r.state.sorted_blocks.size() == 1); + SBScanState rread(r.state.buffer_manager, r.state); + rread.sb = r.state.sorted_blocks[0].get(); + + if (r.entry_idx >= r.not_null) { + return 0; + } + + MergeJoinPinSortingBlock(rread, r.block_idx); + auto r_ptr = MergeJoinRadixPtr(rread, r.entry_idx); + + const auto cmp_size = l.state.sort_layout.comparison_size; + const auto entry_size = l.state.sort_layout.entry_size; + + idx_t result_count = 0; + while (true) { + if (l.entry_idx < l.not_null) { + int comp_res; + if (all_constant) { + comp_res = FastMemcmp(l_ptr, r_ptr, cmp_size); + } else { + lread.entry_idx = l.entry_idx; + rread.entry_idx = r.entry_idx; + comp_res = Comparators::CompareTuple(lread, rread, l_ptr, r_ptr, l.state.sort_layout, external); + } + + if (comp_res <= cmp) { + // left side smaller: found match + l.result.set_index(result_count, sel_t(l.entry_idx - l.base_idx)); + r.result.set_index(result_count, sel_t(r.entry_idx - r.base_idx)); + result_count++; + // move left side forward + l.entry_idx++; + l_ptr += entry_size; + if (result_count == STANDARD_VECTOR_SIZE) { + // out of space! + break; + } + continue; + } + } + // right side smaller or equal, or left side exhausted: move + // right pointer forward reset left side to start + r.entry_idx++; + if (r.entry_idx >= r.not_null) { + break; + } + r_ptr += entry_size; + + l_ptr = l_start; + l.entry_idx = 0; + } + + return result_count; +} + OperatorResultType PhysicalPiecewiseMergeJoin::ResolveComplexJoin(ExecutionContext &context, DataChunk &input, DataChunk &chunk, OperatorState &state_p) const { auto &state = (PiecewiseMergeJoinState &)state_p; auto &gstate = (MergeJoinGlobalState &)*sink_state; + auto &rsorted = *gstate.rhs_global_sort_state.sorted_blocks[0]; do { if (state.first_fetch) { state.ResolveJoinKeys(input); state.right_chunk_index = 0; + state.right_base = 0; state.left_position = 0; state.right_position = 0; state.first_fetch = false; @@ -59813,47 +59003,53 @@ OperatorResultType PhysicalPiecewiseMergeJoin::ResolveComplexJoin(ExecutionConte if (IsLeftOuterJoin(join_type)) { // left join: before we move to the next chunk, see if we need to output any vectors that didn't // have a match found - PhysicalJoin::ConstructLeftJoinResult(input, chunk, state.left_found_match.get()); - memset(state.left_found_match.get(), 0, sizeof(bool) * STANDARD_VECTOR_SIZE); + PhysicalJoin::ConstructLeftJoinResult(input, chunk, state.lhs_found_match.get()); + memset(state.lhs_found_match.get(), 0, sizeof(bool) * STANDARD_VECTOR_SIZE); } state.first_fetch = true; state.finished = false; return OperatorResultType::NEED_MORE_INPUT; } - auto &right_chunk = gstate.right_chunks.GetChunk(state.right_chunk_index); - auto &right_condition_chunk = gstate.right_conditions.GetChunk(state.right_chunk_index); - auto &right_orders = gstate.right_orders[state.right_chunk_index]; + const auto lhs_not_null = state.lhs_count - state.lhs_has_null; + BlockMergeInfo left_info(*state.lhs_global_state, 0, 0, state.left_position, lhs_not_null); - ScalarMergeInfo left_info(state.left_orders, state.join_keys.data[0].GetType(), state.left_position); - ScalarMergeInfo right_info(right_orders, right_condition_chunk.data[0].GetType(), state.right_position); + const auto &rblock = rsorted.radix_sorting_data[state.right_chunk_index]; + const auto rhs_not_null = + SortedBlockNotNull(state.right_base, rblock.count, gstate.rhs_count - gstate.rhs_has_null); + BlockMergeInfo right_info(gstate.rhs_global_sort_state, state.right_chunk_index, state.right_position, + state.right_position, rhs_not_null); - idx_t result_count = MergeJoinComplex::Perform(left_info, right_info, conditions[0].comparison); + idx_t result_count = MergeJoinComplexBlocks(left_info, right_info, conditions[0].comparison); if (result_count == 0) { // exhausted this chunk on the right side // move to the next right chunk state.left_position = 0; state.right_position = 0; + state.right_base += rsorted.radix_sorting_data[state.right_chunk_index].count; state.right_chunk_index++; - if (state.right_chunk_index >= gstate.right_chunks.ChunkCount()) { + if (state.right_chunk_index >= rsorted.radix_sorting_data.size()) { state.finished = true; } } else { // found matches: mark the found matches if required - if (state.left_found_match) { + if (state.lhs_found_match) { for (idx_t i = 0; i < result_count; i++) { - state.left_found_match[left_info.result.get_index(i)] = true; + state.lhs_found_match[left_info.result[i]] = true; } } - if (gstate.right_found_match) { - idx_t base_index = state.right_chunk_index * STANDARD_VECTOR_SIZE; + if (gstate.rhs_found_match) { + // Absolute position of the block + start position inside that block + const idx_t base_index = state.right_base + right_info.base_idx; for (idx_t i = 0; i < result_count; i++) { - gstate.right_found_match[base_index + right_info.result.get_index(i)] = true; + gstate.rhs_found_match[base_index + right_info.result[i]] = true; } } // found matches: output them - chunk.Slice(input, left_info.result, result_count); - chunk.Slice(right_chunk, right_info.result, result_count, input.ColumnCount()); + SliceSortedPayload(chunk, left_info, result_count, input.size()); + SliceSortedPayload(chunk, right_info, result_count, right_info.entry_idx + 1, input.ColumnCount()); + chunk.SetCardinality(result_count); + chunk.Verify(); } } while (chunk.size() == 0); return OperatorResultType::HAVE_MORE_OUTPUT; @@ -59863,10 +59059,10 @@ OperatorResultType PhysicalPiecewiseMergeJoin::Execute(ExecutionContext &context OperatorState &state) const { auto &gstate = (MergeJoinGlobalState &)*sink_state; - if (gstate.right_chunks.Count() == 0) { + if (gstate.Count() == 0) { // empty RHS if (!EmptyResultIfRHSIsEmpty()) { - ConstructEmptyJoinResult(join_type, gstate.has_null, input, chunk); + ConstructEmptyJoinResult(join_type, gstate.rhs_has_null, input, chunk); return OperatorResultType::NEED_MORE_INPUT; } else { return OperatorResultType::FINISHED; @@ -59890,169 +59086,6 @@ OperatorResultType PhysicalPiecewiseMergeJoin::Execute(ExecutionContext &context } } -//===--------------------------------------------------------------------===// -// OrderVector -//===--------------------------------------------------------------------===// -template -static sel_t TemplatedQuicksortInitial(T *data, const SelectionVector &sel, const SelectionVector ¬_null_sel, - idx_t count, SelectionVector &result) { - // select pivot - auto pivot_idx = not_null_sel.get_index(0); - auto dpivot_idx = sel.get_index(pivot_idx); - sel_t low = 0, high = count - 1; - // now insert elements - for (idx_t i = 1; i < count; i++) { - auto idx = not_null_sel.get_index(i); - auto didx = sel.get_index(idx); - if (OP::Operation(data[didx], data[dpivot_idx])) { - result.set_index(low++, idx); - } else { - result.set_index(high--, idx); - } - } - D_ASSERT(low == high); - result.set_index(low, pivot_idx); - return low; -} - -struct QuickSortPivot { - QuickSortPivot(sel_t left_p, sel_t right_p) : left(left_p), right(right_p) { - } - - sel_t left; - sel_t right; -}; - -template -static void TemplatedQuicksortRefine(T *data, const SelectionVector &sel, idx_t count, SelectionVector &result, - sel_t left, sel_t right, vector &pivots) { - if (left >= right) { - return; - } - - sel_t middle = left + (right - left) / 2; - sel_t dpivot_idx = sel.get_index(result.get_index(middle)); - - // move the mid point value to the front. - sel_t i = left + 1; - sel_t j = right; - - result.swap(middle, left); - while (i <= j) { - while (i <= j && (OP::Operation(data[sel.get_index(result.get_index(i))], data[dpivot_idx]))) { - i++; - } - - while (i <= j && !OP::Operation(data[sel.get_index(result.get_index(j))], data[dpivot_idx])) { - j--; - } - - if (i < j) { - result.swap(i, j); - } - } - result.swap(i - 1, left); - sel_t part = i - 1; - - if (part > 0) { - pivots.emplace_back(left, part - 1); - } - if (part + 1 < right) { - pivots.emplace_back(part + 1, right); - } -} - -template -void TemplatedQuicksort(T *__restrict data, const SelectionVector &sel, const SelectionVector ¬_null_sel, - idx_t count, SelectionVector &result) { - auto part = TemplatedQuicksortInitial(data, sel, not_null_sel, count, result); - if (part > count) { - return; - } - vector pivots; - pivots.emplace_back(0, part); - pivots.emplace_back(part + 1, count - 1); - for (idx_t i = 0; i < pivots.size(); i++) { - auto pivot = pivots[i]; - TemplatedQuicksortRefine(data, sel, count, result, pivot.left, pivot.right, pivots); - } -} - -template -static void TemplatedQuicksort(VectorData &vdata, const SelectionVector ¬_null_sel, idx_t not_null_count, - SelectionVector &result) { - if (not_null_count == 0) { - return; - } - TemplatedQuicksort((T *)vdata.data, *vdata.sel, not_null_sel, not_null_count, result); -} - -void OrderVector(Vector &vector, idx_t count, MergeOrder &order) { - if (count == 0) { - order.count = 0; - return; - } - vector.Orrify(count, order.vdata); - auto &vdata = order.vdata; - - // first filter out all the non-null values - SelectionVector not_null(STANDARD_VECTOR_SIZE); - idx_t not_null_count = 0; - for (idx_t i = 0; i < count; i++) { - auto idx = vdata.sel->get_index(i); - if (vdata.validity.RowIsValid(idx)) { - not_null.set_index(not_null_count++, i); - } - } - - order.count = not_null_count; - order.order.Initialize(STANDARD_VECTOR_SIZE); - switch (vector.GetType().InternalType()) { - case PhysicalType::BOOL: - case PhysicalType::INT8: - TemplatedQuicksort(vdata, not_null, not_null_count, order.order); - break; - case PhysicalType::INT16: - TemplatedQuicksort(vdata, not_null, not_null_count, order.order); - break; - case PhysicalType::INT32: - TemplatedQuicksort(vdata, not_null, not_null_count, order.order); - break; - case PhysicalType::INT64: - TemplatedQuicksort(vdata, not_null, not_null_count, order.order); - break; - case PhysicalType::UINT8: - TemplatedQuicksort(vdata, not_null, not_null_count, order.order); - break; - case PhysicalType::UINT16: - TemplatedQuicksort(vdata, not_null, not_null_count, order.order); - break; - case PhysicalType::UINT32: - TemplatedQuicksort(vdata, not_null, not_null_count, order.order); - break; - case PhysicalType::UINT64: - TemplatedQuicksort(vdata, not_null, not_null_count, order.order); - break; - case PhysicalType::INT128: - TemplatedQuicksort(vdata, not_null, not_null_count, order.order); - break; - case PhysicalType::FLOAT: - TemplatedQuicksort(vdata, not_null, not_null_count, order.order); - break; - case PhysicalType::DOUBLE: - TemplatedQuicksort(vdata, not_null, not_null_count, order.order); - break; - case PhysicalType::INTERVAL: - TemplatedQuicksort(vdata, not_null, not_null_count, order.order); - break; - case PhysicalType::VARCHAR: - TemplatedQuicksort(vdata, not_null, not_null_count, order.order); - break; - default: - throw NotImplementedException("Unimplemented type for sort"); - } -} - //===--------------------------------------------------------------------===// // Source //===--------------------------------------------------------------------===// @@ -60063,12 +59096,13 @@ class PiecewiseJoinScanState : public GlobalSourceState { mutex lock; const PhysicalPiecewiseMergeJoin &op; + unique_ptr scanner; idx_t right_outer_position; public: idx_t MaxThreads() override { auto &sink = (MergeJoinGlobalState &)*op.sink_state; - return sink.right_chunks.Count() / (STANDARD_VECTOR_SIZE * 10); + return sink.Count() / (STANDARD_VECTOR_SIZE * idx_t(10)); } }; @@ -60076,17 +59110,63 @@ unique_ptr PhysicalPiecewiseMergeJoin::GetGlobalSourceState(C return make_unique(*this); } -void PhysicalPiecewiseMergeJoin::GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate, +void PhysicalPiecewiseMergeJoin::GetData(ExecutionContext &context, DataChunk &result, GlobalSourceState &gstate, LocalSourceState &lstate) const { D_ASSERT(IsRightOuterJoin(join_type)); // check if we need to scan any unmatched tuples from the RHS for the full/right outer join auto &sink = (MergeJoinGlobalState &)*sink_state; auto &state = (PiecewiseJoinScanState &)gstate; + lock_guard l(state.lock); + if (!state.scanner) { + // Initialize scanner (if not yet initialized) + auto &sort_state = sink.rhs_global_sort_state; + if (sort_state.sorted_blocks.empty()) { + return; + } + state.scanner = make_unique(*sort_state.sorted_blocks[0]->payload_data, sort_state); + } + // if the LHS is exhausted in a FULL/RIGHT OUTER JOIN, we scan the found_match for any chunks we // still need to output - lock_guard l(state.lock); - ConstructFullOuterJoinResult(sink.right_found_match.get(), sink.right_chunks, chunk, state.right_outer_position); + const auto found_match = sink.rhs_found_match.get(); + + // ConstructFullOuterJoinResult(sink.rhs_found_match.get(), sink.right_chunks, chunk, state.right_outer_position); + DataChunk rhs_chunk; + rhs_chunk.Initialize(children[1]->types); + SelectionVector rsel(STANDARD_VECTOR_SIZE); + for (;;) { + // Read the next sorted chunk + state.scanner->Scan(rhs_chunk); + + const auto count = rhs_chunk.size(); + if (count == 0) { + return; + } + + idx_t result_count = 0; + // figure out which tuples didn't find a match in the RHS + for (idx_t i = 0; i < count; i++) { + if (!found_match[state.right_outer_position + i]) { + rsel.set_index(result_count++, i); + } + } + state.right_outer_position += count; + + if (result_count > 0) { + // if there were any tuples that didn't find a match, output them + const idx_t left_column_count = result.ColumnCount() - rhs_chunk.ColumnCount(); + for (idx_t col_idx = 0; col_idx < left_column_count; ++col_idx) { + result.data[col_idx].SetVectorType(VectorType::CONSTANT_VECTOR); + ConstantVector::SetNull(result.data[col_idx], true); + } + for (idx_t col_idx = 0; col_idx < rhs_chunk.ColumnCount(); ++col_idx) { + result.data[left_column_count + col_idx].Slice(rhs_chunk.data[col_idx], rsel, result_count); + } + result.SetCardinality(result_count); + return; + } + } } } // namespace duckdb @@ -60197,7 +59277,7 @@ unique_ptr PhysicalOrder::GetGlobalSinkState(ClientContext &con payload_layout.Initialize(types); auto state = make_unique(BufferManager::GetBufferManager(context), *this, payload_layout); // Set external (can be force with the PRAGMA) - state->global_sort_state.external = context.force_external; + state->global_sort_state.external = ClientConfig::GetConfig(context).force_external; // Memory usage per thread should scale with max mem / num threads // We take 1/4th of this, to be conservative idx_t max_memory = BufferManager::GetBufferManager(context).GetMaxMemory(); @@ -60258,12 +59338,13 @@ class PhysicalOrderMergeTask : public ExecutorTask { : ExecutorTask(context), event(move(event_p)), context(context), state(state) { } - void ExecuteTask() override { + TaskExecutionResult ExecuteTask(TaskExecutionMode mode) override { // Initialize merge sorted and iterate until done auto &global_sort_state = state.global_sort_state; MergeSorter merge_sorter(global_sort_state, BufferManager::GetBufferManager(context)); merge_sorter.PerformInMergeRound(); event->FinishTask(); + return TaskExecutionResult::TASK_FINISHED; } private: @@ -60340,7 +59421,7 @@ void PhysicalOrder::ScheduleMergeTasks(Pipeline &pipeline, Event &event, OrderGl class PhysicalOrderOperatorState : public GlobalSourceState { public: //! Payload scanner - unique_ptr scanner; + unique_ptr scanner; }; unique_ptr PhysicalOrder::GetGlobalSourceState(ClientContext &context) const { @@ -60359,7 +59440,7 @@ void PhysicalOrder::GetData(ExecutionContext &context, DataChunk &chunk, GlobalS return; } state.scanner = - make_unique(*global_sort_state.sorted_blocks[0]->payload_data, global_sort_state); + make_unique(*global_sort_state.sorted_blocks[0]->payload_data, global_sort_state); } // Scan the next data chunk @@ -60459,7 +59540,7 @@ PhysicalTopN::PhysicalTopN(vector types, vector o class TopNHeap; struct TopNScanState { - unique_ptr scanner; + unique_ptr scanner; idx_t pos; bool exclude_offset; }; @@ -60589,7 +59670,7 @@ void TopNSortState::InitializeScan(TopNScanState &state, bool exclude_offset) { state.scanner = nullptr; } else { D_ASSERT(global_state->sorted_blocks.size() == 1); - state.scanner = make_unique(*global_state->sorted_blocks[0]->payload_data, *global_state); + state.scanner = make_unique(*global_state->sorted_blocks[0]->payload_data, *global_state); } state.pos = 0; state.exclude_offset = exclude_offset && heap.offset > 0; @@ -60793,6 +59874,7 @@ bool TopNHeap::CheckBoundaryValues(DataChunk &sort_chunk, DataChunk &payload) { idx_t false_count = remaining_count - true_count; if (false_count > 0) { // check what we should continue to check + compare_chunk.data[i].Slice(sort_chunk.data[i], false_sel, false_count); remaining_count = VectorOperations::NotDistinctFrom(compare_chunk.data[i], boundary_values.data[i], &false_sel, false_count, &new_remaining_sel, nullptr); if (is_last) { @@ -61029,7 +60111,7 @@ struct StrfTimeFormat : public StrTimeFormat { void FormatString(date_t date, int32_t data[7], char *target); void FormatString(date_t date, dtime_t time, char *target); - static string Format(timestamp_t timestamp, const string &format); + DUCKDB_API static string Format(timestamp_t timestamp, const string &format); protected: //! The variable-length specifiers. To determine total string size, these need to be checked. @@ -61057,15 +60139,20 @@ struct StrpTimeFormat : public StrTimeFormat { struct ParseResult { int32_t data[7]; string error_message; - idx_t error_position = INVALID_INDEX; + idx_t error_position = DConstants::INVALID_INDEX; date_t ToDate(); timestamp_t ToTimestamp(); string FormatError(string_t input, const string &format_specifier); }; + +public: //! The full format specifier, for error messages string format_specifier; +public: + DUCKDB_API static ParseResult Parse(const string &format, const string &text); + bool Parse(string_t str, ParseResult &result); bool TryParseDate(string_t str, date_t &result, string &error_message); @@ -61093,6 +60180,7 @@ struct StrpTimeFormat : public StrTimeFormat { namespace duckdb { struct CopyInfo; +struct CSVFileHandle; struct FileHandle; struct StrpTimeFormat; @@ -61129,8 +60217,8 @@ struct BufferedCSVReaderOptions { //! The file path of the CSV file to read string file_path; //! Whether file is compressed or not, and if so which compression type - //! ("infer" (default; infer from file extention), "gzip", "none") - string compression = "infer"; + //! AUTO_DETECT (default; infer from file extension) + FileCompressionType compression = FileCompressionType::AUTO_DETECT; //! Whether or not to automatically detect dialect and datatypes bool auto_detect = false; //! Whether or not a delimiter was defined by the user @@ -61167,20 +60255,17 @@ struct BufferedCSVReaderOptions { idx_t buffer_size = STANDARD_VECTOR_SIZE * 100; //! Consider all columns to be of type varchar bool all_varchar = false; + //! Maximum CSV line size: specified because if we reach this amount, we likely have wrong delimiters (default: 2MB) + idx_t maximum_line_size = 2097152; + //! The date format to use (if any is specified) std::map date_format = {{LogicalTypeId::DATE, {}}, {LogicalTypeId::TIMESTAMP, {}}}; //! Whether or not a type format is specified std::map has_format = {{LogicalTypeId::DATE, false}, {LogicalTypeId::TIMESTAMP, false}}; - std::string 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) + - (has_header ? "" : (auto_detect ? " (auto detected)" : "' (default)")) + - ", SAMPLE_SIZE=" + std::to_string(sample_chunk_size * sample_chunks) + - ", ALL_VARCHAR=" + std::to_string(all_varchar); - } + void SetDelimiter(const string &delimiter); + + std::string ToString() const; }; enum class ParserMode : uint8_t { PARSING = 0, SNIFFING_DIALECT = 1, SNIFFING_DATATYPES = 2, PARSING_HEADER = 3 }; @@ -61189,8 +60274,6 @@ enum class ParserMode : uint8_t { PARSING = 0, SNIFFING_DIALECT = 1, SNIFFING_DA class BufferedCSVReader { //! Initial buffer read size; can be extended for long lines static constexpr idx_t INITIAL_BUFFER_SIZE = 16384; - //! Maximum CSV line size: specified because if we reach this amount, we likely have the wrong delimiters - static constexpr idx_t MAXIMUM_CSV_LINE_SIZE = 1048576; ParserMode mode; public: @@ -61199,16 +60282,14 @@ class BufferedCSVReader { BufferedCSVReader(FileSystem &fs, FileOpener *opener, BufferedCSVReaderOptions options, const vector &requested_types = vector()); + ~BufferedCSVReader(); FileSystem &fs; FileOpener *opener; BufferedCSVReaderOptions options; vector sql_types; vector col_names; - unique_ptr file_handle; - bool plain_file_source = false; - idx_t file_size = 0; - FileCompressionType compression = FileCompressionType::UNCOMPRESSED; + unique_ptr file_handle; unique_ptr buffer; idx_t buffer_size; @@ -61240,6 +60321,8 @@ class BufferedCSVReader { //! Extract a single DataChunk from the CSV file and stores it in insert_chunk void ParseCSV(DataChunk &insert_chunk); + idx_t GetFileSize(); + private: //! Initialize Parser void Initialize(const vector &requested_types); @@ -61286,7 +60369,7 @@ class BufferedCSVReader { //! Reads a new buffer from the CSV file if the current one has been exhausted bool ReadBuffer(idx_t &start); - unique_ptr OpenCSV(const BufferedCSVReaderOptions &options); + unique_ptr OpenCSV(const BufferedCSVReaderOptions &options); //! First phase of auto detection: detect CSV dialect (i.e. delimiter, quote rules, etc) void DetectDialect(const vector &requested_types, BufferedCSVReaderOptions &original_options, @@ -61333,14 +60416,151 @@ class BufferedCSVReader { namespace duckdb { +struct CSVFileHandle { +public: + explicit CSVFileHandle(unique_ptr file_handle_p) : file_handle(move(file_handle_p)) { + can_seek = file_handle->CanSeek(); + plain_file_source = file_handle->OnDiskFile() && can_seek; + file_size = file_handle->GetFileSize(); + } + + bool CanSeek() { + return can_seek; + } + void Seek(idx_t position) { + if (!can_seek) { + throw InternalException("Cannot seek in this file"); + } + file_handle->Seek(position); + } + idx_t SeekPosition() { + if (!can_seek) { + throw InternalException("Cannot seek in this file"); + } + return file_handle->SeekPosition(); + } + void Reset() { + if (plain_file_source) { + file_handle->Reset(); + } else { + if (!reset_enabled) { + throw InternalException("Reset called but reset is not enabled for this CSV Handle"); + } + read_position = 0; + } + } + bool PlainFileSource() { + return plain_file_source; + } + + idx_t FileSize() { + return file_size; + } + + idx_t Read(void *buffer, idx_t nr_bytes) { + if (!plain_file_source) { + // not a plain file source: we need to do some bookkeeping around the reset functionality + idx_t result_offset = 0; + if (read_position < buffer_size) { + // we need to read from our cached buffer + auto buffer_read_count = MinValue(nr_bytes, buffer_size - read_position); + memcpy(buffer, cached_buffer.get() + read_position, buffer_read_count); + result_offset += buffer_read_count; + read_position += buffer_read_count; + if (result_offset == nr_bytes) { + return nr_bytes; + } + } else if (!reset_enabled && cached_buffer) { + // reset is disabled but we still have cached data + // we can remove any cached data + cached_buffer.reset(); + buffer_size = 0; + buffer_capacity = 0; + read_position = 0; + } + // we have data left to read from the file + // read directly into the buffer + auto bytes_read = file_handle->Read((char *)buffer + result_offset, nr_bytes - result_offset); + read_position += bytes_read; + if (reset_enabled) { + // if reset caching is enabled, we need to cache the bytes that we have read + if (buffer_size + bytes_read >= buffer_capacity) { + // no space; first enlarge the buffer + buffer_capacity = MaxValue(NextPowerOfTwo(buffer_size + bytes_read), buffer_capacity * 2); + + auto new_buffer = unique_ptr(new data_t[buffer_capacity]); + if (buffer_size > 0) { + memcpy(new_buffer.get(), cached_buffer.get(), buffer_size); + } + cached_buffer = move(new_buffer); + } + memcpy(cached_buffer.get() + buffer_size, (char *)buffer + result_offset, bytes_read); + buffer_size += bytes_read; + } + + return result_offset + bytes_read; + } else { + return file_handle->Read(buffer, nr_bytes); + } + } + + string ReadLine() { + string result; + char buffer[1]; + while (true) { + idx_t tuples_read = Read(buffer, 1); + if (tuples_read == 0 || buffer[0] == '\n') { + return result; + } + if (buffer[0] != '\r') { + result += buffer[0]; + } + } + } + + void DisableReset() { + this->reset_enabled = false; + } + +private: + unique_ptr file_handle; + bool reset_enabled = true; + bool can_seek = false; + bool plain_file_source = false; + idx_t file_size = 0; + // reset support + unique_ptr cached_buffer; + idx_t read_position = 0; + idx_t buffer_size = 0; + idx_t buffer_capacity = 0; +}; + +void BufferedCSVReaderOptions::SetDelimiter(const string &input) { + this->delimiter = StringUtil::Replace(input, "\\t", "\t"); + this->has_delimiter = true; + if (input.empty()) { + throw BinderException("DELIM or SEP must not be empty"); + } +} + +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) + + (has_header ? "" : (auto_detect ? " (auto detected)" : "' (default)")) + + ", SAMPLE_SIZE=" + std::to_string(sample_chunk_size * sample_chunks) + + ", ALL_VARCHAR=" + std::to_string(all_varchar); +} + static string GetLineNumberStr(idx_t linenr, bool linenr_estimated) { string estimated = (linenr_estimated ? string(" (estimated)") : string("")); return to_string(linenr + 1) + estimated; } -static bool StartsWithNumericDate(string &separator, const string_t &value) { - auto begin = value.GetDataUnsafe(); - auto end = begin + value.GetSize(); +static bool StartsWithNumericDate(string &separator, const string &value) { + auto begin = value.c_str(); + auto end = begin + value.size(); // StrpTimeFormat::Parse will skip whitespace, so we can too auto field1 = std::find_if_not(begin, end, StringUtil::CharacterIsSpace); @@ -61447,6 +60667,13 @@ BufferedCSVReader::BufferedCSVReader(ClientContext &context, BufferedCSVReaderOp requested_types) { } +BufferedCSVReader::~BufferedCSVReader() { +} + +idx_t BufferedCSVReader::GetFileSize() { + return file_handle ? file_handle->FileSize() : 0; +} + void BufferedCSVReader::Initialize(const vector &requested_types) { PrepareComplexParser(); if (options.auto_detect) { @@ -61463,6 +60690,9 @@ void BufferedCSVReader::Initialize(const vector &requested_types) { SkipRowsAndReadHeader(options.skip_rows, options.header); } InitParseChunk(sql_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(); } void BufferedCSVReader::PrepareComplexParser() { @@ -61471,19 +60701,10 @@ void BufferedCSVReader::PrepareComplexParser() { quote_search = TextSearchShiftArray(options.quote); } -unique_ptr BufferedCSVReader::OpenCSV(const BufferedCSVReaderOptions &options) { - this->compression = FileCompressionType::UNCOMPRESSED; - if (options.compression == "infer" || options.compression == "auto") { - this->compression = FileCompressionType::AUTO_DETECT; - } else if (options.compression == "gzip") { - this->compression = FileCompressionType::GZIP; - } - - auto result = fs.OpenFile(options.file_path.c_str(), FileFlags::FILE_FLAGS_READ, FileLockType::NO_LOCK, - this->compression, this->opener); - plain_file_source = result->OnDiskFile() && result->CanSeek(); - file_size = result->GetFileSize(); - return result; +unique_ptr BufferedCSVReader::OpenCSV(const BufferedCSVReaderOptions &options) { + auto file_handle = fs.OpenFile(options.file_path.c_str(), FileFlags::FILE_FLAGS_READ, FileLockType::NO_LOCK, + options.compression, this->opener); + return make_unique(move(file_handle)); } // Helper function to generate column names @@ -61617,11 +60838,11 @@ void BufferedCSVReader::InitParseChunk(idx_t num_cols) { void BufferedCSVReader::JumpToBeginning(idx_t skip_rows = 0, bool skip_header = false) { ResetBuffer(); ResetStream(); - SkipRowsAndReadHeader(skip_rows, skip_header); sample_chunk_idx = 0; bytes_in_chunk = 0; end_of_file_reached = false; bom_checked = false; + SkipRowsAndReadHeader(skip_rows, skip_header); } void BufferedCSVReader::SkipRowsAndReadHeader(idx_t skip_rows, bool skip_header) { @@ -61649,7 +60870,7 @@ bool BufferedCSVReader::JumpToNextSample() { // assess if it makes sense to jump, based on size of the first chunk relative to size of the entire file if (sample_chunk_idx == 0) { idx_t bytes_first_chunk = bytes_in_chunk; - double chunks_fit = (file_size / (double)bytes_first_chunk); + double chunks_fit = (file_handle->FileSize() / (double)bytes_first_chunk); jumping_samples = chunks_fit >= options.sample_chunks; // jump back to the beginning @@ -61664,7 +60885,7 @@ bool BufferedCSVReader::JumpToNextSample() { // if we deal with any other sources than plaintext files, jumping_samples can be tricky. In that case // we just read x continuous chunks from the stream TODO: make jumps possible for zipfiles. - if (!plain_file_source || !jumping_samples) { + if (!file_handle->PlainFileSource() || !jumping_samples) { sample_chunk_idx++; return true; } @@ -61674,13 +60895,13 @@ bool BufferedCSVReader::JumpToNextSample() { bytes_per_line_avg = ((bytes_per_line_avg * (sample_chunk_idx)) + bytes_per_line) / (sample_chunk_idx + 1); // if none of the previous conditions were met, we can jump - idx_t partition_size = (idx_t)round(file_size / (double)options.sample_chunks); + idx_t partition_size = (idx_t)round(file_handle->FileSize() / (double)options.sample_chunks); // calculate offset to end of the current partition int64_t offset = partition_size - bytes_in_chunk - remaining_bytes_in_buffer; auto current_pos = file_handle->SeekPosition(); - if (current_pos + offset < file_size) { + if (current_pos + offset < file_handle->FileSize()) { // set position in stream and clear failure bits file_handle->Seek(current_pos + offset); @@ -61691,10 +60912,10 @@ bool BufferedCSVReader::JumpToNextSample() { // seek backwards from the end in last chunk and hope to catch the end of the file // TODO: actually it would be good to make sure that the end of file is being reached, because // messy end-lines are quite common. For this case, however, we first need a skip_end detection anyways. - file_handle->Seek(file_size - bytes_in_chunk); + file_handle->Seek(file_handle->FileSize() - bytes_in_chunk); // estimate linenr - linenr = (idx_t)round((file_size - bytes_in_chunk) / bytes_per_line_avg); + linenr = (idx_t)round((file_handle->FileSize() - bytes_in_chunk) / bytes_per_line_avg); linenr_estimated = true; } @@ -61722,12 +60943,13 @@ bool BufferedCSVReader::TryCastValue(const Value &value, const LogicalType &sql_ if (options.has_format[LogicalTypeId::DATE] && sql_type.id() == LogicalTypeId::DATE) { date_t result; string error_message; - return options.date_format[LogicalTypeId::DATE].TryParseDate(string_t(value.str_value), result, error_message); + return options.date_format[LogicalTypeId::DATE].TryParseDate(string_t(StringValue::Get(value)), result, + error_message); } else if (options.has_format[LogicalTypeId::TIMESTAMP] && sql_type.id() == LogicalTypeId::TIMESTAMP) { timestamp_t result; string error_message; - return options.date_format[LogicalTypeId::TIMESTAMP].TryParseTimestamp(string_t(value.str_value), result, - error_message); + return options.date_format[LogicalTypeId::TIMESTAMP].TryParseTimestamp(string_t(StringValue::Get(value)), + result, error_message); } else { Value new_value; string error_message; @@ -61848,6 +61070,7 @@ void BufferedCSVReader::DetectDialect(const vector &requested_types JumpToBeginning(original_options.skip_rows); sniffed_column_counts.clear(); + if (!TryParseCSV(ParserMode::SNIFFING_DIALECT)) { continue; } @@ -61962,7 +61185,7 @@ void BufferedCSVReader::DetectCandidateTypes(const vector &type_can // try formatting for date types if the user did not specify one and it starts with numeric values. string separator; if (has_format_candidates.count(sql_type.id()) && !original_options.has_format[sql_type.id()] && - StartsWithNumericDate(separator, dummy_val.str_value)) { + StartsWithNumericDate(separator, StringValue::Get(dummy_val))) { // generate date format candidates the first time through auto &type_format_candidates = format_candidates[sql_type.id()]; const auto had_format_candidates = has_format_candidates[sql_type.id()]; @@ -61991,7 +61214,7 @@ void BufferedCSVReader::DetectCandidateTypes(const vector &type_can while (!type_format_candidates.empty()) { // avoid using exceptions for flow control... auto ¤t_format = options.date_format[sql_type.id()]; - if (current_format.Parse(dummy_val.str_value, result)) { + if (current_format.Parse(StringValue::Get(dummy_val), result)) { break; } // doesn't work - move to the next one @@ -62078,7 +61301,7 @@ void BufferedCSVReader::DetectHeader(const vector> &best_sql first_row_nulls = true; for (idx_t col = 0; col < best_sql_types_candidates.size(); col++) { auto dummy_val = best_header_row.GetValue(col, 0); - if (!dummy_val.is_null) { + if (!dummy_val.IsNull()) { first_row_nulls = false; } @@ -62092,14 +61315,14 @@ void BufferedCSVReader::DetectHeader(const vector> &best_sql // update parser info, and read, generate & set col_names based on previous findings if (((!first_row_consistent || first_row_nulls) && !options.has_header) || (options.has_header && options.header)) { options.header = true; - unordered_map name_collision_count; + case_insensitive_map_t name_collision_count; // get header names from CSV for (idx_t col = 0; col < options.num_cols; col++) { const auto &val = best_header_row.GetValue(col, 0); string col_name = val.ToString(); // generate name if field is empty - if (col_name.empty() || val.is_null) { + if (col_name.empty() || val.IsNull()) { col_name = GenerateColumnName(options.num_cols, col); } @@ -62123,9 +61346,8 @@ void BufferedCSVReader::DetectHeader(const vector> &best_sql } else { options.header = false; - idx_t total_columns = parse_chunk.ColumnCount(); - for (idx_t col = 0; col < total_columns; col++) { - string column_name = GenerateColumnName(total_columns, col); + for (idx_t col = 0; col < options.num_cols; col++) { + string column_name = GenerateColumnName(options.num_cols, col); col_names.push_back(column_name); } } @@ -62146,7 +61368,7 @@ vector BufferedCSVReader::RefineTypeDetection(const vector BufferedCSVReader::SniffCSV(const vector &reque // ####### // ### header detection // ####### + options.num_cols = best_num_cols; DetectHeader(best_sql_types_candidates, best_header_row); // ####### @@ -62404,7 +61627,7 @@ add_row : { } while (ReadBuffer(start)); // still in quoted state at the end of the file, error: error_message = StringUtil::Format("Error in file \"%s\" on line %s: unterminated quotes. (%s)", options.file_path, - GetLineNumberStr(linenr, linenr_estimated).c_str(), options.toString()); + GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString()); return false; unquote: /* state: unquote */ @@ -62434,7 +61657,7 @@ add_row : { error_message = StringUtil::Format( "Error in file \"%s\" on line %s: quote should be followed by end of value, end " "of row or another quote. (%s)", - options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.toString()); + options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString()); return false; } if (delimiter_pos == options.delimiter.size()) { @@ -62451,7 +61674,7 @@ add_row : { } while (ReadBuffer(start)); error_message = StringUtil::Format( "Error in file \"%s\" on line %s: quote should be followed by end of value, end of row or another quote. (%s)", - options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.toString()); + options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString()); return false; handle_escape: escape_pos = 0; @@ -62466,7 +61689,7 @@ add_row : { if (count > escape_pos && count > quote_pos) { error_message = StringUtil::Format( "Error in file \"%s\" on line %s: neither QUOTE nor ESCAPE is proceeded by ESCAPE. (%s)", - options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.toString()); + options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString()); return false; } if (quote_pos == options.quote.size() || escape_pos == options.escape.size()) { @@ -62477,7 +61700,7 @@ add_row : { } while (ReadBuffer(start)); error_message = StringUtil::Format("Error in file \"%s\" on line %s: neither QUOTE nor ESCAPE is proceeded by ESCAPE. (%s)", - options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.toString()); + options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString()); return false; carriage_return: /* state: carriage_return */ @@ -62609,7 +61832,7 @@ add_row : { } while (ReadBuffer(start)); // still in quoted state at the end of the file, error: throw InvalidInputException("Error in file \"%s\" on line %s: unterminated quotes. (%s)", options.file_path, - GetLineNumberStr(linenr, linenr_estimated).c_str(), options.toString()); + GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString()); unquote: /* state: unquote */ // this state handles the state directly after we unquote @@ -62636,7 +61859,7 @@ add_row : { error_message = StringUtil::Format( "Error in file \"%s\" on line %s: quote should be followed by end of value, end of " "row or another quote. (%s)", - options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.toString()); + options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString()); return false; } handle_escape: @@ -62646,13 +61869,13 @@ add_row : { if (position >= buffer_size && !ReadBuffer(start)) { error_message = StringUtil::Format( "Error in file \"%s\" on line %s: neither QUOTE nor ESCAPE is proceeded by ESCAPE. (%s)", options.file_path, - GetLineNumberStr(linenr, linenr_estimated).c_str(), options.toString()); + GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString()); return false; } if (buffer[position] != options.quote[0] && buffer[position] != options.escape[0]) { error_message = StringUtil::Format( "Error in file \"%s\" on line %s: neither QUOTE nor ESCAPE is proceeded by ESCAPE. (%s)", options.file_path, - GetLineNumberStr(linenr, linenr_estimated).c_str(), options.toString()); + GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString()); return false; } // escape was followed by quote or escape, go back to quoted state @@ -62703,8 +61926,8 @@ bool BufferedCSVReader::ReadBuffer(idx_t &start) { while (remaining > buffer_read_size) { buffer_read_size *= 2; } - if (remaining + buffer_read_size > MAXIMUM_CSV_LINE_SIZE) { - throw InvalidInputException("Maximum line size of %llu bytes exceeded!", MAXIMUM_CSV_LINE_SIZE); + if (remaining + buffer_read_size > options.maximum_line_size) { + throw InvalidInputException("Maximum line size of %llu bytes exceeded!", options.maximum_line_size); } buffer = unique_ptr(new char[buffer_read_size + remaining + 1]); buffer_size = remaining + buffer_read_size; @@ -62792,7 +62015,7 @@ void BufferedCSVReader::AddValue(char *str_val, idx_t length, idx_t &column, vec if (column >= sql_types.size()) { throw InvalidInputException("Error on line %s: expected %lld values per row, but got more. (%s)", GetLineNumberStr(linenr, linenr_estimated).c_str(), sql_types.size(), - options.toString()); + options.ToString()); } // insert the line number into the chunk @@ -62847,7 +62070,7 @@ bool BufferedCSVReader::AddRow(DataChunk &insert_chunk, idx_t &column) { if (column < sql_types.size() && mode != ParserMode::SNIFFING_DIALECT) { throw InvalidInputException("Error on line %s: expected %lld values per row, but got %d. (%s)", GetLineNumberStr(linenr, linenr_estimated).c_str(), sql_types.size(), column, - options.toString()); + options.ToString()); } if (mode == ParserMode::SNIFFING_DIALECT) { @@ -62900,7 +62123,7 @@ void BufferedCSVReader::Flush(DataChunk &insert_chunk) { throw InvalidInputException("Error in file \"%s\" between line %llu and %llu in column \"%s\": " "file is not valid UTF8. Parser options: %s", options.file_path, linenr - parse_chunk.size(), linenr, col_name, - options.toString()); + options.ToString()); } } } @@ -62934,11 +62157,11 @@ void BufferedCSVReader::Flush(DataChunk &insert_chunk) { "(SAMPLE_SIZE=X [X rows] or SAMPLE_SIZE=-1 [all rows]), " "or skipping column conversion (ALL_VARCHAR=1)", error_message, col_name, linenr - parse_chunk.size() + 1, linenr, - options.toString()); + options.ToString()); } else { throw InvalidInputException("%s between line %llu and %llu in column %s. Parser options: %s ", error_message, linenr - parse_chunk.size(), linenr, col_name, - options.toString()); + options.ToString()); } } } @@ -63561,7 +62784,7 @@ SinkResultType PhysicalInsert::Sink(ExecutionContext &context, GlobalSinkState & if (!column_index_map.empty()) { // columns specified by the user, use column_index_map for (idx_t i = 0; i < table->columns.size(); i++) { - if (column_index_map[i] == INVALID_INDEX) { + if (column_index_map[i] == DConstants::INVALID_INDEX) { // insert default value istate.default_executor.ExecuteExpression(i, istate.insert_chunk.data[i]); } else { @@ -63595,8 +62818,9 @@ unique_ptr PhysicalInsert::GetLocalSinkState(ExecutionContext &c void PhysicalInsert::Combine(ExecutionContext &context, GlobalSinkState &gstate, LocalSinkState &lstate) const { auto &state = (InsertLocalState &)lstate; + auto &client_profiler = QueryProfiler::Get(context.client); context.thread.profiler.Flush(this, &state.default_executor, "default_executor", 1); - context.client.profiler->Flush(context.thread.profiler); + client_profiler.Flush(context.thread.profiler); } //===--------------------------------------------------------------------===// @@ -63802,8 +63026,9 @@ unique_ptr PhysicalUpdate::GetLocalSinkState(ExecutionContext &c void PhysicalUpdate::Combine(ExecutionContext &context, GlobalSinkState &gstate, LocalSinkState &lstate) const { auto &state = (UpdateLocalState &)lstate; + auto &client_profiler = QueryProfiler::Get(context.client); context.thread.profiler.Flush(this, &state.default_executor, "default_executor", 1); - context.client.profiler->Flush(context.thread.profiler); + client_profiler.Flush(context.thread.profiler); } //===--------------------------------------------------------------------===// @@ -64459,18 +63684,11 @@ class PhysicalExpressionScan : public PhysicalOperator { vector>> expressions; public: - unique_ptr GetGlobalSourceState(ClientContext &context) const override; - void GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate, - LocalSourceState &lstate) const override; - -public: - // Sink interface - SinkResultType Sink(ExecutionContext &context, GlobalSinkState &gstate, LocalSinkState &lstate, - DataChunk &input) const override; - - unique_ptr GetGlobalSinkState(ClientContext &context) const override; + unique_ptr GetOperatorState(ClientContext &context) const override; + OperatorResultType Execute(ExecutionContext &context, DataChunk &input, DataChunk &chunk, + OperatorState &state) const override; - bool IsSink() const override { + bool ParallelOperator() const override { return true; } @@ -64486,7 +63704,7 @@ class PhysicalExpressionScan : public PhysicalOperator { namespace duckdb { -class ExpressionScanState : public GlobalSourceState { +class ExpressionScanState : public OperatorState { public: explicit ExpressionScanState(const PhysicalExpressionScan &op) : expression_index(0) { temp_chunk.Initialize(op.GetTypes()); @@ -64498,16 +63716,26 @@ class ExpressionScanState : public GlobalSourceState { DataChunk temp_chunk; }; -class ExpressionSinkState : public GlobalSinkState { -public: - ExpressionSinkState() { - } +unique_ptr PhysicalExpressionScan::GetOperatorState(ClientContext &context) const { + return make_unique(*this); +} - DataChunk child_chunk; -}; +OperatorResultType PhysicalExpressionScan::Execute(ExecutionContext &context, DataChunk &input, DataChunk &chunk, + OperatorState &state_p) const { + auto &state = (ExpressionScanState &)state_p; -unique_ptr PhysicalExpressionScan::GetGlobalSourceState(ClientContext &context) const { - return make_unique(*this); + for (; chunk.size() + input.size() <= STANDARD_VECTOR_SIZE && state.expression_index < expressions.size(); + state.expression_index++) { + state.temp_chunk.Reset(); + EvaluateExpression(state.expression_index, &input, state.temp_chunk); + chunk.Append(state.temp_chunk); + } + if (state.expression_index < expressions.size()) { + return OperatorResultType::HAVE_MORE_OUTPUT; + } else { + state.expression_index = 0; + return OperatorResultType::NEED_MORE_INPUT; + } } void PhysicalExpressionScan::EvaluateExpression(idx_t expression_idx, DataChunk *child_chunk, DataChunk &result) const { @@ -64520,20 +63748,6 @@ void PhysicalExpressionScan::EvaluateExpression(idx_t expression_idx, DataChunk } } -void PhysicalExpressionScan::GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate_p, - LocalSourceState &lstate) const { - D_ASSERT(sink_state); - auto &state = (ExpressionScanState &)gstate_p; - auto &gstate = (ExpressionSinkState &)*sink_state; - - for (; chunk.size() < STANDARD_VECTOR_SIZE && state.expression_index < expressions.size(); - state.expression_index++) { - state.temp_chunk.Reset(); - EvaluateExpression(state.expression_index, &gstate.child_chunk, state.temp_chunk); - chunk.Append(state.temp_chunk); - } -} - bool PhysicalExpressionScan::IsFoldable() const { for (auto &expr_list : expressions) { for (auto &expr : expr_list) { @@ -64545,24 +63759,6 @@ bool PhysicalExpressionScan::IsFoldable() const { return true; } -SinkResultType PhysicalExpressionScan::Sink(ExecutionContext &context, GlobalSinkState &gstate_p, - LocalSinkState &lstate, DataChunk &input) const { - auto &gstate = (ExpressionSinkState &)gstate_p; - - D_ASSERT(children.size() == 1); - D_ASSERT(gstate.child_chunk.size() == 0); - if (input.size() != 1) { - throw InternalException("Expected expression scan child to have exactly one element"); - } - gstate.child_chunk.Move(input); - gstate.child_chunk.Verify(); - return SinkResultType::FINISHED; -} - -unique_ptr PhysicalExpressionScan::GetGlobalSinkState(ClientContext &context) const { - return make_unique(); -} - } // namespace duckdb @@ -66056,7 +65252,7 @@ void PerfectAggregateHashTable::Combine(PerfectAggregateHashTable &other) { data_ptr_t target_ptr = data; idx_t combine_count = 0; idx_t reinit_count = 0; - const auto &reinit_sel = FlatVector::INCREMENTAL_SELECTION_VECTOR; + const auto &reinit_sel = *FlatVector::IncrementalSelectionVector(); for (idx_t i = 0; i < total_groups; i++) { auto has_entry_source = other.group_is_set[i]; // we only have any work to do if the source has an entry for this group @@ -66279,6 +65475,123 @@ unique_ptr PhysicalOperator::GetGlobalSinkState(ClientContext & } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/operator/subtract.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { + +struct SubtractOperator { + template + static inline TR Operation(TA left, TB right) { + return left - right; + } +}; + +template <> +float SubtractOperator::Operation(float left, float right); +template <> +double SubtractOperator::Operation(double left, double right); +template <> +interval_t SubtractOperator::Operation(interval_t left, interval_t right); +template <> +int64_t SubtractOperator::Operation(date_t left, date_t right); +template <> +date_t SubtractOperator::Operation(date_t left, int32_t right); +template <> +date_t SubtractOperator::Operation(date_t left, interval_t right); +template <> +timestamp_t SubtractOperator::Operation(timestamp_t left, interval_t right); +template <> +interval_t SubtractOperator::Operation(timestamp_t left, timestamp_t right); + +struct TrySubtractOperator { + template + static inline bool Operation(TA left, TB right, TR &result) { + throw InternalException("Unimplemented type for TrySubtractOperator"); + } +}; + +template <> +bool TrySubtractOperator::Operation(uint8_t left, uint8_t right, uint8_t &result); +template <> +bool TrySubtractOperator::Operation(uint16_t left, uint16_t right, uint16_t &result); +template <> +bool TrySubtractOperator::Operation(uint32_t left, uint32_t right, uint32_t &result); +template <> +bool TrySubtractOperator::Operation(uint64_t left, uint64_t right, uint64_t &result); + +template <> +bool TrySubtractOperator::Operation(int8_t left, int8_t right, int8_t &result); +template <> +bool TrySubtractOperator::Operation(int16_t left, int16_t right, int16_t &result); +template <> +bool TrySubtractOperator::Operation(int32_t left, int32_t right, int32_t &result); +template <> +bool TrySubtractOperator::Operation(int64_t left, int64_t right, int64_t &result); + +struct SubtractOperatorOverflowCheck { + template + 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, + right); + } + return result; + } +}; + +struct TryDecimalSubtract { + template + static inline bool Operation(TA left, TB right, TR &result) { + throw InternalException("Unimplemented type for TryDecimalSubtract"); + } +}; + +template <> +bool TryDecimalSubtract::Operation(int16_t left, int16_t right, int16_t &result); +template <> +bool TryDecimalSubtract::Operation(int32_t left, int32_t right, int32_t &result); +template <> +bool TryDecimalSubtract::Operation(int64_t left, int64_t right, int64_t &result); +template <> +bool TryDecimalSubtract::Operation(hugeint_t left, hugeint_t right, hugeint_t &result); + +struct DecimalSubtractOverflowCheck { + template + static inline TR Operation(TA left, TB right) { + TR result; + if (!TryDecimalSubtract::Operation(left, right, result)) { + throw OutOfRangeException("Overflow in subtract of DECIMAL(18) (%d - %d). You might want to add an " + "explicit cast to a bigger decimal.", + left, right); + } + return result; + } +}; + +template <> +hugeint_t DecimalSubtractOverflowCheck::Operation(hugeint_t left, hugeint_t right); + +struct SubtractTimeOperator { + template + static TR Operation(TA left, TB right); +}; + +template <> +dtime_t SubtractTimeOperator::Operation(dtime_t left, interval_t right); + +} // namespace duckdb @@ -66298,6 +65611,49 @@ unique_ptr PhysicalOperator::GetGlobalSinkState(ClientContext & +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/operator/logical_limit_percent.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +//! 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)) { + } + + //! 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; + +public: + vector GetColumnBindings() override { + return children[0]->GetColumnBindings(); + } + +protected: + void ResolveTypes() override { + types = children[0]->types; + } +}; +} // namespace duckdb + @@ -66344,6 +65700,7 @@ class PhysicalPlanGenerator { 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); @@ -66377,6 +65734,39 @@ class PhysicalPlanGenerator { } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/expression/comparison_expression.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { +//! ComparisonExpression represents a boolean comparison (e.g. =, >=, <>). Always returns a boolean +//! and has two children. +class ComparisonExpression : public ParsedExpression { +public: + ComparisonExpression(ExpressionType type, unique_ptr left, unique_ptr right); + + unique_ptr left; + unique_ptr right; + +public: + string ToString() const override; + + static bool Equals(const ComparisonExpression *a, const ComparisonExpression *b); + + unique_ptr Copy() const override; + + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(ExpressionType type, FieldReader &source); +}; +} // namespace duckdb //===----------------------------------------------------------------------===// @@ -66484,7 +65874,7 @@ static bool CanUsePerfectHashAggregate(ClientContext &context, LogicalAggregate } auto &nstats = (NumericStatistics &)*stats; - if (nstats.min.is_null || nstats.max.is_null) { + if (nstats.min.IsNull() || nstats.max.IsNull()) { return false; } // we have a min and a max value for the stats: use that to figure out how many bits we have @@ -66520,7 +65910,7 @@ static bool CanUsePerfectHashAggregate(ClientContext &context, LogicalAggregate bits_per_group.push_back(required_bits); perfect_hash_bits += required_bits; // check if we have exceeded the bits for the hash - if (perfect_hash_bits > context.perfect_ht_threshold) { + if (perfect_hash_bits > ClientConfig::GetConfig(context).perfect_ht_threshold) { // too many bits for perfect hash return false; } @@ -66755,6 +66145,7 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalChunkGet & + namespace duckdb { static bool CanPlanIndexJoin(Transaction &transaction, TableScanBindData *bind_data, PhysicalTableScan &scan) { @@ -66774,6 +66165,30 @@ static bool CanPlanIndexJoin(Transaction &transaction, TableScanBindData *bind_d return true; } +bool ExtractNumericValue(Value val, int64_t &result) { + if (!val.type().IsIntegral()) { + switch (val.type().InternalType()) { + case PhysicalType::INT16: + result = val.GetValueUnsafe(); + break; + case PhysicalType::INT32: + result = val.GetValueUnsafe(); + break; + case PhysicalType::INT64: + result = val.GetValueUnsafe(); + break; + default: + return false; + } + } else { + if (!val.TryCastAs(LogicalType::BIGINT)) { + return false; + } + result = val.GetValue(); + } + return true; +} + void CheckForPerfectJoinOpt(LogicalComparisonJoin &op, PerfectHashJoinStats &join_state) { // we only do this optimization for inner joins if (op.join_type != JoinType::INNER) { @@ -66803,10 +66218,17 @@ void CheckForPerfectJoinOpt(LogicalComparisonJoin &op, PerfectHashJoinStats &joi // and when the build range is smaller than the threshold auto stats_build = reinterpret_cast(op.join_stats[0].get()); // lhs stats - if (stats_build->min.is_null || stats_build->max.is_null) { + if (stats_build->min.IsNull() || stats_build->max.IsNull()) { + return; + } + int64_t min_value, max_value; + if (!ExtractNumericValue(stats_build->min, min_value) || !ExtractNumericValue(stats_build->max, max_value)) { + return; + } + int64_t build_range; + if (!TrySubtractOperator::Operation(max_value, min_value, build_range)) { return; } - auto build_range = stats_build->max - stats_build->min; // Join Keys Range // Fill join_stats for invisible join auto stats_probe = reinterpret_cast(op.join_stats[1].get()); // rhs stats @@ -66818,27 +66240,8 @@ void CheckForPerfectJoinOpt(LogicalComparisonJoin &op, PerfectHashJoinStats &joi join_state.build_min = stats_build->min; join_state.build_max = stats_build->max; join_state.estimated_cardinality = op.estimated_cardinality; - if (!build_range.type().IsIntegral()) { - switch (build_range.type().InternalType()) { - case PhysicalType::INT16: - join_state.build_range = build_range.value_.smallint; - break; - case PhysicalType::INT32: - join_state.build_range = build_range.value_.integer; - break; - case PhysicalType::INT64: - join_state.build_range = build_range.value_.bigint; - break; - case PhysicalType::INT128: - // we do not support hugeint for this optimization - return; - default: - throw InternalException("Invalid Physical Type for Decimals"); - } - } else { - join_state.build_range = build_range.GetValue(); // cast integer types into idx_t - } - if (join_state.build_range > MAX_BUILD_SIZE || stats_probe->max.is_null || stats_probe->min.is_null) { + join_state.build_range = build_range; + if (join_state.build_range > MAX_BUILD_SIZE || stats_probe->max.IsNull() || stats_probe->min.IsNull()) { return; } if (stats_build->min <= stats_probe->min && stats_probe->max <= stats_build->max) { @@ -66923,14 +66326,16 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalComparison if (has_equality) { Index *left_index {}, *right_index {}; TransformIndexJoin(context, op, &left_index, &right_index, left.get(), right.get()); - if (left_index && (context.force_index_join || rhs_cardinality < 0.01 * lhs_cardinality)) { + if (left_index && + (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); } - if (right_index && (context.force_index_join || lhs_cardinality < 0.01 * rhs_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, @@ -66986,7 +66391,7 @@ class LogicalCopyToFile : public LogicalOperator { protected: void ResolveTypes() override { - types.push_back(LogicalType::BIGINT); + types.emplace_back(LogicalType::BIGINT); } }; } // namespace duckdb @@ -67039,7 +66444,7 @@ class LogicalCreate : public LogicalOperator { protected: void ResolveTypes() override { - types.push_back(LogicalType::BIGINT); + types.emplace_back(LogicalType::BIGINT); } }; } // namespace duckdb @@ -67155,7 +66560,7 @@ class LogicalCreateTable : public LogicalOperator { protected: void ResolveTypes() override { - types.push_back(LogicalType::BIGINT); + types.emplace_back(LogicalType::BIGINT); } }; } // namespace duckdb @@ -67266,7 +66671,7 @@ class LogicalDelete : public LogicalOperator { protected: void ResolveTypes() override { - types.push_back(LogicalType::BIGINT); + types.emplace_back(LogicalType::BIGINT); } }; } // namespace duckdb @@ -67564,7 +66969,7 @@ class LogicalDummyScan : public LogicalOperator { protected: void ResolveTypes() override { if (types.size() == 0) { - types.push_back(LogicalType::INTEGER); + types.emplace_back(LogicalType::INTEGER); } } }; @@ -67690,15 +67095,50 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalExecute &o +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/statement/explain_statement.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { + +enum class ExplainType : uint8_t { EXPLAIN_STANDARD, EXPLAIN_ANALYZE }; + +class ExplainStatement : public SQLStatement { +public: + explicit ExplainStatement(unique_ptr stmt, ExplainType explain_type = ExplainType::EXPLAIN_STANDARD); + + unique_ptr stmt; + ExplainType explain_type; + +protected: + ExplainStatement(const ExplainStatement &other); + +public: + unique_ptr Copy() const override; +}; + +} // namespace duckdb + namespace duckdb { class LogicalExplain : public LogicalOperator { public: - explicit LogicalExplain(unique_ptr plan) : LogicalOperator(LogicalOperatorType::LOGICAL_EXPLAIN) { + LogicalExplain(unique_ptr plan, ExplainType explain_type) + : LogicalOperator(LogicalOperatorType::LOGICAL_EXPLAIN), explain_type(explain_type) { children.push_back(move(plan)); } + ExplainType explain_type; string physical_plan; string logical_plan_unopt; string logical_plan_opt; @@ -67717,18 +67157,23 @@ class LogicalExplain : public LogicalOperator { + namespace duckdb { unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalExplain &op) { D_ASSERT(op.children.size() == 1); auto logical_plan_opt = op.children[0]->ToString(); 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); + } op.physical_plan = plan->ToString(); - // the output of the explain vector keys, values; - switch (context.explain_output_type) { + switch (ClientConfig::GetConfig(context).explain_output_type) { case ExplainOutputType::OPTIMIZED_ONLY: keys = {"logical_opt"}; values = {logical_plan_opt}; @@ -67798,16 +67243,21 @@ class LogicalExport : public LogicalOperator { protected: void ResolveTypes() override { - types.push_back(LogicalType::BOOLEAN); + types.emplace_back(LogicalType::BOOLEAN); } }; } // namespace duckdb + namespace duckdb { unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalExport &op) { + auto &config = DBConfig::GetConfig(context); + if (!config.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); // plan the underlying copy statements, if any @@ -68000,6 +67450,8 @@ class SetMatcher { UNORDERED, //! Only some entries have to be matched, the order of the matches does not matter SOME, + //! Not initialized + INVALID }; /* The double {{}} in the intializer for excluded_entries is intentional, workaround for bug in gcc-4.9 */ @@ -68259,7 +67711,8 @@ class CaseExpressionMatcher : public ExpressionMatcher { class ComparisonExpressionMatcher : public ExpressionMatcher { public: - ComparisonExpressionMatcher() : ExpressionMatcher(ExpressionClass::BOUND_COMPARISON) { + ComparisonExpressionMatcher() + : ExpressionMatcher(ExpressionClass::BOUND_COMPARISON), policy(SetMatcher::Policy::INVALID) { } //! The matchers for the child expressions vector> matchers; @@ -68293,7 +67746,8 @@ class InClauseExpressionMatcher : public ExpressionMatcher { class ConjunctionExpressionMatcher : public ExpressionMatcher { public: - ConjunctionExpressionMatcher() : ExpressionMatcher(ExpressionClass::BOUND_CONJUNCTION) { + ConjunctionExpressionMatcher() + : ExpressionMatcher(ExpressionClass::BOUND_CONJUNCTION), policy(SetMatcher::Policy::INVALID) { } //! The matchers for the child expressions vector> matchers; @@ -68409,6 +67863,8 @@ class LogicalGet : public LogicalOperator { string GetName() const override; string ParamsToString() const override; + //! Returns the underlying table that is being scanned, or nullptr if there is none + TableCatalogEntry *GetTable() const; public: vector GetColumnBindings() override; @@ -68464,14 +67920,14 @@ unique_ptr CreateTableFilterSet(TableFilterSet &table_filters, v auto table_filter_set = make_unique(); for (auto &table_filter : table_filters.filters) { // find the relative column index from the absolute column index into the table - idx_t column_index = INVALID_INDEX; + idx_t column_index = DConstants::INVALID_INDEX; for (idx_t i = 0; i < column_ids.size(); i++) { if (table_filter.first == column_ids[i]) { column_index = i; break; } } - if (column_index == INVALID_INDEX) { + 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); @@ -68523,7 +67979,7 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalGet &op) { vector> expressions; for (auto &column_id : op.column_ids) { if (column_id == COLUMN_IDENTIFIER_ROW_ID) { - types.push_back(LogicalType::BIGINT); + types.emplace_back(LogicalType::BIGINT); expressions.push_back(make_unique(Value::BIGINT(0))); } else { auto type = op.returned_types[column_id]; @@ -68567,7 +68023,7 @@ class LogicalInsert : public LogicalOperator { } vector>> insert_values; - //! The insertion map ([table_index -> index in result, or INVALID_INDEX if not specified]) + //! The insertion map ([table_index -> index in result, or DConstants::INVALID_INDEX if not specified]) vector column_index_map; //! The expected types for the INSERT statement (obtained from the column types) vector expected_types; @@ -68578,7 +68034,7 @@ class LogicalInsert : public LogicalOperator { protected: void ResolveTypes() override { - types.push_back(LogicalType::BIGINT); + types.emplace_back(LogicalType::BIGINT); } }; } // namespace duckdb @@ -68622,10 +68078,7 @@ namespace duckdb { //! LogicalLimit represents a LIMIT clause class LogicalLimit : public LogicalOperator { public: - 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)) { - } + LogicalLimit(int64_t limit_val, int64_t offset_val, unique_ptr limit, unique_ptr offset); //! Limit and offset values in case they are constants, used in optimizations. int64_t limit_val; @@ -68636,14 +68089,12 @@ class LogicalLimit : public LogicalOperator { unique_ptr offset; public: - vector GetColumnBindings() override { - return children[0]->GetColumnBindings(); - } + vector GetColumnBindings() override; + + idx_t EstimateCardinality(ClientContext &context) override; protected: - void ResolveTypes() override { - types = children[0]->types; - } + void ResolveTypes() override; }; } // namespace duckdb @@ -68655,8 +68106,26 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalLimit &op) auto plan = CreatePlan(*op.children[0]); - auto limit = make_unique(op.types, op.limit_val, op.offset_val, move(op.limit), move(op.offset), - op.estimated_cardinality); + auto limit = make_unique(op.types, (idx_t)op.limit_val, op.offset_val, move(op.limit), + move(op.offset), op.estimated_cardinality); + limit->children.push_back(move(plan)); + return move(limit); +} + +} // namespace duckdb + + + + +namespace duckdb { + +unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalLimitPercent &op) { + D_ASSERT(op.children.size() == 1); + + 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); } @@ -68759,7 +68228,7 @@ class LogicalPragma : public LogicalOperator { protected: void ResolveTypes() override { - types.push_back(LogicalType::BOOLEAN); + types.emplace_back(LogicalType::BOOLEAN); } }; } // namespace duckdb @@ -68806,7 +68275,7 @@ class LogicalPrepare : public LogicalOperator { protected: void ResolveTypes() override { - types.push_back(LogicalType::BOOLEAN); + types.emplace_back(LogicalType::BOOLEAN); } }; } // namespace duckdb @@ -69048,23 +68517,18 @@ namespace duckdb { //! LogicalSample represents a SAMPLE clause class LogicalSample : public LogicalOperator { public: - LogicalSample(unique_ptr sample_options_p, unique_ptr child) - : LogicalOperator(LogicalOperatorType::LOGICAL_SAMPLE), sample_options(move(sample_options_p)) { - children.push_back(move(child)); - } + LogicalSample(unique_ptr sample_options_p, unique_ptr child); //! The sample options unique_ptr sample_options; public: - vector GetColumnBindings() override { - return children[0]->GetColumnBindings(); - } + vector GetColumnBindings() override; + + idx_t EstimateCardinality(ClientContext &context) override; protected: - void ResolveTypes() override { - types = children[0]->types; - } + void ResolveTypes() override; }; } // namespace duckdb @@ -69131,7 +68595,7 @@ class LogicalSet : public LogicalOperator { protected: void ResolveTypes() override { - types.push_back(LogicalType::BOOLEAN); + types.emplace_back(LogicalType::BOOLEAN); } }; @@ -69377,7 +68841,7 @@ class LogicalSimple : public LogicalOperator { protected: void ResolveTypes() override { - types.push_back(LogicalType::BOOLEAN); + types.emplace_back(LogicalType::BOOLEAN); } }; } // namespace duckdb @@ -69465,7 +68929,8 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalTopN &op) auto plan = CreatePlan(*op.children[0]); - auto top_n = make_unique(op.types, move(op.orders), op.limit, op.offset, op.estimated_cardinality); + 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); } @@ -69547,7 +69012,7 @@ class LogicalUpdate : public LogicalOperator { protected: void ResolveTypes() override { - types.push_back(LogicalType::BIGINT); + types.emplace_back(LogicalType::BIGINT); } }; } // namespace duckdb @@ -69572,6 +69037,9 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalUpdate &op + + + //===----------------------------------------------------------------------===// // DuckDB // @@ -69605,12 +69073,28 @@ class LogicalWindow : public LogicalOperator { } // namespace duckdb - - #include namespace duckdb { +static bool IsStreamingWindow(unique_ptr &expr) { + auto wexpr = reinterpret_cast(expr.get()); + if (!wexpr->partitions.empty() || !wexpr->orders.empty() || wexpr->ignore_nulls) { + return false; + } + switch (wexpr->type) { + // TODO: add more expression types here? + case ExpressionType::WINDOW_FIRST_VALUE: + case ExpressionType::WINDOW_PERCENT_RANK: + case ExpressionType::WINDOW_RANK: + case ExpressionType::WINDOW_RANK_DENSE: + case ExpressionType::WINDOW_ROW_NUMBER: + return true; + default: + return false; + } +} + unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalWindow &op) { D_ASSERT(op.children.size() == 1); @@ -69626,11 +69110,23 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalWindow &op const auto output_idx = types.size() - op.expressions.size(); types.resize(output_idx); + // Identify streaming windows + vector blocking_windows; + vector streaming_windows; + for (idx_t expr_idx = 0; expr_idx < op.expressions.size(); expr_idx++) { + if (IsStreamingWindow(op.expressions[expr_idx])) { + streaming_windows.push_back(expr_idx); + } else { + blocking_windows.push_back(expr_idx); + } + } + // Process the window functions by sharing the partition/order definitions vector evaluation_order; - vector remaining(op.expressions.size()); - std::iota(remaining.begin(), remaining.end(), 0); - while (!remaining.empty()) { + while (!blocking_windows.empty() || !streaming_windows.empty()) { + const bool process_streaming = blocking_windows.empty(); + auto &remaining = process_streaming ? streaming_windows : blocking_windows; + // Find all functions that share the partitioning of the first remaining expression const auto over_idx = remaining[0]; auto over_expr = reinterpret_cast(op.expressions[over_idx].get()); @@ -69656,7 +69152,12 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalWindow &op } // Chain the new window operator on top of the plan - auto window = make_unique(types, move(select_list), op.estimated_cardinality); + unique_ptr window; + if (process_streaming) { + window = make_unique(types, move(select_list), op.estimated_cardinality); + } else { + window = make_unique(types, move(select_list), op.estimated_cardinality); + } window->children.push_back(move(plan)); plan = move(window); @@ -69715,25 +69216,27 @@ class DependencyExtractor : public LogicalOperatorVisitor { }; unique_ptr PhysicalPlanGenerator::CreatePlan(unique_ptr op) { + auto &profiler = QueryProfiler::Get(context); + // first resolve column references - context.profiler->StartPhase("column_binding"); + profiler.StartPhase("column_binding"); ColumnBindingResolver resolver; resolver.VisitOperator(*op); - context.profiler->EndPhase(); + profiler.EndPhase(); // now resolve types of all the operators - context.profiler->StartPhase("resolve_types"); + profiler.StartPhase("resolve_types"); op->ResolveOperatorTypes(); - context.profiler->EndPhase(); + profiler.EndPhase(); // extract dependencies from the logical plan DependencyExtractor extractor(dependencies); extractor.VisitOperator(*op); // then create the main physical plan - context.profiler->StartPhase("create_plan"); + profiler.StartPhase("create_plan"); auto plan = CreatePlan(*op); - context.profiler->EndPhase(); + profiler.EndPhase(); return plan; } @@ -69756,6 +69259,8 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalOperator & return CreatePlan((LogicalUnnest &)op); case LogicalOperatorType::LOGICAL_LIMIT: return CreatePlan((LogicalLimit &)op); + case LogicalOperatorType::LOGICAL_LIMIT_PERCENT: + return CreatePlan((LogicalLimitPercent &)op); case LogicalOperatorType::LOGICAL_SAMPLE: return CreatePlan((LogicalSample &)op); case LogicalOperatorType::LOGICAL_ORDER_BY: @@ -69853,7 +69358,7 @@ RadixPartitionedHashTable::RadixPartitionedHashTable(GroupingSet &grouping_set_p if (grouping_set.empty()) { // fake a single group with a constant value for aggregation without groups - group_types.push_back(LogicalType::TINYINT); + group_types.emplace_back(LogicalType::TINYINT); } for (auto &entry : grouping_set) { D_ASSERT(entry < op.group_types.size()); @@ -70093,6 +69598,7 @@ class RadixAggregateFinalizeTask : public ExecutorTask { idx_t radix_p) : ExecutorTask(executor), event(move(event_p)), state(state_p), radix(radix_p) { } + static void FinalizeHT(RadixHTGlobalState &gstate, idx_t radix) { D_ASSERT(gstate.partition_info.n_partitions <= gstate.finalized_hts.size()); D_ASSERT(gstate.finalized_hts[radix]); @@ -70105,9 +69611,10 @@ class RadixAggregateFinalizeTask : public ExecutorTask { gstate.finalized_hts[radix]->Finalize(); } - void ExecuteTask() override { + TaskExecutionResult ExecuteTask(TaskExecutionMode mode) override { FinalizeHT(state, radix); event->FinishTask(); + return TaskExecutionResult::TASK_FINISHED; } private: @@ -70470,8 +69977,8 @@ WindowSegmentTree::WindowSegmentTree(AggregateFunction &aggregate, FunctionData const LogicalType &result_type_p, ChunkCollection *input, WindowAggregationMode mode_p) : aggregate(aggregate), bind_info(bind_info), result_type(result_type_p), state(aggregate.state_size()), - statep(Value::POINTER((idx_t)state.data())), frame(0, 0), statev(Value::POINTER((idx_t)state.data())), - internal_nodes(0), input_ref(input), mode(mode_p) { + statep(Value::POINTER((idx_t)state.data())), frame(0, 0), active(0, 1), + statev(Value::POINTER((idx_t)state.data())), internal_nodes(0), input_ref(input), mode(mode_p) { #if STANDARD_VECTOR_SIZE < 512 throw NotImplementedException("Window functions are not supported for vector sizes < 512"); #endif @@ -70483,6 +69990,7 @@ WindowSegmentTree::WindowSegmentTree(AggregateFunction &aggregate, FunctionData // if we have a frame-by-frame method, share the single state if (aggregate.window && UseWindowAPI()) { AggregateInit(); + inputs.Reference(input_ref->GetChunk(0)); } else if (aggregate.combine && UseCombineAPI()) { ConstructTree(); } @@ -70649,9 +70157,38 @@ void WindowSegmentTree::Compute(Vector &result, idx_t rid, idx_t begin, idx_t en frame = FrameBounds(begin, end); // Extract the range - ExtractFrame(MinValue(frame.first, prev.first), MaxValue(frame.second, prev.second)); + auto &coll = *input_ref; + const auto prev_active = active; + const FrameBounds combined(MinValue(frame.first, prev.first), MaxValue(frame.second, prev.second)); + + // The chunk bounds are the range that includes the begin and end - 1 + const FrameBounds prev_chunks(coll.LocateChunk(prev_active.first), coll.LocateChunk(prev_active.second - 1)); + const FrameBounds active_chunks(coll.LocateChunk(combined.first), coll.LocateChunk(combined.second - 1)); - aggregate.window(inputs.data.data(), bind_info, inputs.ColumnCount(), state.data(), frame, prev, result, rid); + // Extract the range + if (active_chunks.first == active_chunks.second) { + // If all the data is in a single chunk, then just reference it + if (prev_chunks != active_chunks || (!prev.first && !prev.second)) { + inputs.Reference(coll.GetChunk(active_chunks.first)); + } + } else if (active_chunks.first == prev_chunks.first && prev_chunks.first != prev_chunks.second) { + // If the start chunk did not change, and we are not just a reference, then extend if necessary + for (auto chunk_idx = prev_chunks.second + 1; chunk_idx <= active_chunks.second; ++chunk_idx) { + inputs.Append(coll.GetChunk(chunk_idx), true); + } + } else { + // If the first chunk changed, start over + inputs.Reset(); + for (auto chunk_idx = active_chunks.first; chunk_idx <= active_chunks.second; ++chunk_idx) { + inputs.Append(coll.GetChunk(chunk_idx), true); + } + } + + active = FrameBounds(active_chunks.first * STANDARD_VECTOR_SIZE, + MinValue((active_chunks.second + 1) * STANDARD_VECTOR_SIZE, coll.Count())); + + aggregate.window(inputs.data.data(), bind_info, inputs.ColumnCount(), state.data(), frame, prev, result, rid, + active.first); return; } @@ -71608,6 +71145,12 @@ struct ApproxCountDistinctFunctionString : ApproxCountDistinctFunctionBase { } }; +template +AggregateFunction GetApproxCountDistinctFunction(const LogicalType &input_type, const LogicalType &result_type) { + return AggregateFunction::UnaryAggregateDestructor(input_type, result_type); +} + AggregateFunction GetApproxCountDistinctFunction(PhysicalType type) { switch (type) { case PhysicalType::UINT16: @@ -71663,9 +71206,10 @@ void ApproxCountDistinctFun::RegisterFunction(BuiltinFunctions &set) { approx_count.AddFunction(GetApproxCountDistinctFunction(PhysicalType::INT64)); approx_count.AddFunction(GetApproxCountDistinctFunction(PhysicalType::DOUBLE)); approx_count.AddFunction(GetApproxCountDistinctFunction(PhysicalType::VARCHAR)); - approx_count.AddFunction(AggregateFunction::UnaryAggregateDestructor( - LogicalType::TIMESTAMP, LogicalType::BIGINT)); + approx_count.AddFunction( + GetApproxCountDistinctFunction(LogicalType::TIMESTAMP, LogicalType::BIGINT)); + approx_count.AddFunction( + GetApproxCountDistinctFunction(LogicalType::TIMESTAMP_TZ, LogicalType::BIGINT)); set.AddFunction(approx_count); } @@ -71796,6 +71340,9 @@ AggregateFunction GetArgMinMaxFunctionArg2(LogicalTypeId arg_2, const LogicalTyp case LogicalTypeId::TIMESTAMP: return AggregateFunction::BinaryAggregate, T, timestamp_t, T, OP>( arg, LogicalType::TIMESTAMP, arg); + case LogicalTypeId::TIMESTAMP_TZ: + return AggregateFunction::BinaryAggregate, T, timestamp_t, T, OP>( + arg, LogicalType::TIMESTAMP_TZ, arg); case LogicalTypeId::BLOB: return AggregateFunction::BinaryAggregate, T, string_t, T, OP>( arg, LogicalType::BLOB, arg); @@ -71814,6 +71361,7 @@ void GetArgMinMaxFunction(LogicalTypeId arg_1, AggregateFunctionSet &fun) { fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::VARCHAR, LogicalType::INTEGER)); fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::DATE, LogicalType::INTEGER)); fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::TIMESTAMP, LogicalType::INTEGER)); + fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::TIMESTAMP_TZ, LogicalType::INTEGER)); fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::BLOB, LogicalType::INTEGER)); break; case LogicalTypeId::BIGINT: @@ -71823,6 +71371,7 @@ void GetArgMinMaxFunction(LogicalTypeId arg_1, AggregateFunctionSet &fun) { fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::VARCHAR, LogicalType::BIGINT)); fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::DATE, LogicalType::BIGINT)); fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::TIMESTAMP, LogicalType::BIGINT)); + fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::TIMESTAMP_TZ, LogicalType::BIGINT)); fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::BLOB, LogicalType::BIGINT)); break; case LogicalTypeId::DOUBLE: @@ -71832,6 +71381,7 @@ void GetArgMinMaxFunction(LogicalTypeId arg_1, AggregateFunctionSet &fun) { fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::VARCHAR, LogicalType::DOUBLE)); fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::DATE, LogicalType::DOUBLE)); fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::TIMESTAMP, LogicalType::DOUBLE)); + fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::TIMESTAMP_TZ, LogicalType::DOUBLE)); fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::BLOB, LogicalType::DOUBLE)); break; case LogicalTypeId::VARCHAR: @@ -71841,6 +71391,7 @@ void GetArgMinMaxFunction(LogicalTypeId arg_1, AggregateFunctionSet &fun) { fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::VARCHAR, LogicalType::VARCHAR)); fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::DATE, LogicalType::VARCHAR)); fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::TIMESTAMP, LogicalType::VARCHAR)); + fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::TIMESTAMP_TZ, LogicalType::VARCHAR)); fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::BLOB, LogicalType::VARCHAR)); break; case LogicalTypeId::DATE: @@ -71850,6 +71401,7 @@ void GetArgMinMaxFunction(LogicalTypeId arg_1, AggregateFunctionSet &fun) { fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::VARCHAR, LogicalType::DATE)); fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::DATE, LogicalType::DATE)); fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::TIMESTAMP, LogicalType::DATE)); + fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::TIMESTAMP_TZ, LogicalType::DATE)); fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::BLOB, LogicalType::DATE)); break; case LogicalTypeId::TIMESTAMP: @@ -71859,8 +71411,20 @@ void GetArgMinMaxFunction(LogicalTypeId arg_1, AggregateFunctionSet &fun) { fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::VARCHAR, LogicalType::TIMESTAMP)); fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::DATE, LogicalType::TIMESTAMP)); fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::TIMESTAMP, LogicalType::TIMESTAMP)); + fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::TIMESTAMP_TZ, LogicalType::TIMESTAMP)); fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::BLOB, LogicalType::TIMESTAMP)); break; + case LogicalTypeId::TIMESTAMP_TZ: + fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::INTEGER, LogicalType::TIMESTAMP_TZ)); + fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::BIGINT, LogicalType::TIMESTAMP_TZ)); + fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::DOUBLE, LogicalType::TIMESTAMP_TZ)); + fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::VARCHAR, LogicalType::TIMESTAMP_TZ)); + fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::DATE, LogicalType::TIMESTAMP_TZ)); + fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::TIMESTAMP, LogicalType::TIMESTAMP_TZ)); + fun.AddFunction( + GetArgMinMaxFunctionArg2(LogicalTypeId::TIMESTAMP_TZ, LogicalType::TIMESTAMP_TZ)); + fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::BLOB, LogicalType::TIMESTAMP_TZ)); + break; case LogicalTypeId::BLOB: fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::INTEGER, LogicalType::BLOB)); fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::BIGINT, LogicalType::BLOB)); @@ -71868,6 +71432,7 @@ void GetArgMinMaxFunction(LogicalTypeId arg_1, AggregateFunctionSet &fun) { fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::VARCHAR, LogicalType::BLOB)); fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::DATE, LogicalType::BLOB)); fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::TIMESTAMP, LogicalType::BLOB)); + fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::TIMESTAMP_TZ, LogicalType::BLOB)); fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalTypeId::BLOB, LogicalType::BLOB)); break; default: @@ -71882,6 +71447,7 @@ void ArgMinFun::RegisterFunction(BuiltinFunctions &set) { GetArgMinMaxFunction(LogicalTypeId::VARCHAR, fun); GetArgMinMaxFunction(LogicalTypeId::DATE, fun); GetArgMinMaxFunction(LogicalTypeId::TIMESTAMP, fun); + GetArgMinMaxFunction(LogicalTypeId::TIMESTAMP_TZ, fun); GetArgMinMaxFunction(LogicalTypeId::BLOB, fun); set.AddFunction(fun); @@ -71902,6 +71468,7 @@ void ArgMaxFun::RegisterFunction(BuiltinFunctions &set) { GetArgMinMaxFunction(LogicalTypeId::VARCHAR, fun); GetArgMinMaxFunction(LogicalTypeId::DATE, fun); GetArgMinMaxFunction(LogicalTypeId::TIMESTAMP, fun); + GetArgMinMaxFunction(LogicalTypeId::TIMESTAMP_TZ, fun); GetArgMinMaxFunction(LogicalTypeId::BLOB, fun); set.AddFunction(fun); @@ -72009,7 +71576,7 @@ struct BitAndOperation { void BitAndFun::RegisterFunction(BuiltinFunctions &set) { AggregateFunctionSet bit_and("bit_and"); - for (auto &type : LogicalType::INTEGRAL) { + for (auto &type : LogicalType::Integral()) { bit_and.AddFunction(GetBitfieldUnaryAggregate(type)); } set.AddFunction(bit_and); @@ -72069,7 +71636,7 @@ struct BitOrOperation { void BitOrFun::RegisterFunction(BuiltinFunctions &set) { AggregateFunctionSet bit_or("bit_or"); - for (auto &type : LogicalType::INTEGRAL) { + for (auto &type : LogicalType::Integral()) { bit_or.AddFunction(GetBitfieldUnaryAggregate(type)); } set.AddFunction(bit_or); @@ -72129,7 +71696,7 @@ struct BitXorOperation { void BitXorFun::RegisterFunction(BuiltinFunctions &set) { AggregateFunctionSet bit_xor("bit_xor"); - for (auto &type : LogicalType::INTEGRAL) { + for (auto &type : LogicalType::Integral()) { bit_xor.AddFunction(GetBitfieldUnaryAggregate(type)); } set.AddFunction(bit_xor); @@ -72468,6 +72035,12 @@ struct EntropyFunctionString : EntropyFunctionBase { } }; +template +AggregateFunction GetEntropyFunction(const LogicalType &input_type, const LogicalType &result_type) { + return AggregateFunction::UnaryAggregateDestructor, INPUT_TYPE, RESULT_TYPE, + EntropyFunction>(input_type, result_type); +} + AggregateFunction GetEntropyFunction(PhysicalType type) { switch (type) { case PhysicalType::UINT16: @@ -72515,9 +72088,8 @@ void EntropyFun::RegisterFunction(BuiltinFunctions &set) { entropy.AddFunction(GetEntropyFunction(PhysicalType::INT64)); entropy.AddFunction(GetEntropyFunction(PhysicalType::DOUBLE)); entropy.AddFunction(GetEntropyFunction(PhysicalType::VARCHAR)); - entropy.AddFunction( - AggregateFunction::UnaryAggregateDestructor, int64_t, double, EntropyFunction>( - LogicalType::TIMESTAMP, LogicalType::DOUBLE)); + entropy.AddFunction(GetEntropyFunction(LogicalType::TIMESTAMP, LogicalType::DOUBLE)); + entropy.AddFunction(GetEntropyFunction(LogicalType::TIMESTAMP_TZ, LogicalType::DOUBLE)); set.AddFunction(entropy); } @@ -72760,6 +72332,8 @@ static AggregateFunction GetFirstFunction(const LogicalType &type) { case LogicalTypeId::BIGINT: case LogicalTypeId::TIME: case LogicalTypeId::TIMESTAMP: + case LogicalTypeId::TIME_TZ: + case LogicalTypeId::TIMESTAMP_TZ: return GetFirstAggregateTemplated(type); case LogicalTypeId::UTINYINT: return GetFirstAggregateTemplated(type); @@ -72819,7 +72393,7 @@ unique_ptr BindDecimalFirst(ClientContext &context, AggregateFunct void FirstFun::RegisterFunction(BuiltinFunctions &set) { AggregateFunctionSet first("first"); AggregateFunctionSet last("last"); - for (auto &type : LogicalType::ALL_TYPES) { + for (auto &type : LogicalType::AllTypes()) { if (type.id() == LogicalTypeId::DECIMAL) { first.AddFunction(AggregateFunction({type}, type, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, BindDecimalFirst, nullptr, nullptr, nullptr)); @@ -72965,6 +72539,8 @@ static AggregateFunction GetUnaryAggregate(LogicalType type) { return AggregateFunction::UnaryAggregate, int32_t, int32_t, OP>(type, type); case LogicalTypeId::TIMESTAMP: case LogicalTypeId::TIME: + case LogicalTypeId::TIMESTAMP_TZ: + case LogicalTypeId::TIME_TZ: case LogicalTypeId::BIGINT: return AggregateFunction::UnaryAggregate, int64_t, int64_t, OP>(type, type); case LogicalTypeId::UTINYINT: @@ -73456,7 +73032,7 @@ static AggregateFunction GetMinMaxFunction(const LogicalType &type) { template static void AddMinMaxOperator(AggregateFunctionSet &set) { - for (auto &type : LogicalType::ALL_TYPES) { + for (auto &type : LogicalType::AllTypes()) { if (type.id() == LogicalTypeId::VARCHAR || type.id() == LogicalTypeId::BLOB) { set.AddFunction( AggregateFunction::UnaryAggregateDestructor, string_t, string_t, OP_STRING>( @@ -73861,7 +73437,7 @@ unique_ptr SumPropagateStats(ClientContext &context, BoundAggreg NodeStatistics *node_stats) { if (child_stats[0] && node_stats && node_stats->has_max_cardinality) { auto &numeric_stats = (NumericStatistics &)*child_stats[0]; - if (numeric_stats.min.is_null || numeric_stats.max.is_null) { + if (numeric_stats.min.IsNull() || numeric_stats.max.IsNull()) { return nullptr; } auto internal_type = numeric_stats.min.type().InternalType(); @@ -74843,7 +74419,7 @@ unique_ptr BindApproxQuantile(ClientContext &context, AggregateFun Value quantile_val = ExpressionExecutor::EvaluateScalar(*arguments[1]); auto quantile = quantile_val.GetValue(); - if (quantile_val.is_null || quantile < 0 || quantile > 1) { + if (quantile_val.IsNull() || quantile < 0 || quantile > 1) { throw BinderException("APPROXIMATE QUANTILE can only take parameters in range [0, 1]"); } // remove the quantile argument so we can use the unary aggregate @@ -74863,7 +74439,7 @@ AggregateFunction GetApproximateQuantileAggregate(PhysicalType type) { auto fun = GetApproximateQuantileAggregateFunction(type); fun.bind = BindApproxQuantile; // temporarily push an argument so we can bind the actual quantile - fun.arguments.push_back(LogicalType::FLOAT); + fun.arguments.emplace_back(LogicalType::FLOAT); return fun; } @@ -75050,11 +74626,10 @@ struct ModeFunction { template static void Window(const INPUT_TYPE *data, const ValidityMask &dmask, FunctionData *bind_data_p, STATE *state, - const FrameBounds &frame, const FrameBounds &prev, Vector &result, idx_t rid) { + const FrameBounds &frame, const FrameBounds &prev, Vector &result, idx_t rid, idx_t bias) { auto rdata = FlatVector::GetData(result); auto &rmask = FlatVector::Validity(result); - const auto bias = MinValue(frame.first, prev.first); if (!state->frequency_map) { state->frequency_map = new unordered_map(); } @@ -75174,14 +74749,14 @@ unique_ptr BindModeDecimal(ClientContext &context, AggregateFuncti } void ModeFun::RegisterFunction(BuiltinFunctions &set) { - const vector TEMPORAL = {LogicalType::DATE, LogicalType::TIMESTAMP, LogicalType::TIME, - LogicalType::INTERVAL}; + const vector TEMPORAL = {LogicalType::DATE, LogicalType::TIMESTAMP, LogicalType::TIME, + LogicalType::TIMESTAMP_TZ, LogicalType::TIME_TZ, LogicalType::INTERVAL}; AggregateFunctionSet mode("mode"); mode.AddFunction(AggregateFunction({LogicalTypeId::DECIMAL}, LogicalTypeId::DECIMAL, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, BindModeDecimal)); - for (const auto &type : LogicalType::NUMERIC) { + for (const auto &type : LogicalType::Numeric()) { if (type.id() != LogicalTypeId::DECIMAL) { mode.AddFunction(GetModeAggregate(type)); } @@ -75701,11 +75276,11 @@ struct QuantileScalarOperation : public QuantileOperation { template static void Window(const INPUT_TYPE *data, const ValidityMask &dmask, FunctionData *bind_data_p, STATE *state, - const FrameBounds &frame, const FrameBounds &prev, Vector &result, idx_t ridx) { + const FrameBounds &frame, const FrameBounds &prev, Vector &result, idx_t ridx, idx_t bias) { auto rdata = FlatVector::GetData(result); auto &rmask = FlatVector::Validity(result); - QuantileNotNull not_null(dmask, MinValue(frame.first, prev.first)); + QuantileNotNull not_null(dmask, bias); // Lazily initialise frame state auto prev_pos = state->pos; @@ -75797,8 +75372,10 @@ AggregateFunction GetDiscreteQuantileAggregateFunction(const LogicalType &type) case LogicalTypeId::DATE: return GetTypedDiscreteQuantileAggregateFunction(type); case LogicalTypeId::TIMESTAMP: + case LogicalTypeId::TIMESTAMP_TZ: return GetTypedDiscreteQuantileAggregateFunction(type); case LogicalTypeId::TIME: + case LogicalTypeId::TIME_TZ: return GetTypedDiscreteQuantileAggregateFunction(type); case LogicalTypeId::INTERVAL: return GetTypedDiscreteQuantileAggregateFunction(type); @@ -75850,11 +75427,11 @@ struct QuantileListOperation : public QuantileOperation { template static void Window(const INPUT_TYPE *data, const ValidityMask &dmask, FunctionData *bind_data_p, STATE *state, - const FrameBounds &frame, const FrameBounds &prev, Vector &list, idx_t lidx) { + const FrameBounds &frame, const FrameBounds &prev, Vector &list, idx_t lidx, idx_t bias) { D_ASSERT(bind_data_p); auto bind_data = (QuantileBindData *)bind_data_p; - QuantileNotNull not_null(dmask, MinValue(frame.first, prev.first)); + QuantileNotNull not_null(dmask, bias); // Result is a constant LIST with a fixed length auto ldata = FlatVector::GetData(list); @@ -75986,8 +75563,10 @@ AggregateFunction GetDiscreteQuantileListAggregateFunction(const LogicalType &ty case LogicalTypeId::DATE: return GetTypedDiscreteQuantileListAggregateFunction(type); case LogicalTypeId::TIMESTAMP: + case LogicalTypeId::TIMESTAMP_TZ: return GetTypedDiscreteQuantileListAggregateFunction(type); case LogicalTypeId::TIME: + case LogicalTypeId::TIME_TZ: return GetTypedDiscreteQuantileListAggregateFunction(type); case LogicalTypeId::INTERVAL: return GetTypedDiscreteQuantileListAggregateFunction(type); @@ -76045,8 +75624,10 @@ AggregateFunction GetContinuousQuantileAggregateFunction(const LogicalType &type case LogicalTypeId::DATE: return GetTypedContinuousQuantileAggregateFunction(type, LogicalType::TIMESTAMP); case LogicalTypeId::TIMESTAMP: + case LogicalTypeId::TIMESTAMP_TZ: return GetTypedContinuousQuantileAggregateFunction(type, type); case LogicalTypeId::TIME: + case LogicalTypeId::TIME_TZ: return GetTypedContinuousQuantileAggregateFunction(type, type); default: @@ -76099,8 +75680,10 @@ AggregateFunction GetContinuousQuantileListAggregateFunction(const LogicalType & case LogicalTypeId::DATE: return GetTypedContinuousQuantileListAggregateFunction(type, LogicalType::TIMESTAMP); case LogicalTypeId::TIMESTAMP: + case LogicalTypeId::TIMESTAMP_TZ: return GetTypedContinuousQuantileListAggregateFunction(type, type); case LogicalTypeId::TIME: + case LogicalTypeId::TIME_TZ: return GetTypedContinuousQuantileListAggregateFunction(type, type); default: @@ -76203,11 +75786,11 @@ struct MedianAbsoluteDeviationOperation : public QuantileOperation { template static void Window(const INPUT_TYPE *data, const ValidityMask &dmask, FunctionData *bind_data_p, STATE *state, - const FrameBounds &frame, const FrameBounds &prev, Vector &result, idx_t ridx) { + const FrameBounds &frame, const FrameBounds &prev, Vector &result, idx_t ridx, idx_t bias) { auto rdata = FlatVector::GetData(result); auto &rmask = FlatVector::Validity(result); - QuantileNotNull not_null(dmask, MinValue(frame.first, prev.first)); + QuantileNotNull not_null(dmask, bias); // Lazily initialise frame state auto prev_pos = state->pos; @@ -76311,9 +75894,11 @@ AggregateFunction GetMedianAbsoluteDeviationAggregateFunction(const LogicalType return GetTypedMedianAbsoluteDeviationAggregateFunction(type, LogicalType::INTERVAL); case LogicalTypeId::TIMESTAMP: + case LogicalTypeId::TIMESTAMP_TZ: return GetTypedMedianAbsoluteDeviationAggregateFunction( type, LogicalType::INTERVAL); case LogicalTypeId::TIME: + case LogicalTypeId::TIME_TZ: return GetTypedMedianAbsoluteDeviationAggregateFunction(type, LogicalType::INTERVAL); @@ -76346,7 +75931,7 @@ unique_ptr BindMedianAbsoluteDeviationDecimal(ClientContext &conte static double CheckQuantile(const Value &quantile_val) { auto quantile = quantile_val.GetValue(); - if (quantile_val.is_null || quantile < 0 || quantile > 1) { + if (quantile_val.IsNull() || quantile < 0 || quantile > 1) { throw BinderException("QUANTILE can only take parameters in the range [0, 1]"); } @@ -76363,7 +75948,7 @@ unique_ptr BindQuantile(ClientContext &context, AggregateFunction if (quantile_val.type().id() != LogicalTypeId::LIST) { quantiles.push_back(CheckQuantile(quantile_val)); } else { - for (const auto &element_val : quantile_val.list_value) { + for (const auto &element_val : ListValue::GetChildren(quantile_val)) { quantiles.push_back(CheckQuantile(element_val)); } } @@ -76425,7 +76010,7 @@ AggregateFunction GetDiscreteQuantileAggregate(const LogicalType &type) { auto fun = GetDiscreteQuantileAggregateFunction(type); fun.bind = BindQuantile; // temporarily push an argument so we can bind the actual quantile - fun.arguments.push_back(LogicalType::DOUBLE); + fun.arguments.emplace_back(LogicalType::DOUBLE); return fun; } @@ -76442,7 +76027,7 @@ AggregateFunction GetContinuousQuantileAggregate(const LogicalType &type) { auto fun = GetContinuousQuantileAggregateFunction(type); fun.bind = BindQuantile; // temporarily push an argument so we can bind the actual quantile - fun.arguments.push_back(LogicalType::DOUBLE); + fun.arguments.emplace_back(LogicalType::DOUBLE); return fun; } @@ -76456,10 +76041,11 @@ AggregateFunction GetContinuousQuantileListAggregate(const LogicalType &type) { } void QuantileFun::RegisterFunction(BuiltinFunctions &set) { - const vector QUANTILES = {LogicalType::TINYINT, LogicalType::SMALLINT, LogicalType::INTEGER, - LogicalType::BIGINT, LogicalType::HUGEINT, LogicalType::FLOAT, - LogicalType::DOUBLE, LogicalType::DATE, LogicalType::TIMESTAMP, - LogicalType::TIME, LogicalType::INTERVAL, LogicalType::VARCHAR}; + const vector QUANTILES = {LogicalType::TINYINT, LogicalType::SMALLINT, LogicalType::INTEGER, + LogicalType::BIGINT, LogicalType::HUGEINT, LogicalType::FLOAT, + LogicalType::DOUBLE, LogicalType::DATE, LogicalType::TIMESTAMP, + LogicalType::TIME, LogicalType::TIMESTAMP_TZ, LogicalType::TIME_TZ, + LogicalType::INTERVAL, LogicalType::VARCHAR}; AggregateFunctionSet median("median"); median.AddFunction(AggregateFunction({LogicalTypeId::DECIMAL}, LogicalTypeId::DECIMAL, nullptr, nullptr, nullptr, @@ -76502,8 +76088,9 @@ void QuantileFun::RegisterFunction(BuiltinFunctions &set) { mad.AddFunction(AggregateFunction({LogicalTypeId::DECIMAL}, LogicalTypeId::DECIMAL, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, BindMedianAbsoluteDeviationDecimal)); - const vector MADS = {LogicalType::FLOAT, LogicalType::DOUBLE, LogicalType::DATE, - LogicalType::TIMESTAMP, LogicalType::TIME}; + const vector MADS = {LogicalType::FLOAT, LogicalType::DOUBLE, LogicalType::DATE, + LogicalType::TIMESTAMP, LogicalType::TIME, LogicalType::TIMESTAMP_TZ, + LogicalType::TIME_TZ}; for (const auto &type : MADS) { mad.AddFunction(GetMedianAbsoluteDeviationAggregateFunction(type)); } @@ -76696,7 +76283,7 @@ unique_ptr BindReservoirQuantile(ClientContext &context, Aggregate Value quantile_val = ExpressionExecutor::EvaluateScalar(*arguments[1]); auto quantile = quantile_val.GetValue(); - if (quantile_val.is_null || quantile < 0 || quantile > 1) { + if (quantile_val.IsNull() || quantile < 0 || quantile > 1) { throw BinderException("QUANTILE can only take parameters in range [0, 1]"); } if (arguments.size() <= 2) { @@ -76709,7 +76296,7 @@ unique_ptr BindReservoirQuantile(ClientContext &context, Aggregate Value sample_size_val = ExpressionExecutor::EvaluateScalar(*arguments[2]); auto sample_size = sample_size_val.GetValue(); - if (sample_size_val.is_null || sample_size <= 0) { + if (sample_size_val.IsNull() || sample_size <= 0) { throw BinderException("Percentage of the sample must be bigger than 0"); } @@ -76731,7 +76318,7 @@ AggregateFunction GetReservoirQuantileAggregate(PhysicalType type) { auto fun = GetReservoirQuantileAggregateFunction(type); fun.bind = BindReservoirQuantile; // temporarily push an argument so we can bind the actual quantile - fun.arguments.push_back(LogicalType::DOUBLE); + fun.arguments.emplace_back(LogicalType::DOUBLE); return fun; } @@ -76783,7 +76370,7 @@ namespace duckdb { struct VariableReturnBindData : public FunctionData { LogicalType stype; - explicit VariableReturnBindData(LogicalType stype) : stype(stype) { + explicit VariableReturnBindData(const LogicalType &stype_p) : stype(stype_p) { } unique_ptr Copy() override { @@ -77022,6 +76609,15 @@ unique_ptr HistogramBindFunction(ClientContext &context, Aggregate return make_unique(function.return_type); } +template +AggregateFunction GetHistogramFunction(const LogicalType &type) { + using STATE_TYPE = HistogramAggState; + return AggregateFunction("histogram", {type}, LogicalTypeId::MAP, AggregateFunction::StateSize, + AggregateFunction::StateInitialize, + HistogramUpdateFunction, HistogramCombineFunction, HistogramFinalize, nullptr, + HistogramBindFunction, AggregateFunction::StateDestroy); +} + AggregateFunction GetHistogramFunction(PhysicalType type) { switch (type) { case PhysicalType::UINT16: @@ -77104,12 +76700,8 @@ void HistogramFun::RegisterFunction(BuiltinFunctions &set) { fun.AddFunction(GetHistogramFunction(PhysicalType::FLOAT)); fun.AddFunction(GetHistogramFunction(PhysicalType::DOUBLE)); fun.AddFunction(GetHistogramFunction(PhysicalType::VARCHAR)); - fun.AddFunction(AggregateFunction("histogram", {LogicalType::TIMESTAMP}, LogicalTypeId::MAP, - AggregateFunction::StateSize>, - AggregateFunction::StateInitialize, HistogramFunction>, - HistogramUpdateFunction, HistogramCombineFunction, - HistogramFinalize, nullptr, HistogramBindFunction, - AggregateFunction::StateDestroy, HistogramFunction>)); + fun.AddFunction(GetHistogramFunction(LogicalType::TIMESTAMP)); + fun.AddFunction(GetHistogramFunction(LogicalType::TIMESTAMP_TZ)); set.AddFunction(fun); } @@ -78129,9 +77721,13 @@ static int64_t TargetTypeCost(const LogicalType &type) { case LogicalTypeId::TIMESTAMP: return 120; case LogicalTypeId::VARCHAR: - return 199; + return 149; case LogicalTypeId::DECIMAL: return 104; + case LogicalTypeId::STRUCT: + case LogicalTypeId::MAP: + case LogicalTypeId::LIST: + return 160; default: return 110; } @@ -78396,6 +77992,11 @@ struct RLEFun { static bool TypeIsSupported(PhysicalType type); }; +struct BitpackingFun { + static CompressionFunction GetFunction(PhysicalType type); + static bool TypeIsSupported(PhysicalType type); +}; + } // namespace duckdb @@ -78415,6 +78016,7 @@ static DefaultCompressionMethod internal_compression_methods[] = { {CompressionType::COMPRESSION_CONSTANT, ConstantFun::GetFunction, ConstantFun::TypeIsSupported}, {CompressionType::COMPRESSION_UNCOMPRESSED, UncompressedFun::GetFunction, UncompressedFun::TypeIsSupported}, {CompressionType::COMPRESSION_RLE, RLEFun::GetFunction, RLEFun::TypeIsSupported}, + {CompressionType::COMPRESSION_BITPACKING, BitpackingFun::GetFunction, BitpackingFun::TypeIsSupported}, {CompressionType::COMPRESSION_AUTO, nullptr, nullptr}}; static CompressionFunction *FindCompressionFunction(CompressionFunctionSet &set, CompressionType type, @@ -78463,6 +78065,7 @@ vector DBConfig::GetCompressionFunctions(PhysicalType dat vector result; TryLoadCompression(*this, result, CompressionType::COMPRESSION_UNCOMPRESSED, data_type); TryLoadCompression(*this, result, CompressionType::COMPRESSION_RLE, data_type); + TryLoadCompression(*this, result, CompressionType::COMPRESSION_BITPACKING, data_type); return result; } @@ -78502,6 +78105,76 @@ CompressionFunction *DBConfig::GetCompressionFunction(CompressionType type, Phys namespace duckdb { +FunctionData::~FunctionData() { +} + +unique_ptr FunctionData::Copy() { + throw InternalException("Unimplemented copy for FunctionData"); +} + +bool FunctionData::Equals(FunctionData &other) { + return true; +} + +bool FunctionData::Equals(FunctionData *left, FunctionData *right) { + if (left == right) { + return true; + } + if (!left || !right) { + return false; + } + return left->Equals(*right); +} + +Function::Function(string name_p) : name(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)) { +} + +SimpleFunction::~SimpleFunction() { +} + +string SimpleFunction::ToString() { + return Function::CallToString(name, arguments); +} + +bool SimpleFunction::HasVarArgs() const { + return varargs.id() != LogicalTypeId::INVALID; +} + +SimpleNamedParameterFunction::SimpleNamedParameterFunction(string name_p, vector arguments_p, + LogicalType varargs_p) + : SimpleFunction(move(name_p), move(arguments_p), move(varargs_p)) { +} + +SimpleNamedParameterFunction::~SimpleNamedParameterFunction() { +} + +string SimpleNamedParameterFunction::ToString() { + return Function::CallToString(name, arguments, named_parameters); +} + +bool SimpleNamedParameterFunction::HasNamedParameters() { + return !named_parameters.empty(); +} + +BaseScalarFunction::BaseScalarFunction(string name_p, vector arguments_p, LogicalType return_type_p, + bool has_side_effects, LogicalType varargs_p) + : SimpleFunction(move(name_p), move(arguments_p), move(varargs_p)), return_type(move(return_type_p)), + has_side_effects(has_side_effects) { +} + +BaseScalarFunction::~BaseScalarFunction() { +} + +string BaseScalarFunction::ToString() { + return Function::CallToString(name, arguments, return_type); +} + // add your initializer for new functions here void BuiltinFunctions::Initialize() { RegisterSQLiteFunctions(); @@ -78516,6 +78189,7 @@ void BuiltinFunctions::Initialize() { RegisterRegressiveAggregates(); RegisterDateFunctions(); + RegisterEnumFunctions(); RegisterGenericFunctions(); RegisterMathFunctions(); RegisterOperators(); @@ -78616,7 +78290,7 @@ string Function::CallToString(const string &name, const vector &arg } string Function::CallToString(const string &name, const vector &arguments, - const unordered_map &named_parameters) { + const named_parameter_type_map_t &named_parameters) { vector input_arguments; input_arguments.reserve(arguments.size() + named_parameters.size()); for (auto &arg : arguments) { @@ -78682,7 +78356,7 @@ static int64_t BindFunctionCost(SimpleFunction &func, vector &argum template static idx_t BindFunctionFromArguments(const string &name, vector &functions, vector &arguments, string &error) { - idx_t best_function = INVALID_INDEX; + idx_t best_function = DConstants::INVALID_INDEX; int64_t lowest_cost = NumericLimits::Maximum(); vector conflicting_functions; for (idx_t f_idx = 0; f_idx < functions.size(); f_idx++) { @@ -78718,9 +78392,9 @@ static idx_t BindFunctionFromArguments(const string &name, vector &functions, StringUtil::Format("Could not choose a best candidate function for the function call \"%s\". In order to " "select one, please add explicit type casts.\n\tCandidate functions:\n%s", call_str, candidate_str); - return INVALID_INDEX; + return DConstants::INVALID_INDEX; } - if (best_function == INVALID_INDEX) { + if (best_function == DConstants::INVALID_INDEX) { // no matching function was found, throw an error string call_str = Function::CallToString(name, arguments); string candidate_str = ""; @@ -78730,7 +78404,7 @@ static idx_t BindFunctionFromArguments(const string &name, vector &functions, error = StringUtil::Format("No function matches the given name and argument types '%s'. You might need to add " "explicit type casts.\n\tCandidate functions:\n%s", call_str, candidate_str); - return INVALID_INDEX; + return DConstants::INVALID_INDEX; } return best_function; } @@ -78756,7 +78430,7 @@ idx_t Function::BindFunction(const string &name, vector &functio types.push_back(value.type()); } idx_t entry = BindFunctionFromArguments(name, functions, types, error); - if (entry == INVALID_INDEX) { + if (entry == DConstants::INVALID_INDEX) { throw BinderException(error); } auto &candidate_function = functions[entry]; @@ -78850,7 +78524,7 @@ unique_ptr ScalarFunction::BindScalarFunction(ClientCon string &error, bool is_operator) { // bind the function idx_t best_function = Function::BindFunction(func.name, func.functions, children, error); - if (best_function == INVALID_INDEX) { + if (best_function == DConstants::INVALID_INDEX) { return nullptr; } // found a matching function! @@ -78927,7 +78601,8 @@ string MacroFunction::ValidateArguments(MacroCatalogEntry ¯o_func, FunctionE } else if (defaults.find(arg->alias) != defaults.end()) { return StringUtil::Format("Duplicate default parameters %s!", arg->alias); } - defaults[arg->alias] = move(arg); + auto alias = arg->alias; + defaults[alias] = move(arg); } else if (!defaults.empty()) { return "Positional parameters cannot come after parameters with a default value!"; } else { @@ -78943,7 +78618,7 @@ string MacroFunction::ValidateArguments(MacroCatalogEntry ¯o_func, FunctionE error = StringUtil::Format( "Macro function '%s(%s)' requires ", macro_func.name, StringUtil::Join(parameters, parameters.size(), ", ", [](const unique_ptr &p) { - return ((ColumnRefExpression &)*p).column_name; + return ((ColumnRefExpression &)*p).column_names[0]; })); error += parameters.size() == 1 ? "a single positional argument" : StringUtil::Format("%i positional arguments", parameters.size()); @@ -79016,144 +78691,55 @@ struct PragmaFunctions { namespace duckdb { static void PragmaEnableProfilingStatement(ClientContext &context, const FunctionParameters ¶meters) { - context.profiler->automatic_print_format = ProfilerPrintFormat::QUERY_TREE; - context.profiler->Enable(); -} - -static void PragmaSetProfilingModeStatement(ClientContext &context, const FunctionParameters ¶meters) { - // this is either profiling_mode = standard, or profiling_mode = detailed - string mode = StringUtil::Lower(parameters.values[0].ToString()); - if (mode == "standard") { - context.profiler->Enable(); - } else if (mode == "detailed") { - context.profiler->DetailedEnable(); - } else { - throw ParserException("Unrecognized print format %s, supported formats: [standard, detailed]", mode); - } -} - -static void PragmaSetProfilerHistorySize(ClientContext &context, const FunctionParameters ¶meters) { - auto size = parameters.values[0].GetValue(); - if (size <= 0) { - throw ParserException("Size should be larger than 0"); - } - context.query_profiler_history->SetProfilerHistorySize(size); -} - -static void PragmaEnableProfilingAssignment(ClientContext &context, const FunctionParameters ¶meters) { - // this is either enable_profiling = json, or enable_profiling = query_tree - string assignment = parameters.values[0].ToString(); - if (assignment == "json") { - context.profiler->automatic_print_format = ProfilerPrintFormat::JSON; - } else if (assignment == "query_tree") { - context.profiler->automatic_print_format = ProfilerPrintFormat::QUERY_TREE; - } else if (assignment == "query_tree_optimizer") { - context.profiler->automatic_print_format = ProfilerPrintFormat::QUERY_TREE_OPTIMIZER; - } else { - throw ParserException( - "Unrecognized print format %s, supported formats: [json, query_tree, query_tree_optimizer]", assignment); - } - context.profiler->Enable(); + auto &config = ClientConfig::GetConfig(context); + config.profiler_print_format = ProfilerPrintFormat::QUERY_TREE; + config.enable_profiler = true; } void RegisterEnableProfiling(BuiltinFunctions &set) { vector functions; functions.push_back(PragmaFunction::PragmaStatement(string(), PragmaEnableProfilingStatement)); - functions.push_back( - PragmaFunction::PragmaAssignment(string(), PragmaEnableProfilingAssignment, LogicalType::VARCHAR)); set.AddFunction("enable_profile", functions); set.AddFunction("enable_profiling", functions); } static void PragmaDisableProfiling(ClientContext &context, const FunctionParameters ¶meters) { - context.profiler->Disable(); - context.profiler->automatic_print_format = ProfilerPrintFormat::NONE; -} - -static void PragmaProfileOutput(ClientContext &context, const FunctionParameters ¶meters) { - context.profiler->save_location = parameters.values[0].ToString(); -} - -static void PragmaMemoryLimit(ClientContext &context, const FunctionParameters ¶meters) { - idx_t new_limit = DBConfig::ParseMemoryLimit(parameters.values[0].ToString()); - // set the new limit in the buffer manager - BufferManager::GetBufferManager(context).SetLimit(new_limit); -} - -static void PragmaCollation(ClientContext &context, const FunctionParameters ¶meters) { - auto collation_param = StringUtil::Lower(parameters.values[0].ToString()); - // bind the collation to verify that it exists - ExpressionBinder::TestCollation(context, collation_param); - auto &config = DBConfig::GetConfig(context); - config.collation = collation_param; -} - -static void PragmaNullOrder(ClientContext &context, const FunctionParameters ¶meters) { - auto &config = DBConfig::GetConfig(context); - string new_null_order = StringUtil::Lower(parameters.values[0].ToString()); - if (new_null_order == "nulls first" || new_null_order == "null first" || new_null_order == "first") { - config.default_null_order = OrderByNullType::NULLS_FIRST; - } else if (new_null_order == "nulls last" || new_null_order == "null last" || new_null_order == "last") { - config.default_null_order = OrderByNullType::NULLS_LAST; - } else { - throw ParserException("Unrecognized null order '%s', expected either NULLS FIRST or NULLS LAST", - new_null_order); - } -} - -static void PragmaDefaultOrder(ClientContext &context, const FunctionParameters ¶meters) { - auto &config = DBConfig::GetConfig(context); - string new_order = StringUtil::Lower(parameters.values[0].ToString()); - if (new_order == "ascending" || new_order == "asc") { - config.default_order_type = OrderType::ASCENDING; - } else if (new_order == "descending" || new_order == "desc") { - config.default_order_type = OrderType::DESCENDING; - } else { - throw ParserException("Unrecognized order order '%s', expected either ASCENDING or DESCENDING", new_order); - } -} - -static void PragmaSetThreads(ClientContext &context, const FunctionParameters ¶meters) { - auto nr_threads = parameters.values[0].GetValue(); - TaskScheduler::GetScheduler(context).SetThreads(nr_threads); + auto &config = ClientConfig::GetConfig(context); + config.enable_profiler = false; + config.profiler_print_format = ProfilerPrintFormat::NONE; } static void PragmaEnableProgressBar(ClientContext &context, const FunctionParameters ¶meters) { - context.enable_progress_bar = true; -} - -static void PragmaSetProgressBarWaitTime(ClientContext &context, const FunctionParameters ¶meters) { - context.wait_time = parameters.values[0].GetValue(); - context.enable_progress_bar = true; + ClientConfig::GetConfig(context).enable_progress_bar = true; } static void PragmaDisableProgressBar(ClientContext &context, const FunctionParameters ¶meters) { - context.enable_progress_bar = false; + ClientConfig::GetConfig(context).enable_progress_bar = false; } static void PragmaEnablePrintProgressBar(ClientContext &context, const FunctionParameters ¶meters) { - context.print_progress_bar = true; + ClientConfig::GetConfig(context).print_progress_bar = true; } static void PragmaDisablePrintProgressBar(ClientContext &context, const FunctionParameters ¶meters) { - context.print_progress_bar = false; + ClientConfig::GetConfig(context).print_progress_bar = false; } static void PragmaEnableVerification(ClientContext &context, const FunctionParameters ¶meters) { - context.query_verification_enabled = true; + ClientConfig::GetConfig(context).query_verification_enabled = true; } static void PragmaDisableVerification(ClientContext &context, const FunctionParameters ¶meters) { - context.query_verification_enabled = false; + ClientConfig::GetConfig(context).query_verification_enabled = false; } static void PragmaEnableForceParallelism(ClientContext &context, const FunctionParameters ¶meters) { - context.verify_parallelism = true; + ClientConfig::GetConfig(context).verify_parallelism = true; } static void PragmaEnableForceIndexJoin(ClientContext &context, const FunctionParameters ¶meters) { - context.force_index_join = true; + ClientConfig::GetConfig(context).force_index_join = true; } static void PragmaForceCheckpoint(ClientContext &context, const FunctionParameters ¶meters) { @@ -79161,15 +78747,7 @@ static void PragmaForceCheckpoint(ClientContext &context, const FunctionParamete } static void PragmaDisableForceParallelism(ClientContext &context, const FunctionParameters ¶meters) { - context.verify_parallelism = false; -} - -static void PragmaEnableForceExternal(ClientContext &context, const FunctionParameters ¶meters) { - context.force_external = true; -} - -static void PragmaDisableForceExternal(ClientContext &context, const FunctionParameters ¶meters) { - context.force_external = false; + ClientConfig::GetConfig(context).verify_parallelism = false; } static void PragmaEnableObjectCache(ClientContext &context, const FunctionParameters ¶meters) { @@ -79188,156 +78766,32 @@ static void PragmaDisableCheckpointOnShutdown(ClientContext &context, const Func DBConfig::GetConfig(context).checkpoint_on_shutdown = false; } -static void PragmaLogQueryPath(ClientContext &context, const FunctionParameters ¶meters) { - auto str_val = parameters.values[0].ToString(); - if (str_val.empty()) { - // empty path: clean up query writer - context.log_query_writer = nullptr; - } else { - context.log_query_writer = - make_unique(FileSystem::GetFileSystem(context), str_val, - BufferedFileWriter::DEFAULT_OPEN_FLAGS, context.file_opener.get()); - } -} - -static void PragmaExplainOutput(ClientContext &context, const FunctionParameters ¶meters) { - string val = StringUtil::Lower(parameters.values[0].ToString()); - if (val == "all") { - context.explain_output_type = ExplainOutputType::ALL; - } else if (val == "optimized_only") { - context.explain_output_type = ExplainOutputType::OPTIMIZED_ONLY; - } else if (val == "physical_only") { - context.explain_output_type = ExplainOutputType::PHYSICAL_ONLY; - } else { - throw ParserException("Unrecognized output type '%s', expected either ALL, OPTIMIZED_ONLY or PHYSICAL_ONLY", - val); - } -} - static void PragmaEnableOptimizer(ClientContext &context, const FunctionParameters ¶meters) { - context.enable_optimizer = true; + ClientConfig::GetConfig(context).enable_optimizer = true; } static void PragmaDisableOptimizer(ClientContext &context, const FunctionParameters ¶meters) { - context.enable_optimizer = false; -} - -static void PragmaPerfectHashThreshold(ClientContext &context, const FunctionParameters ¶meters) { - auto bits = parameters.values[0].GetValue(); - ; - if (bits < 0 || bits > 32) { - throw ParserException("Perfect HT threshold out of range: should be within range 0 - 32"); - } - context.perfect_ht_threshold = bits; -} - -static void PragmaAutoCheckpointThreshold(ClientContext &context, const FunctionParameters ¶meters) { - idx_t new_limit = DBConfig::ParseMemoryLimit(parameters.values[0].ToString()); - DBConfig::GetConfig(context).checkpoint_wal_size = new_limit; -} - -static void PragmaDebugCheckpointAbort(ClientContext &context, const FunctionParameters ¶meters) { - auto checkpoint_abort = StringUtil::Lower(parameters.values[0].ToString()); - auto &config = DBConfig::GetConfig(context); - if (checkpoint_abort == "none") { - config.checkpoint_abort = CheckpointAbort::NO_ABORT; - } else if (checkpoint_abort == "before_truncate") { - config.checkpoint_abort = CheckpointAbort::DEBUG_ABORT_BEFORE_TRUNCATE; - } else if (checkpoint_abort == "before_header") { - config.checkpoint_abort = CheckpointAbort::DEBUG_ABORT_BEFORE_HEADER; - } else if (checkpoint_abort == "after_free_list_write") { - config.checkpoint_abort = CheckpointAbort::DEBUG_ABORT_AFTER_FREE_LIST_WRITE; - } else { - throw ParserException( - "Unrecognized option for PRAGMA debug_checkpoint_abort, expected none, before_truncate or before_header"); - } -} - -static void PragmaSetTempDirectory(ClientContext &context, const FunctionParameters ¶meters) { - auto &buffer_manager = BufferManager::GetBufferManager(context); - buffer_manager.SetTemporaryDirectory(parameters.values[0].ToString()); -} - -static void PragmaForceCompression(ClientContext &context, const FunctionParameters ¶meters) { - auto compression = StringUtil::Lower(parameters.values[0].ToString()); - auto &config = DBConfig::GetConfig(context); - if (compression == "none") { - config.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"); - } - config.force_compression = compression_type; - } -} - -static void PragmaDebugManyFreeListBlocks(ClientContext &context, const FunctionParameters ¶meters) { - auto &config = DBConfig::GetConfig(context); - config.debug_many_free_list_blocks = true; -} - -static void PragmaDebugWindowMode(ClientContext &context, const FunctionParameters ¶meters) { - auto param = StringUtil::Lower(parameters.values[0].ToString()); - auto &config = DBConfig::GetConfig(context); - if (param == "window") { - config.window_mode = WindowAggregationMode::WINDOW; - } else if (param == "combine") { - config.window_mode = WindowAggregationMode::COMBINE; - } else if (param == "separate") { - config.window_mode = WindowAggregationMode::SEPARATE; - } else { - throw ParserException("Unrecognized option for PRAGMA debug_window_mode, expected window, combine or separate"); - } + ClientConfig::GetConfig(context).enable_optimizer = false; } void PragmaFunctions::RegisterFunction(BuiltinFunctions &set) { RegisterEnableProfiling(set); - set.AddFunction( - PragmaFunction::PragmaAssignment("profiling_mode", PragmaSetProfilingModeStatement, LogicalType::VARCHAR)); - set.AddFunction(PragmaFunction::PragmaAssignment("set_profiler_history_size", PragmaSetProfilerHistorySize, - LogicalType::BIGINT)); - set.AddFunction(PragmaFunction::PragmaStatement("disable_profile", PragmaDisableProfiling)); set.AddFunction(PragmaFunction::PragmaStatement("disable_profiling", PragmaDisableProfiling)); - set.AddFunction(PragmaFunction::PragmaAssignment("profile_output", PragmaProfileOutput, LogicalType::VARCHAR)); - set.AddFunction(PragmaFunction::PragmaAssignment("profiling_output", PragmaProfileOutput, LogicalType::VARCHAR)); - - set.AddFunction(PragmaFunction::PragmaAssignment("memory_limit", PragmaMemoryLimit, LogicalType::VARCHAR)); - - set.AddFunction(PragmaFunction::PragmaAssignment("collation", PragmaCollation, LogicalType::VARCHAR)); - set.AddFunction(PragmaFunction::PragmaAssignment("default_collation", PragmaCollation, LogicalType::VARCHAR)); - - set.AddFunction(PragmaFunction::PragmaAssignment("null_order", PragmaNullOrder, LogicalType::VARCHAR)); - set.AddFunction(PragmaFunction::PragmaAssignment("default_null_order", PragmaNullOrder, LogicalType::VARCHAR)); - - set.AddFunction(PragmaFunction::PragmaAssignment("order", PragmaDefaultOrder, LogicalType::VARCHAR)); - set.AddFunction(PragmaFunction::PragmaAssignment("default_order", PragmaDefaultOrder, LogicalType::VARCHAR)); - - set.AddFunction(PragmaFunction::PragmaAssignment("threads", PragmaSetThreads, LogicalType::BIGINT)); - set.AddFunction(PragmaFunction::PragmaAssignment("worker_threads", PragmaSetThreads, LogicalType::BIGINT)); - set.AddFunction(PragmaFunction::PragmaStatement("enable_verification", PragmaEnableVerification)); set.AddFunction(PragmaFunction::PragmaStatement("disable_verification", PragmaDisableVerification)); set.AddFunction(PragmaFunction::PragmaStatement("verify_parallelism", PragmaEnableForceParallelism)); set.AddFunction(PragmaFunction::PragmaStatement("disable_verify_parallelism", PragmaDisableForceParallelism)); - set.AddFunction(PragmaFunction::PragmaStatement("force_external", PragmaEnableForceExternal)); - set.AddFunction(PragmaFunction::PragmaStatement("disable_force_external", PragmaDisableForceExternal)); - set.AddFunction(PragmaFunction::PragmaStatement("enable_object_cache", PragmaEnableObjectCache)); set.AddFunction(PragmaFunction::PragmaStatement("disable_object_cache", PragmaDisableObjectCache)); set.AddFunction(PragmaFunction::PragmaStatement("enable_optimizer", PragmaEnableOptimizer)); set.AddFunction(PragmaFunction::PragmaStatement("disable_optimizer", PragmaDisableOptimizer)); - set.AddFunction(PragmaFunction::PragmaAssignment("log_query_path", PragmaLogQueryPath, LogicalType::VARCHAR)); - set.AddFunction(PragmaFunction::PragmaAssignment("explain_output", PragmaExplainOutput, LogicalType::VARCHAR)); - set.AddFunction(PragmaFunction::PragmaStatement("force_index_join", PragmaEnableForceIndexJoin)); set.AddFunction(PragmaFunction::PragmaStatement("force_checkpoint", PragmaForceCheckpoint)); @@ -79347,32 +78801,9 @@ void PragmaFunctions::RegisterFunction(BuiltinFunctions &set) { set.AddFunction(PragmaFunction::PragmaStatement("enable_print_progress_bar", PragmaEnablePrintProgressBar)); set.AddFunction(PragmaFunction::PragmaStatement("disable_print_progress_bar", PragmaDisablePrintProgressBar)); - set.AddFunction( - PragmaFunction::PragmaAssignment("set_progress_bar_time", PragmaSetProgressBarWaitTime, LogicalType::INTEGER)); - set.AddFunction(PragmaFunction::PragmaStatement("enable_checkpoint_on_shutdown", PragmaEnableCheckpointOnShutdown)); set.AddFunction( PragmaFunction::PragmaStatement("disable_checkpoint_on_shutdown", PragmaDisableCheckpointOnShutdown)); - - set.AddFunction( - PragmaFunction::PragmaAssignment("perfect_ht_threshold", PragmaPerfectHashThreshold, LogicalType::INTEGER)); - - set.AddFunction( - PragmaFunction::PragmaAssignment("wal_autocheckpoint", PragmaAutoCheckpointThreshold, LogicalType::VARCHAR)); - set.AddFunction( - PragmaFunction::PragmaAssignment("checkpoint_threshold", PragmaAutoCheckpointThreshold, LogicalType::VARCHAR)); - - set.AddFunction( - PragmaFunction::PragmaAssignment("debug_checkpoint_abort", PragmaDebugCheckpointAbort, LogicalType::VARCHAR)); - - set.AddFunction(PragmaFunction::PragmaAssignment("temp_directory", PragmaSetTempDirectory, LogicalType::VARCHAR)); - - set.AddFunction( - PragmaFunction::PragmaAssignment("force_compression", PragmaForceCompression, LogicalType::VARCHAR)); - - set.AddFunction(PragmaFunction::PragmaStatement("debug_many_free_list_blocks", PragmaDebugManyFreeListBlocks)); - - set.AddFunction(PragmaFunction::PragmaAssignment("debug_window_mode", PragmaDebugWindowMode, LogicalType::VARCHAR)); } } // namespace duckdb @@ -79380,6 +78811,7 @@ void PragmaFunctions::RegisterFunction(BuiltinFunctions &set) { + namespace duckdb { string PragmaTableInfo(ClientContext &context, const FunctionParameters ¶meters) { @@ -79420,6 +78852,10 @@ string PragmaVersion(ClientContext &context, const FunctionParameters ¶meter } string PragmaImportDatabase(ClientContext &context, const FunctionParameters ¶meters) { + auto &config = DBConfig::GetConfig(context); + if (!config.enable_external_access) { + throw PermissionException("Import is disabled through configuration"); + } auto &fs = FileSystem::GetFileSystem(context); auto *opener = FileSystem::GetFileOpener(context); @@ -79493,22 +78929,10 @@ PragmaFunction PragmaFunction::PragmaStatement(const string &name, pragma_functi return PragmaFunction(name, PragmaType::PRAGMA_STATEMENT, nullptr, function, move(types), LogicalType::INVALID); } -PragmaFunction PragmaFunction::PragmaAssignment(const string &name, pragma_query_t query, LogicalType type) { - vector types {move(type)}; - return PragmaFunction(name, PragmaType::PRAGMA_ASSIGNMENT, query, nullptr, move(types), LogicalType::INVALID); -} - -PragmaFunction PragmaFunction::PragmaAssignment(const string &name, pragma_function_t function, LogicalType type) { - vector types {move(type)}; - return PragmaFunction(name, PragmaType::PRAGMA_ASSIGNMENT, nullptr, function, move(types), LogicalType::INVALID); -} - string PragmaFunction::ToString() { switch (type) { case PragmaType::PRAGMA_STATEMENT: return StringUtil::Format("PRAGMA %s", name); - case PragmaType::PRAGMA_ASSIGNMENT: - return StringUtil::Format("PRAGMA %s=%s", name, arguments[0].ToString()); case PragmaType::PRAGMA_CALL: { return StringUtil::Format("PRAGMA %s", SimpleNamedParameterFunction::ToString()); } @@ -79579,10 +79003,8 @@ static void Base64DecodeFunction(DataChunk &args, ExpressionState &state, Vector void Base64Fun::RegisterFunction(BuiltinFunctions &set) { // base64 encode - ScalarFunction to_base64("base64", {LogicalType::BLOB}, LogicalType::VARCHAR, Base64EncodeFunction); - set.AddFunction(to_base64); - to_base64.name = "to_base64"; // mysql alias - set.AddFunction(to_base64); + ScalarFunction to_base64({LogicalType::BLOB}, LogicalType::VARCHAR, Base64EncodeFunction); + set.AddFunction({"base64", "to_base64"}, to_base64); // to_base64 is a mysql alias set.AddFunction(ScalarFunction("from_base64", {LogicalType::VARCHAR}, LogicalType::BLOB, Base64DecodeFunction)); } @@ -79677,6 +79099,10 @@ struct EpochFun { static void RegisterFunction(BuiltinFunctions &set); }; +struct MakeDateFun { + static void RegisterFunction(BuiltinFunctions &set); +}; + struct StrfTimeFun { static void RegisterFunction(BuiltinFunctions &set); }; @@ -79878,6 +79304,13 @@ struct DateDiff { } }; + struct ISOYearOperator { + template + static inline TR Operation(TA startdate, TB enddate) { + return Date::ExtractISOYearNumber(enddate) - Date::ExtractISOYearNumber(startdate); + } + }; + struct MicrosecondsOperator { template static inline TR Operation(TA startdate, TB enddate) { @@ -79963,6 +79396,12 @@ int64_t DateDiff::WeekOperator::Operation(timestamp_t startdate, timestamp_t end return WeekOperator::Operation(Timestamp::GetDate(startdate), Timestamp::GetDate(enddate)); } +template <> +int64_t DateDiff::ISOYearOperator::Operation(timestamp_t startdate, timestamp_t enddate) { + return ISOYearOperator::Operation(Timestamp::GetDate(startdate), + Timestamp::GetDate(enddate)); +} + template <> int64_t DateDiff::MicrosecondsOperator::Operation(timestamp_t startdate, timestamp_t enddate) { return Timestamp::GetEpochMicroSeconds(enddate) - Timestamp::GetEpochMicroSeconds(startdate); @@ -80031,6 +79470,11 @@ int64_t DateDiff::WeekOperator::Operation(dtime_t startdate, dtime_t enddate) { throw NotImplementedException("\"time\" units \"week\" not recognized"); } +template <> +int64_t DateDiff::ISOYearOperator::Operation(dtime_t startdate, dtime_t enddate) { + throw NotImplementedException("\"time\" units \"isoyear\" not recognized"); +} + template <> int64_t DateDiff::MicrosecondsOperator::Operation(dtime_t startdate, dtime_t enddate) { return enddate.micros - startdate.micros; @@ -80079,6 +79523,8 @@ static int64_t DifferenceDates(DatePartSpecifier type, TA startdate, TB enddate) case DatePartSpecifier::WEEK: case DatePartSpecifier::YEARWEEK: return DateDiff::WeekOperator::template Operation(startdate, enddate); + case DatePartSpecifier::ISOYEAR: + return DateDiff::ISOYearOperator::template Operation(startdate, enddate); case DatePartSpecifier::MICROSECONDS: return DateDiff::MicrosecondsOperator::template Operation(startdate, enddate); case DatePartSpecifier::MILLISECONDS: @@ -80133,6 +79579,9 @@ static void DateDiffBinaryExecutor(DatePartSpecifier type, Vector &left, Vector case DatePartSpecifier::YEARWEEK: BinaryExecutor::ExecuteStandard(left, right, result, count); break; + case DatePartSpecifier::ISOYEAR: + BinaryExecutor::ExecuteStandard(left, right, result, count); + break; case DatePartSpecifier::MICROSECONDS: BinaryExecutor::ExecuteStandard(left, right, result, count); break; @@ -80200,6 +79649,10 @@ void DateDiffFun::RegisterFunction(BuiltinFunctions &set) { + + + + namespace duckdb { bool TryGetDatePartSpecifier(const string &specifier_p, DatePartSpecifier &result) { @@ -80208,13 +79661,13 @@ bool TryGetDatePartSpecifier(const string &specifier_p, DatePartSpecifier &resul result = DatePartSpecifier::YEAR; } else if (specifier == "month" || specifier == "mon" || specifier == "months" || specifier == "mons") { result = DatePartSpecifier::MONTH; - } else if (specifier == "day" || specifier == "days" || specifier == "d") { + } else if (specifier == "day" || specifier == "days" || specifier == "d" || specifier == "dayofmonth") { result = DatePartSpecifier::DAY; } else if (specifier == "decade" || specifier == "decades") { result = DatePartSpecifier::DECADE; } else if (specifier == "century" || specifier == "centuries") { result = DatePartSpecifier::CENTURY; - } else if (specifier == "millennium" || specifier == "millenia") { + } else if (specifier == "millennium" || specifier == "millennia" || specifier == "millenium") { result = DatePartSpecifier::MILLENNIUM; } else if (specifier == "microseconds" || specifier == "microsecond") { result = DatePartSpecifier::MICROSECONDS; @@ -80230,14 +79683,14 @@ bool TryGetDatePartSpecifier(const string &specifier_p, DatePartSpecifier &resul } else if (specifier == "epoch") { // seconds since 1970-01-01 result = DatePartSpecifier::EPOCH; - } else if (specifier == "dow") { + } else if (specifier == "dow" || specifier == "dayofweek" || specifier == "weekday") { // day of the week (Sunday = 0, Saturday = 6) result = DatePartSpecifier::DOW; } else if (specifier == "isodow") { // isodow (Monday = 1, Sunday = 7) result = DatePartSpecifier::ISODOW; - } else if (specifier == "week" || specifier == "weeks" || specifier == "w") { - // week number + } else if (specifier == "week" || specifier == "weeks" || specifier == "w" || specifier == "weekofyear") { + // ISO week number result = DatePartSpecifier::WEEK; } else if (specifier == "doy" || specifier == "dayofyear") { // day of the year (1-365/366) @@ -80246,8 +79699,19 @@ bool TryGetDatePartSpecifier(const string &specifier_p, DatePartSpecifier &resul // quarter of the year (1-4) result = DatePartSpecifier::QUARTER; } else if (specifier == "yearweek") { - // Combined year and week YYYYWW + // Combined isoyear and isoweek YYYYWW result = DatePartSpecifier::YEARWEEK; + } else if (specifier == "isoyear") { + // ISO year (first week of the year may be in previous year) + result = DatePartSpecifier::ISOYEAR; + } else if (specifier == "era") { + result = DatePartSpecifier::ERA; + } else if (specifier == "timezone") { + result = DatePartSpecifier::TIMEZONE; + } else if (specifier == "timezone_hour") { + result = DatePartSpecifier::TIMEZONE_HOUR; + } else if (specifier == "timezone_minute") { + result = DatePartSpecifier::TIMEZONE_MINUTE; } else { return false; } @@ -80262,6 +79726,76 @@ DatePartSpecifier GetDatePartSpecifier(const string &specifier) { return result; } +DatePartSpecifier GetDateTypePartSpecifier(const string &specifier, LogicalType &type) { + const auto part = GetDatePartSpecifier(specifier); + switch (type.id()) { + case LogicalType::TIMESTAMP: + case LogicalType::TIMESTAMP_TZ: + return part; + case LogicalType::DATE: + switch (part) { + case DatePartSpecifier::YEAR: + case DatePartSpecifier::MONTH: + case DatePartSpecifier::DAY: + case DatePartSpecifier::DECADE: + case DatePartSpecifier::CENTURY: + case DatePartSpecifier::MILLENNIUM: + case DatePartSpecifier::DOW: + case DatePartSpecifier::ISODOW: + case DatePartSpecifier::ISOYEAR: + case DatePartSpecifier::WEEK: + case DatePartSpecifier::QUARTER: + case DatePartSpecifier::DOY: + case DatePartSpecifier::YEARWEEK: + case DatePartSpecifier::ERA: + return part; + default: + break; + } + break; + case LogicalType::TIME: + switch (part) { + case DatePartSpecifier::MICROSECONDS: + case DatePartSpecifier::MILLISECONDS: + case DatePartSpecifier::SECOND: + case DatePartSpecifier::MINUTE: + case DatePartSpecifier::HOUR: + case DatePartSpecifier::EPOCH: + case DatePartSpecifier::TIMEZONE: + case DatePartSpecifier::TIMEZONE_HOUR: + case DatePartSpecifier::TIMEZONE_MINUTE: + return part; + default: + break; + } + break; + case LogicalType::INTERVAL: + switch (part) { + case DatePartSpecifier::YEAR: + case DatePartSpecifier::MONTH: + case DatePartSpecifier::DAY: + case DatePartSpecifier::DECADE: + case DatePartSpecifier::CENTURY: + case DatePartSpecifier::QUARTER: + case DatePartSpecifier::MILLENNIUM: + case DatePartSpecifier::MICROSECONDS: + case DatePartSpecifier::MILLISECONDS: + case DatePartSpecifier::SECOND: + case DatePartSpecifier::MINUTE: + case DatePartSpecifier::HOUR: + case DatePartSpecifier::EPOCH: + return part; + default: + break; + } + break; + default: + break; + } + + throw NotImplementedException("\"%s\" units \"%s\" not recognized", LogicalTypeIdToString(type.id()), specifier); +} + template static void LastYearFunction(DataChunk &args, ExpressionState &state, Vector &result) { int32_t last_year = 0; @@ -80276,7 +79810,7 @@ static unique_ptr PropagateDatePartStatistics(vector + static inline TR DecadeFromYear(TR yyyy) { + return yyyy / 10; + } + template static inline TR Operation(TA input) { - return YearOperator::Operation(input) / 10; + return DecadeFromYear(YearOperator::Operation(input)); } template @@ -80368,9 +79908,25 @@ struct DatePart { }; struct CenturyOperator { + // From the PG docs: + // "The first century starts at 0001-01-01 00:00:00 AD, although they did not know it at the time. + // This definition applies to all Gregorian calendar countries. + // There is no century number 0, you go from -1 century to 1 century. + // If you disagree with this, please write your complaint to: Pope, Cathedral Saint-Peter of Roma, Vatican." + // (To be fair, His Holiness had nothing to do with this - + // it was the lack of zero in the counting systems of the time...) + template + static inline TR CenturyFromYear(TR yyyy) { + if (yyyy > 0) { + return ((yyyy - 1) / 100) + 1; + } else { + return (yyyy / 100) - 1; + } + } + template static inline TR Operation(TA input) { - return ((YearOperator::Operation(input) - 1) / 100) + 1; + return CenturyFromYear(YearOperator::Operation(input)); } template @@ -80381,24 +79937,39 @@ struct DatePart { } }; - struct MilleniumOperator { + struct MillenniumOperator { + // See the century comment + template + static inline TR MillenniumFromYear(TR yyyy) { + if (yyyy > 0) { + return ((yyyy - 1) / 1000) + 1; + } else { + return (yyyy / 1000) - 1; + } + } + template static inline TR Operation(TA input) { - return ((YearOperator::Operation(input) - 1) / 1000) + 1; + return MillenniumFromYear(YearOperator::Operation(input)); } template static unique_ptr PropagateStatistics(ClientContext &context, BoundFunctionExpression &expr, FunctionData *bind_data, vector> &child_stats) { - return PropagateDatePartStatistics(child_stats); + return PropagateDatePartStatistics(child_stats); } }; struct QuarterOperator { + template + static inline TR QuarterFromMonth(TR mm) { + return (mm - 1) / Interval::MONTHS_PER_QUARTER + 1; + } + template static inline TR Operation(TA input) { - return (Date::ExtractMonth(input) - 1) / Interval::MONTHS_PER_QUARTER + 1; + return QuarterFromMonth(Date::ExtractMonth(input)); } template @@ -80411,11 +79982,16 @@ struct DatePart { }; struct DayOfWeekOperator { - template - static inline TR Operation(TA input) { + template + static inline TR DayOfWeekFromISO(TR isodow) { // day of the week (Sunday = 0, Saturday = 6) // turn sunday into 0 by doing mod 7 - return Date::ExtractISODayOfTheWeek(input) % 7; + return isodow % 7; + } + + template + static inline TR Operation(TA input) { + return DayOfWeekFromISO(Date::ExtractISODayOfTheWeek(input)); } template @@ -80469,10 +80045,31 @@ struct DatePart { } }; + struct ISOYearOperator { + template + static inline TR Operation(TA input) { + return Date::ExtractISOYearNumber(input); + } + + template + static unique_ptr PropagateStatistics(ClientContext &context, BoundFunctionExpression &expr, + FunctionData *bind_data, + vector> &child_stats) { + return PropagateDatePartStatistics(child_stats); + } + }; + struct YearWeekOperator { + template + static inline TR YearWeekFromParts(TR yyyy, TR ww) { + return yyyy * 100 + ((yyyy > 0) ? ww : -ww); + } + template static inline TR Operation(TA input) { - return YearOperator::Operation(input) * 100 + WeekOperator::Operation(input); + int32_t yyyy, ww; + Date::ExtractISOYearWeek(input, yyyy, ww); + return YearWeekFromParts(yyyy, ww); } template @@ -80566,6 +80163,184 @@ struct DatePart { return PropagateDatePartStatistics(child_stats); } }; + + struct EraOperator { + template + static inline TR EraFromYear(TR yyyy) { + return yyyy > 0 ? 1 : 0; + } + + template + static inline TR Operation(TA input) { + return EraFromYear(Date::ExtractYear(input)); + } + + template + static unique_ptr PropagateStatistics(ClientContext &context, BoundFunctionExpression &expr, + FunctionData *bind_data, + vector> &child_stats) { + return PropagateSimpleDatePartStatistics<0, 1>(child_stats); + } + }; + + struct TimezoneOperator { + template + static inline TR Operation(TA input) { + // Regular timestamps are UTC. + return 0; + } + + template + static unique_ptr PropagateStatistics(ClientContext &context, BoundFunctionExpression &expr, + FunctionData *bind_data, + vector> &child_stats) { + return PropagateSimpleDatePartStatistics<0, 0>(child_stats); + } + }; + + // These are all zero and have the same restrictions + using TimezoneHourOperator = TimezoneOperator; + using TimezoneMinuteOperator = TimezoneOperator; + + struct StructOperator { + using part_codes_t = vector; + using part_mask_t = uint64_t; + + enum MaskBits : uint8_t { + YMD = 1 << 0, + DOW = 1 << 1, + DOY = 1 << 2, + EPOCH = 1 << 3, + TIME = 1 << 4, + ZONE = 1 << 5, + ISO = 1 << 6 + }; + + static part_mask_t GetMask(const part_codes_t &part_codes) { + part_mask_t mask = 0; + for (const auto &part_code : part_codes) { + switch (part_code) { + case DatePartSpecifier::YEAR: + case DatePartSpecifier::MONTH: + case DatePartSpecifier::DAY: + case DatePartSpecifier::DECADE: + case DatePartSpecifier::CENTURY: + case DatePartSpecifier::MILLENNIUM: + case DatePartSpecifier::QUARTER: + case DatePartSpecifier::ERA: + mask |= YMD; + break; + case DatePartSpecifier::YEARWEEK: + case DatePartSpecifier::WEEK: + case DatePartSpecifier::ISOYEAR: + mask |= ISO; + break; + case DatePartSpecifier::DOW: + case DatePartSpecifier::ISODOW: + mask |= DOW; + break; + case DatePartSpecifier::DOY: + mask |= DOY; + break; + case DatePartSpecifier::EPOCH: + mask |= EPOCH; + break; + case DatePartSpecifier::MICROSECONDS: + case DatePartSpecifier::MILLISECONDS: + case DatePartSpecifier::SECOND: + case DatePartSpecifier::MINUTE: + case DatePartSpecifier::HOUR: + mask |= TIME; + break; + case DatePartSpecifier::TIMEZONE: + case DatePartSpecifier::TIMEZONE_HOUR: + case DatePartSpecifier::TIMEZONE_MINUTE: + mask |= ZONE; + break; + } + } + return mask; + } + + template + static inline P HasPartValue(P *part_values, DatePartSpecifier part) { + return part_values[int(part)]; + } + + template + static inline void Operation(TR **part_values, const TA &input, const idx_t idx, const part_mask_t mask) { + TR *part_data; + // YMD calculations + int32_t yyyy = 1970; + int32_t mm = 0; + int32_t dd = 1; + if (mask & YMD) { + Date::Convert(input, yyyy, mm, dd); + if ((part_data = HasPartValue(part_values, DatePartSpecifier::YEAR))) { + part_data[idx] = yyyy; + } + if ((part_data = HasPartValue(part_values, DatePartSpecifier::MONTH))) { + part_data[idx] = mm; + } + if ((part_data = HasPartValue(part_values, DatePartSpecifier::DAY))) { + part_data[idx] = dd; + } + if ((part_data = HasPartValue(part_values, DatePartSpecifier::DECADE))) { + part_data[idx] = DecadeOperator::DecadeFromYear(yyyy); + } + if ((part_data = HasPartValue(part_values, DatePartSpecifier::CENTURY))) { + part_data[idx] = CenturyOperator::CenturyFromYear(yyyy); + } + if ((part_data = HasPartValue(part_values, DatePartSpecifier::MILLENNIUM))) { + part_data[idx] = MillenniumOperator::MillenniumFromYear(yyyy); + } + if ((part_data = HasPartValue(part_values, DatePartSpecifier::QUARTER))) { + part_data[idx] = QuarterOperator::QuarterFromMonth(mm); + } + if ((part_data = HasPartValue(part_values, DatePartSpecifier::ERA))) { + part_data[idx] = EraOperator::EraFromYear(yyyy); + } + } + + // Week calculations + if (mask & DOW) { + auto isodow = Date::ExtractISODayOfTheWeek(input); + if ((part_data = HasPartValue(part_values, DatePartSpecifier::DOW))) { + part_data[idx] = DayOfWeekOperator::DayOfWeekFromISO(isodow); + } + if ((part_data = HasPartValue(part_values, DatePartSpecifier::ISODOW))) { + part_data[idx] = isodow; + } + } + + // ISO calculations + if (mask & ISO) { + int32_t ww = 0; + int32_t iyyy = 0; + Date::ExtractISOYearWeek(input, iyyy, ww); + if ((part_data = HasPartValue(part_values, DatePartSpecifier::WEEK))) { + part_data[idx] = ww; + } + if ((part_data = HasPartValue(part_values, DatePartSpecifier::ISOYEAR))) { + part_data[idx] = iyyy; + } + if ((part_data = HasPartValue(part_values, DatePartSpecifier::YEARWEEK))) { + part_data[idx] = YearWeekOperator::YearWeekFromParts(iyyy, ww); + } + } + + if (mask & EPOCH) { + if ((part_data = HasPartValue(part_values, DatePartSpecifier::EPOCH))) { + part_data[idx] = Date::Epoch(input); + } + } + if (mask & DOY) { + if ((part_data = HasPartValue(part_values, DatePartSpecifier::DOY))) { + part_data[idx] = Date::ExtractDayOfTheYear(input); + } + } + } + }; }; template <> @@ -80634,12 +80409,12 @@ int64_t DatePart::CenturyOperator::Operation(dtime_t input) { } template <> -int64_t DatePart::MilleniumOperator::Operation(interval_t input) { +int64_t DatePart::MillenniumOperator::Operation(interval_t input) { return input.months / Interval::MONTHS_PER_MILLENIUM; } template <> -int64_t DatePart::MilleniumOperator::Operation(dtime_t input) { +int64_t DatePart::MillenniumOperator::Operation(dtime_t input) { throw NotImplementedException("\"time\" units \"millennium\" not recognized"); } @@ -80718,6 +80493,33 @@ int64_t DatePart::WeekOperator::Operation(dtime_t input) { throw NotImplementedException("\"time\" units \"week\" not recognized"); } +template <> +int64_t DatePart::ISOYearOperator::Operation(timestamp_t input) { + return ISOYearOperator::Operation(Timestamp::GetDate(input)); +} + +template <> +int64_t DatePart::ISOYearOperator::Operation(interval_t input) { + throw NotImplementedException("interval units \"isoyear\" not recognized"); +} + +template <> +int64_t DatePart::ISOYearOperator::Operation(dtime_t input) { + throw NotImplementedException("\"time\" units \"isoyear\" not recognized"); +} + +template <> +int64_t DatePart::YearWeekOperator::Operation(timestamp_t input) { + return YearWeekOperator::Operation(Timestamp::GetDate(input)); +} + +template <> +int64_t DatePart::YearWeekOperator::Operation(interval_t input) { + const auto yyyy = YearOperator::Operation(input); + const auto ww = WeekOperator::Operation(input); + return YearWeekOperator::YearWeekFromParts(yyyy, ww); +} + template <> int64_t DatePart::YearWeekOperator::Operation(dtime_t input) { throw NotImplementedException("\"time\" units \"yearweek\" not recognized"); @@ -80733,7 +80535,7 @@ int64_t DatePart::MicrosecondsOperator::Operation(timestamp_t input) { template <> int64_t DatePart::MicrosecondsOperator::Operation(interval_t input) { // remove everything but the second & microsecond part - return input.micros; + return input.micros % Interval::MICROS_PER_MINUTE; } template <> @@ -80813,13 +80615,22 @@ int64_t DatePart::EpochOperator::Operation(timestamp_t input) { template <> int64_t DatePart::EpochOperator::Operation(interval_t input) { - auto secs = SecondsOperator::Operation(input); - return (input.months * Interval::DAYS_PER_MONTH + input.days) * Interval::SECS_PER_DAY + secs; + int64_t interval_years = input.months / Interval::MONTHS_PER_YEAR; + int64_t interval_days; + interval_days = Interval::DAYS_PER_YEAR * interval_years; + interval_days += Interval::DAYS_PER_MONTH * (input.months % Interval::MONTHS_PER_YEAR); + interval_days += input.days; + int64_t interval_epoch; + interval_epoch = interval_days * Interval::SECS_PER_DAY; + // we add 0.25 days per year to sort of account for leap days + interval_epoch += interval_years * (Interval::SECS_PER_DAY / 4); + interval_epoch += input.micros / Interval::MICROS_PER_SEC; + return interval_epoch; } template <> int64_t DatePart::EpochOperator::Operation(dtime_t input) { - return SecondsOperator::Operation(input); + return input.micros / Interval::MICROS_PER_SEC; } template <> @@ -80831,7 +80642,155 @@ DatePart::EpochOperator::PropagateStatistics(ClientContext &context, Bo return PropagateSimpleDatePartStatistics<0, 86400>(child_stats); } -template +template <> +int64_t DatePart::EraOperator::Operation(timestamp_t input) { + return EraOperator::Operation(Timestamp::GetDate(input)); +} + +template <> +int64_t DatePart::EraOperator::Operation(interval_t input) { + throw NotImplementedException("interval units \"era\" not recognized"); +} + +template <> +int64_t DatePart::EraOperator::Operation(dtime_t input) { + throw NotImplementedException("\"time\" units \"era\" not recognized"); +} + +template <> +int64_t DatePart::TimezoneOperator::Operation(date_t input) { + throw NotImplementedException("\"date\" units \"timezone\" not recognized"); +} + +template <> +int64_t DatePart::TimezoneOperator::Operation(interval_t input) { + throw NotImplementedException("\"interval\" units \"timezone\" not recognized"); +} + +template <> +int64_t DatePart::TimezoneOperator::Operation(dtime_t input) { + return 0; +} + +template <> +void DatePart::StructOperator::Operation(int64_t **part_values, const dtime_t &input, const idx_t idx, + const part_mask_t mask) { + int64_t *part_data; + if (mask & TIME) { + const auto micros = MicrosecondsOperator::Operation(input); + if ((part_data = HasPartValue(part_values, DatePartSpecifier::MICROSECONDS))) { + part_data[idx] = micros; + } + if ((part_data = HasPartValue(part_values, DatePartSpecifier::MILLISECONDS))) { + part_data[idx] = micros / Interval::MICROS_PER_MSEC; + } + if ((part_data = HasPartValue(part_values, DatePartSpecifier::SECOND))) { + part_data[idx] = micros / Interval::MICROS_PER_SEC; + } + if ((part_data = HasPartValue(part_values, DatePartSpecifier::MINUTE))) { + part_data[idx] = MinutesOperator::Operation(input); + } + if ((part_data = HasPartValue(part_values, DatePartSpecifier::HOUR))) { + part_data[idx] = HoursOperator::Operation(input); + } + } + + if (mask & EPOCH) { + if ((part_data = HasPartValue(part_values, DatePartSpecifier::EPOCH))) { + part_data[idx] = EpochOperator::Operation(input); + ; + } + } + + if (mask & ZONE) { + if ((part_data = HasPartValue(part_values, DatePartSpecifier::TIMEZONE))) { + part_data[idx] = 0; + } + if ((part_data = HasPartValue(part_values, DatePartSpecifier::TIMEZONE_HOUR))) { + part_data[idx] = 0; + } + if ((part_data = HasPartValue(part_values, DatePartSpecifier::TIMEZONE_MINUTE))) { + part_data[idx] = 0; + } + } +} + +template <> +void DatePart::StructOperator::Operation(int64_t **part_values, const timestamp_t &input, const idx_t idx, + const part_mask_t mask) { + date_t d; + dtime_t t; + Timestamp::Convert(input, d, t); + + // Both define epoch, and the correct value is the sum. + // So mask it out and compute it separately. + Operation(part_values, d, idx, mask & ~EPOCH); + Operation(part_values, t, idx, mask & ~EPOCH); + + if (mask & EPOCH) { + auto part_data = HasPartValue(part_values, DatePartSpecifier::EPOCH); + if (part_data) { + part_data[idx] = EpochOperator::Operation(input); + } + } +} + +template <> +void DatePart::StructOperator::Operation(int64_t **part_values, const interval_t &input, const idx_t idx, + const part_mask_t mask) { + int64_t *part_data; + if (mask & YMD) { + const auto mm = input.months % Interval::MONTHS_PER_YEAR; + if ((part_data = HasPartValue(part_values, DatePartSpecifier::YEAR))) { + part_data[idx] = input.months / Interval::MONTHS_PER_YEAR; + } + if ((part_data = HasPartValue(part_values, DatePartSpecifier::MONTH))) { + part_data[idx] = mm; + } + if ((part_data = HasPartValue(part_values, DatePartSpecifier::DAY))) { + part_data[idx] = input.days; + } + if ((part_data = HasPartValue(part_values, DatePartSpecifier::DECADE))) { + part_data[idx] = input.months / Interval::MONTHS_PER_DECADE; + } + if ((part_data = HasPartValue(part_values, DatePartSpecifier::CENTURY))) { + part_data[idx] = input.months / Interval::MONTHS_PER_CENTURY; + } + if ((part_data = HasPartValue(part_values, DatePartSpecifier::MILLENNIUM))) { + part_data[idx] = input.months / Interval::MONTHS_PER_MILLENIUM; + } + if ((part_data = HasPartValue(part_values, DatePartSpecifier::QUARTER))) { + part_data[idx] = mm / Interval::MONTHS_PER_QUARTER + 1; + } + } + + if (mask & TIME) { + const auto micros = MicrosecondsOperator::Operation(input); + if ((part_data = HasPartValue(part_values, DatePartSpecifier::MICROSECONDS))) { + part_data[idx] = micros; + } + if ((part_data = HasPartValue(part_values, DatePartSpecifier::MILLISECONDS))) { + part_data[idx] = micros / Interval::MICROS_PER_MSEC; + } + if ((part_data = HasPartValue(part_values, DatePartSpecifier::SECOND))) { + part_data[idx] = micros / Interval::MICROS_PER_SEC; + } + if ((part_data = HasPartValue(part_values, DatePartSpecifier::MINUTE))) { + part_data[idx] = MinutesOperator::Operation(input); + } + if ((part_data = HasPartValue(part_values, DatePartSpecifier::HOUR))) { + part_data[idx] = HoursOperator::Operation(input); + } + } + + if (mask & EPOCH) { + if ((part_data = HasPartValue(part_values, DatePartSpecifier::EPOCH))) { + part_data[idx] = EpochOperator::Operation(input); + } + } +} + +template static int64_t ExtractElement(DatePartSpecifier type, T element) { switch (type) { case DatePartSpecifier::YEAR: @@ -80845,7 +80804,7 @@ static int64_t ExtractElement(DatePartSpecifier type, T element) { case DatePartSpecifier::CENTURY: return DatePart::CenturyOperator::template Operation(element); case DatePartSpecifier::MILLENNIUM: - return DatePart::MilleniumOperator::template Operation(element); + return DatePart::MillenniumOperator::template Operation(element); case DatePartSpecifier::QUARTER: return DatePart::QuarterOperator::template Operation(element); case DatePartSpecifier::DOW: @@ -80856,6 +80815,8 @@ static int64_t ExtractElement(DatePartSpecifier type, T element) { return DatePart::DayOfYearOperator::template Operation(element); case DatePartSpecifier::WEEK: return DatePart::WeekOperator::template Operation(element); + case DatePartSpecifier::ISOYEAR: + return DatePart::ISOYearOperator::template Operation(element); case DatePartSpecifier::YEARWEEK: return DatePart::YearWeekOperator::template Operation(element); case DatePartSpecifier::EPOCH: @@ -80870,6 +80831,12 @@ static int64_t ExtractElement(DatePartSpecifier type, T element) { return DatePart::MinutesOperator::template Operation(element); case DatePartSpecifier::HOUR: return DatePart::HoursOperator::template Operation(element); + case DatePartSpecifier::ERA: + return DatePart::EraOperator::template Operation(element); + case DatePartSpecifier::TIMEZONE: + case DatePartSpecifier::TIMEZONE_HOUR: + case DatePartSpecifier::TIMEZONE_MINUTE: + return DatePart::TimezoneOperator::template Operation(element); default: throw NotImplementedException("Specifier type not implemented for DATEPART"); } @@ -80967,6 +80934,165 @@ struct DayNameOperator { } }; +struct StructDatePart { + using part_codes_t = vector; + + struct BindData : public VariableReturnBindData { + part_codes_t part_codes; + + explicit BindData(const LogicalType &stype, const part_codes_t &part_codes_p) + : VariableReturnBindData(stype), part_codes(part_codes_p) { + } + + unique_ptr Copy() override { + return make_unique(stype, part_codes); + } + }; + + static unique_ptr Bind(ClientContext &context, ScalarFunction &bound_function, + vector> &arguments) { + // collect names and deconflict, construct return type + if (!arguments[0]->IsFoldable()) { + throw BinderException("%s can only take constant lists of part names", bound_function.name); + } + + case_insensitive_set_t name_collision_set; + child_list_t struct_children; + part_codes_t part_codes; + + Value parts_list = ExpressionExecutor::EvaluateScalar(*arguments[0]); + if (parts_list.type().id() == LogicalTypeId::LIST) { + auto &list_children = ListValue::GetChildren(parts_list); + if (list_children.empty()) { + throw BinderException("%s requires non-empty lists of part names", bound_function.name); + } + for (const auto &part_value : list_children) { + if (part_value.IsNull()) { + throw BinderException("NULL struct entry name in %s", bound_function.name); + } + const auto part_name = part_value.ToString(); + const auto part_code = GetDateTypePartSpecifier(part_name, arguments[1]->return_type); + if (name_collision_set.find(part_name) != name_collision_set.end()) { + throw BinderException("Duplicate struct entry name \"%s\" in %s", part_name, bound_function.name); + } + name_collision_set.insert(part_name); + part_codes.emplace_back(part_code); + struct_children.emplace_back(make_pair(part_name, LogicalType::BIGINT)); + } + } else { + throw BinderException("%s can only take constant lists of part names", bound_function.name); + } + + arguments.erase(arguments.begin()); + bound_function.arguments.erase(bound_function.arguments.begin()); + bound_function.return_type = LogicalType::STRUCT(move(struct_children)); + return make_unique(bound_function.return_type, part_codes); + } + + template + static void Function(DataChunk &args, ExpressionState &state, Vector &result) { + auto &func_expr = (BoundFunctionExpression &)state.expr; + auto &info = (BindData &)*func_expr.bind_info; + D_ASSERT(args.ColumnCount() == 1); + + const auto count = args.size(); + Vector &input = args.data[0]; + vector part_values(int(DatePartSpecifier::TIMEZONE_MINUTE) + 1, nullptr); + const auto part_mask = DatePart::StructOperator::GetMask(info.part_codes); + + auto &child_entries = StructVector::GetEntries(result); + + // The first computer of a part "owns" it + // and other requestors just reference the owner + vector owners(int(DatePartSpecifier::TIMEZONE_MINUTE) + 1, child_entries.size()); + for (size_t col = 0; col < child_entries.size(); ++col) { + const auto part_index = size_t(info.part_codes[col]); + if (owners[part_index] == child_entries.size()) { + owners[part_index] = col; + } + } + + if (input.GetVectorType() == VectorType::CONSTANT_VECTOR) { + result.SetVectorType(VectorType::CONSTANT_VECTOR); + + if (ConstantVector::IsNull(input)) { + ConstantVector::SetNull(result, true); + } else { + ConstantVector::SetNull(result, false); + for (size_t col = 0; col < child_entries.size(); ++col) { + auto &child_entry = child_entries[col]; + ConstantVector::SetNull(*child_entry, false); + const auto part_index = size_t(info.part_codes[col]); + if (owners[part_index] == col) { + part_values[part_index] = ConstantVector::GetData(*child_entry); + } + } + auto tdata = ConstantVector::GetData(input); + DatePart::StructOperator::Operation(part_values.data(), tdata[0], 0, part_mask); + } + } else { + VectorData rdata; + input.Orrify(count, rdata); + + const auto &arg_valid = rdata.validity; + auto tdata = (const INPUT_TYPE *)rdata.data; + + // Start with a valid flat vector + result.SetVectorType(VectorType::FLAT_VECTOR); + auto &res_valid = FlatVector::Validity(result); + if (res_valid.GetData()) { + res_valid.SetAllValid(count); + } + + // Start with valid children + for (size_t col = 0; col < child_entries.size(); ++col) { + auto &child_entry = child_entries[col]; + child_entry->SetVectorType(VectorType::FLAT_VECTOR); + auto &child_validity = FlatVector::Validity(*child_entry); + if (child_validity.GetData()) { + child_validity.SetAllValid(count); + } + + // Pre-multiplex + const auto part_index = size_t(info.part_codes[col]); + if (owners[part_index] == col) { + part_values[part_index] = FlatVector::GetData(*child_entry); + } + } + + for (idx_t i = 0; i < count; ++i) { + const auto idx = rdata.sel->get_index(i); + if (arg_valid.RowIsValid(idx)) { + DatePart::StructOperator::Operation(part_values.data(), tdata[idx], idx, part_mask); + } else { + res_valid.SetInvalid(idx); + for (auto &child_entry : child_entries) { + FlatVector::Validity(*child_entry).SetInvalid(idx); + } + } + } + } + + // Reference any duplicate parts + for (size_t col = 0; col < child_entries.size(); ++col) { + const auto part_index = size_t(info.part_codes[col]); + const auto owner = owners[part_index]; + if (owner != col) { + child_entries[col]->Reference(*child_entries[owner]); + } + } + + result.Verify(count); + } + + template + static ScalarFunction GetFunction(const LogicalType &temporal_type) { + auto part_type = LogicalType::LIST(LogicalType::VARCHAR); + auto result_type = LogicalType::STRUCT({}); + return ScalarFunction({part_type, temporal_type}, result_type, Function, false, Bind); + } +}; + void DatePartFun::RegisterFunction(BuiltinFunctions &set) { // register the individual operators AddGenericDatePartOperator(set, "year", LastYearFunction, LastYearFunction, @@ -80977,12 +81103,17 @@ void DatePartFun::RegisterFunction(BuiltinFunctions &set) { AddDatePartOperator(set, "day"); AddDatePartOperator(set, "decade"); AddDatePartOperator(set, "century"); - AddDatePartOperator(set, "millenium"); + AddDatePartOperator(set, "millennium"); AddDatePartOperator(set, "quarter"); AddDatePartOperator(set, "dayofweek"); AddDatePartOperator(set, "isodow"); AddDatePartOperator(set, "dayofyear"); AddDatePartOperator(set, "week"); + AddDatePartOperator(set, "isoyear"); + AddDatePartOperator(set, "era"); + AddDatePartOperator(set, "timezone"); + AddDatePartOperator(set, "timezone_hour"); + AddDatePartOperator(set, "timezone_minute"); AddTimePartOperator(set, "epoch"); AddTimePartOperator(set, "microsecond"); AddTimePartOperator(set, "millisecond"); @@ -81032,6 +81163,13 @@ void DatePartFun::RegisterFunction(BuiltinFunctions &set) { ScalarFunction({LogicalType::VARCHAR, LogicalType::TIME}, LogicalType::BIGINT, DatePartFunction)); date_part.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::INTERVAL}, LogicalType::BIGINT, DatePartFunction)); + + // struct variants + date_part.AddFunction(StructDatePart::GetFunction(LogicalType::DATE)); + date_part.AddFunction(StructDatePart::GetFunction(LogicalType::TIMESTAMP)); + date_part.AddFunction(StructDatePart::GetFunction(LogicalType::TIME)); + date_part.AddFunction(StructDatePart::GetFunction(LogicalType::INTERVAL)); + set.AddFunction(date_part); date_part.name = "datepart"; set.AddFunction(date_part); @@ -81094,6 +81232,7 @@ struct DateSub { return MonthOperator::Operation(start_ts, end_ts) / Interval::MONTHS_PER_QUARTER; } }; + struct YearOperator { template static inline TR Operation(TA start_ts, TB end_ts) { @@ -81340,6 +81479,7 @@ template static int64_t SubtractDateParts(DatePartSpecifier type, TA startdate, TB enddate) { switch (type) { case DatePartSpecifier::YEAR: + case DatePartSpecifier::ISOYEAR: return DateSub::YearOperator::template Operation(startdate, enddate); case DatePartSpecifier::MONTH: return DateSub::MonthOperator::template Operation(startdate, enddate); @@ -81386,6 +81526,7 @@ template static void DateSubBinaryExecutor(DatePartSpecifier type, Vector &left, Vector &right, Vector &result, idx_t count) { switch (type) { case DatePartSpecifier::YEAR: + case DatePartSpecifier::ISOYEAR: BinaryExecutor::ExecuteStandard(left, right, result, count); break; case DatePartSpecifier::MONTH: @@ -81546,6 +81687,16 @@ struct DateTrunc { } }; + struct ISOYearOperator { + template + static inline TR Operation(TA input) { + date_t date = Date::GetMondayOfCurrentWeek(input); + date.days -= (Date::ExtractISOWeekNumber(date) - 1) * Interval::DAYS_PER_WEEK; + + return Timestamp::FromDatetime(date, dtime_t(0)); + } + }; + struct DayOperator { template static inline TR Operation(TA input) { @@ -81647,6 +81798,11 @@ timestamp_t DateTrunc::WeekOperator::Operation(date_t input) { return WeekOperator::Operation(Timestamp::FromDatetime(input, dtime_t(0))); } +template <> +timestamp_t DateTrunc::ISOYearOperator::Operation(timestamp_t input) { + return ISOYearOperator::Operation(Timestamp::GetDate(input)); +} + template <> timestamp_t DateTrunc::DayOperator::Operation(date_t input) { return Timestamp::FromDatetime(input, dtime_t(0)); @@ -81695,6 +81851,8 @@ static TR TruncateElement(DatePartSpecifier type, TA element) { case DatePartSpecifier::WEEK: case DatePartSpecifier::YEARWEEK: return DateTrunc::WeekOperator::Operation(element); + case DatePartSpecifier::ISOYEAR: + return DateTrunc::ISOYearOperator::Operation(element); case DatePartSpecifier::DAY: case DatePartSpecifier::DOW: case DatePartSpecifier::ISODOW: @@ -81748,6 +81906,9 @@ static void DateTruncUnaryExecutor(DatePartSpecifier type, Vector &left, Vector case DatePartSpecifier::YEARWEEK: UnaryExecutor::Execute(left, result, count); break; + case DatePartSpecifier::ISOYEAR: + UnaryExecutor::Execute(left, result, count); + break; case DatePartSpecifier::DAY: case DatePartSpecifier::DOW: case DatePartSpecifier::ISODOW: @@ -81859,6 +82020,189 @@ void EpochFun::RegisterFunction(BuiltinFunctions &set) { +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/vector_operations/senary_executor.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +struct SenaryExecutor { + static const size_t NCOLS = 6; + + template > + static void Execute(DataChunk &input, Vector &result, FUN fun) { + D_ASSERT(input.ColumnCount() >= NCOLS); + const auto count = input.size(); + + bool all_constant = true; + bool any_null = false; + for (const auto &v : input.data) { + if (v.GetVectorType() == VectorType::CONSTANT_VECTOR) { + if (ConstantVector::IsNull(v)) { + any_null = true; + } + } else { + all_constant = false; + break; + } + } + + if (all_constant) { + result.SetVectorType(VectorType::CONSTANT_VECTOR); + if (any_null) { + ConstantVector::SetNull(result, true); + } else { + auto adata = ConstantVector::GetData(input.data[0]); + auto bdata = ConstantVector::GetData(input.data[1]); + auto cdata = ConstantVector::GetData(input.data[2]); + auto ddata = ConstantVector::GetData(input.data[3]); + auto edata = ConstantVector::GetData(input.data[4]); + auto fdata = ConstantVector::GetData(input.data[5]); + auto result_data = ConstantVector::GetData(result); + result_data[0] = fun(*adata, *bdata, *cdata, *ddata, *edata, *fdata); + } + } else { + result.SetVectorType(VectorType::FLAT_VECTOR); + auto result_data = FlatVector::GetData(result); + auto &result_validity = FlatVector::Validity(result); + + bool all_valid = true; + vector vdata(NCOLS); + for (size_t c = 0; c < NCOLS; ++c) { + input.data[c].Orrify(count, vdata[c]); + all_valid = all_valid && vdata[c].validity.AllValid(); + } + + auto adata = (const TA *)(vdata[0].data); + auto bdata = (const TB *)(vdata[1].data); + auto cdata = (const TC *)(vdata[2].data); + auto ddata = (const TD *)(vdata[3].data); + auto edata = (const TE *)(vdata[4].data); + auto fdata = (const TF *)(vdata[5].data); + + vector idx(NCOLS); + if (all_valid) { + for (idx_t r = 0; r < count; ++r) { + for (size_t c = 0; c < NCOLS; ++c) { + idx[c] = vdata[c].sel->get_index(r); + } + result_data[r] = + fun(adata[idx[0]], bdata[idx[1]], cdata[idx[2]], ddata[idx[3]], edata[idx[4]], fdata[idx[5]]); + } + } else { + for (idx_t r = 0; r < count; ++r) { + all_valid = true; + for (size_t c = 0; c < NCOLS; ++c) { + idx[c] = vdata[c].sel->get_index(r); + if (!vdata[c].validity.RowIsValid(idx[c])) { + result_validity.SetInvalid(r); + all_valid = false; + break; + } + } + if (all_valid) { + result_data[r] = fun(adata[idx[0]], bdata[idx[1]], cdata[idx[2]], ddata[idx[3]], edata[idx[4]], + fdata[idx[5]]); + } + } + } + } + } +}; + +} // namespace duckdb + + +namespace duckdb { + +struct MakeDateOperator { + template + static RESULT_TYPE Operation(YYYY yyyy, MM mm, DD dd) { + return Date::FromDate(yyyy, mm, dd); + } +}; + +template +static void ExecuteMakeDate(DataChunk &input, ExpressionState &state, Vector &result) { + D_ASSERT(input.ColumnCount() == 3); + auto &yyyy = input.data[0]; + auto &mm = input.data[1]; + auto &dd = input.data[2]; + + TernaryExecutor::Execute(yyyy, mm, dd, result, input.size(), + MakeDateOperator::Operation); +} + +struct MakeTimeOperator { + template + static RESULT_TYPE Operation(HH hh, MM mm, SS ss) { + int64_t secs = ss; + int64_t micros = std::round((ss - secs) * Interval::MICROS_PER_SEC); + return Time::FromTime(hh, mm, secs, micros); + } +}; + +template +static void ExecuteMakeTime(DataChunk &input, ExpressionState &state, Vector &result) { + D_ASSERT(input.ColumnCount() == 3); + auto &yyyy = input.data[0]; + auto &mm = input.data[1]; + auto &dd = input.data[2]; + + TernaryExecutor::Execute(yyyy, mm, dd, result, input.size(), + MakeTimeOperator::Operation); +} + +struct MakeTimestampOperator { + template + static RESULT_TYPE Operation(YYYY yyyy, MM mm, DD dd, HR hr, MN mn, SS ss) { + const auto d = MakeDateOperator::Operation(yyyy, mm, dd); + const auto t = MakeTimeOperator::Operation(hr, mn, ss); + return Timestamp::FromDatetime(d, t); + } +}; + +template +static void ExecuteMakeTimestamp(DataChunk &input, ExpressionState &state, Vector &result) { + D_ASSERT(input.ColumnCount() == 6); + + auto func = MakeTimestampOperator::Operation; + SenaryExecutor::Execute(input, result, func); +} + +void MakeDateFun::RegisterFunction(BuiltinFunctions &set) { + ScalarFunctionSet make_date("make_date"); + make_date.AddFunction(ScalarFunction({LogicalType::BIGINT, LogicalType::BIGINT, LogicalType::BIGINT}, + LogicalType::DATE, ExecuteMakeDate)); + set.AddFunction(make_date); + + ScalarFunctionSet make_time("make_time"); + make_time.AddFunction(ScalarFunction({LogicalType::BIGINT, LogicalType::BIGINT, LogicalType::DOUBLE}, + LogicalType::TIME, ExecuteMakeTime)); + set.AddFunction(make_time); + + ScalarFunctionSet make_timestamp("make_timestamp"); + make_timestamp.AddFunction(ScalarFunction({LogicalType::BIGINT, LogicalType::BIGINT, LogicalType::BIGINT, + LogicalType::BIGINT, LogicalType::BIGINT, LogicalType::DOUBLE}, + LogicalType::TIMESTAMP, ExecuteMakeTimestamp)); + set.AddFunction(make_timestamp); +} + +} // namespace duckdb + + + + + @@ -82379,7 +82723,8 @@ string StrTimeFormat::ParseFormatSpecifier(const string &format_string, StrTimeF break; case 'c': case 'x': - case 'X': { + case 'X': + case 'T': { string subformat; if (format_char == 'c') { // %c: Locale’s appropriate date and time representation. @@ -82389,7 +82734,7 @@ string StrTimeFormat::ParseFormatSpecifier(const string &format_string, StrTimeF // %x - Locale’s appropriate date representation. // we push the ISO date format here subformat = "%Y-%m-%d"; - } else if (format_char == 'X') { + } else if (format_char == 'X' || format_char == 'T') { // %X - Locale’s appropriate time representation. // we push the ISO time format here subformat = "%H:%M:%S"; @@ -82443,7 +82788,7 @@ static unique_ptr StrfTimeBindFunction(ClientContext &context, Sca } Value options_str = ExpressionExecutor::EvaluateScalar(*arguments[1]); StrfTimeFormat format; - if (!options_str.is_null && options_str.type().id() == LogicalTypeId::VARCHAR) { + if (!options_str.IsNull() && options_str.type().id() == LogicalTypeId::VARCHAR) { auto format_string = options_str.GetValue(); string error = StrTimeFormat::ParseFormatSpecifier(format_string, format); if (!error.empty()) { @@ -82864,7 +83209,18 @@ bool StrpTimeFormat::Parse(string_t str, ParseResult &result) { result_data[4] -= minute_offset; break; } - + case StrTimeSpecifier::TZ_NAME: { + // skip leading spaces + while (pos < size && StringUtil::CharacterIsSpace(data[pos])) { + pos++; + } + // stop when we encounter a space or the end of the string + while (pos < size && !StringUtil::CharacterIsSpace(data[pos])) { + pos++; + } + // FIXME: actually use the timestamp... + break; + } default: throw NotImplementedException("Unsupported specifier for strptime"); } @@ -82952,7 +83308,7 @@ static unique_ptr StrpTimeBindFunction(ClientContext &context, Sca } Value options_str = ExpressionExecutor::EvaluateScalar(*arguments[1]); StrpTimeFormat format; - if (!options_str.is_null && options_str.type().id() == LogicalTypeId::VARCHAR) { + if (!options_str.IsNull() && options_str.type().id() == LogicalTypeId::VARCHAR) { string format_string = options_str.ToString(); format.format_specifier = format_string; string error = StrTimeFormat::ParseFormatSpecifier(format_string, format); @@ -82963,8 +83319,22 @@ static unique_ptr StrpTimeBindFunction(ClientContext &context, Sca return make_unique(format); } +StrpTimeFormat::ParseResult StrpTimeFormat::Parse(const string &format_string, const string &text) { + StrpTimeFormat format; + format.format_specifier = format_string; + string error = StrTimeFormat::ParseFormatSpecifier(format_string, format); + if (!error.empty()) { + throw InvalidInputException("Failed to parse format specifier %s: %s", format_string, error); + } + StrpTimeFormat::ParseResult result; + if (!format.Parse(text, result)) { + throw InvalidInputException("Failed to parse string \"%s\" with format specifier \"%s\"", text, format_string); + } + return result; +} + string StrpTimeFormat::FormatStrpTimeError(const string &input, idx_t position) { - if (position == INVALID_INDEX) { + if (position == DConstants::INVALID_INDEX) { return string(); } return input + "\n" + string(position, ' ') + "^"; @@ -83189,11 +83559,169 @@ void BuiltinFunctions::RegisterDateFunctions() { Register(); Register(); Register(); + Register(); Register(); Register(); Register(); } +} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/function/scalar/enum_functions.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { + +struct EnumFirst { + static void RegisterFunction(BuiltinFunctions &set); +}; + +struct EnumLast { + static void RegisterFunction(BuiltinFunctions &set); +}; + +struct EnumRange { + static void RegisterFunction(BuiltinFunctions &set); +}; + +struct EnumRangeBoundary { + static void RegisterFunction(BuiltinFunctions &set); +}; + +} // namespace duckdb + + +namespace duckdb { + +static void EnumFirstFunction(DataChunk &input, ExpressionState &state, Vector &result) { + D_ASSERT(input.GetTypes().size() == 1); + auto &enum_vector = EnumType::GetValuesInsertOrder(input.GetTypes()[0]); + auto val = Value(enum_vector.GetValue(0)); + result.Reference(val); +} + +static void EnumLastFunction(DataChunk &input, ExpressionState &state, Vector &result) { + D_ASSERT(input.GetTypes().size() == 1); + auto enum_size = EnumType::GetSize(input.GetTypes()[0]); + auto &enum_vector = EnumType::GetValuesInsertOrder(input.GetTypes()[0]); + auto val = Value(enum_vector.GetValue(enum_size - 1)); + result.Reference(val); +} + +static void EnumRangeFunction(DataChunk &input, ExpressionState &state, Vector &result) { + D_ASSERT(input.GetTypes().size() == 1); + auto enum_size = EnumType::GetSize(input.GetTypes()[0]); + auto &enum_vector = EnumType::GetValuesInsertOrder(input.GetTypes()[0]); + vector enum_values; + for (idx_t i = 0; i < enum_size; i++) { + enum_values.emplace_back(enum_vector.GetValue(i)); + } + auto val = Value::LIST(enum_values); + result.Reference(val); +} + +static void EnumRangeBoundaryFunction(DataChunk &input, ExpressionState &state, Vector &result) { + D_ASSERT(input.GetTypes().size() == 2); + idx_t start, end; + auto first_param = input.GetValue(0, 0); + auto second_param = input.GetValue(1, 0); + + auto &enum_vector = first_param.IsNull() ? EnumType::GetValuesInsertOrder(input.GetTypes()[1]) + : EnumType::GetValuesInsertOrder(input.GetTypes()[0]); + + if (first_param.IsNull()) { + start = 0; + } else { + start = first_param.GetValue(); + } + if (second_param.IsNull()) { + end = EnumType::GetSize(input.GetTypes()[0]); + } else { + end = second_param.GetValue() + 1; + } + vector enum_values; + for (idx_t i = start; i < end; i++) { + enum_values.emplace_back(enum_vector.GetValue(i)); + } + Value val; + if (enum_values.empty()) { + val = Value::EMPTYLIST(LogicalType::VARCHAR); + } else { + val = Value::LIST(enum_values); + } + result.Reference(val); +} + +unique_ptr BindEnumFunction(ClientContext &context, ScalarFunction &bound_function, + vector> &arguments) { + if (arguments[0]->return_type.id() != LogicalTypeId::ENUM) { + throw BinderException("This function needs an ENUM as an argument"); + } + return nullptr; +} + +unique_ptr BindEnumRangeBoundaryFunction(ClientContext &context, ScalarFunction &bound_function, + vector> &arguments) { + if (arguments[0]->return_type.id() != LogicalTypeId::ENUM && arguments[0]->return_type != LogicalType::SQLNULL) { + throw BinderException("This function needs an ENUM as an argument"); + } + if (arguments[1]->return_type.id() != LogicalTypeId::ENUM && arguments[1]->return_type != LogicalType::SQLNULL) { + throw BinderException("This function needs an ENUM as an argument"); + } + if (arguments[0]->return_type == LogicalType::SQLNULL && arguments[1]->return_type == LogicalType::SQLNULL) { + throw BinderException("This function needs an ENUM as an argument"); + } + if (arguments[0]->return_type.id() == LogicalTypeId::ENUM && + arguments[1]->return_type.id() == LogicalTypeId::ENUM && + arguments[0]->return_type != arguments[1]->return_type) { + + throw BinderException("The parameters need to link to ONLY one enum OR be NULL "); + } + return nullptr; +} + +void EnumFirst::RegisterFunction(BuiltinFunctions &set) { + set.AddFunction(ScalarFunction("enum_first", {LogicalType::ANY}, LogicalType::VARCHAR, EnumFirstFunction, false, + BindEnumFunction)); +} + +void EnumLast::RegisterFunction(BuiltinFunctions &set) { + set.AddFunction(ScalarFunction("enum_last", {LogicalType::ANY}, LogicalType::VARCHAR, EnumLastFunction, false, + BindEnumFunction)); +} + +void EnumRange::RegisterFunction(BuiltinFunctions &set) { + set.AddFunction(ScalarFunction("enum_range", {LogicalType::ANY}, LogicalType::LIST(LogicalType::VARCHAR), + EnumRangeFunction, false, BindEnumFunction)); +} + +void EnumRangeBoundary::RegisterFunction(BuiltinFunctions &set) { + set.AddFunction(ScalarFunction("enum_range_boundary", {LogicalType::ANY, LogicalType::ANY}, + LogicalType::LIST(LogicalType::VARCHAR), EnumRangeBoundaryFunction, false, + BindEnumRangeBoundaryFunction)); +} + +} // namespace duckdb + + +namespace duckdb { + +void BuiltinFunctions::RegisterEnumFunctions() { + Register(); + Register(); + Register(); + Register(); +} + } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB @@ -83370,16 +83898,6 @@ static void CurrentSettingFunction(DataChunk &args, ExpressionState &state, Vect result.Reference(info.value); } -static string NormalizeSettingName(const string &name) { - if (CaseInsensitiveStringEquality()(name, "schema")) { - // The PG doc says: - // > SET SCHEMA 'value' is an alias for SET search_path TO value. - return "search_path"; - } - - return name; -} - unique_ptr CurrentSettingBind(ClientContext &context, ScalarFunction &bound_function, vector> &arguments) { @@ -83387,18 +83905,19 @@ unique_ptr CurrentSettingBind(ClientContext &context, ScalarFuncti if (key_child->return_type.id() != LogicalTypeId::VARCHAR || key_child->return_type.id() != LogicalTypeId::VARCHAR || !key_child->IsFoldable()) { - throw ParserException("Key name for struct_extract needs to be a constant string"); + throw ParserException("Key name for current_setting needs to be a constant string"); } Value key_val = ExpressionExecutor::EvaluateScalar(*key_child.get()); D_ASSERT(key_val.type().id() == LogicalTypeId::VARCHAR); - if (key_val.is_null || key_val.str_value.length() < 1) { - throw ParserException("Key name for struct_extract needs to be neither NULL nor empty"); + auto &key_str = StringValue::Get(key_val); + if (key_val.IsNull() || key_str.empty()) { + throw ParserException("Key name for current_setting needs to be neither NULL nor empty"); } - const auto &key = NormalizeSettingName(key_val.str_value); + auto key = StringUtil::Lower(key_str); Value val; if (!context.TryGetCurrentSetting(key, val)) { - throw InvalidInputException("Variable '%s' was not SET in this context", key); + throw InvalidInputException("unrecognized configuration parameter \"%s\"", key_str); } bound_function.return_type = val.type(); @@ -83433,14 +83952,7 @@ static void LeastGreatestFunction(DataChunk &args, ExpressionState &state, Vecto } auto result_type = VectorType::CONSTANT_VECTOR; for (idx_t col_idx = 0; col_idx < args.ColumnCount(); col_idx++) { - if (args.data[col_idx].GetVectorType() == VectorType::CONSTANT_VECTOR) { - if (ConstantVector::IsNull(args.data[col_idx])) { - // constant NULL: result is constant NULL - result.SetVectorType(VectorType::CONSTANT_VECTOR); - ConstantVector::SetNull(result, true); - return; - } - } else { + if (args.data[col_idx].GetVectorType() != VectorType::CONSTANT_VECTOR) { // non-constant input: result is not a constant vector result_type = VectorType::FLAT_VECTOR; } @@ -83450,71 +83962,78 @@ static void LeastGreatestFunction(DataChunk &args, ExpressionState &state, Vecto } } - // we start off performing a binary operation between the first two inputs, where we store the lowest (or highest) - // directly in the result - BinaryExecutor::ExecuteGeneric, bool>( - args.data[0], args.data[1], result, args.size(), false); - - // now we loop over the other columns and compare it to the stored result auto result_data = FlatVector::GetData(result); auto &result_mask = FlatVector::Validity(result); - SelectionVector rsel; - idx_t rcount = 0; - // create a selection vector from the mask - rsel.Initialize(); - for (idx_t i = 0; i < args.size(); i++) { - if (result_mask.RowIsValid(i)) { - rsel.set_index(rcount++, i); + // copy over the first column + bool result_has_value[STANDARD_VECTOR_SIZE]; + { + VectorData vdata; + args.data[0].Orrify(args.size(), vdata); + auto input_data = (T *)vdata.data; + for (idx_t i = 0; i < args.size(); i++) { + auto vindex = vdata.sel->get_index(i); + if (vdata.validity.RowIsValid(vindex)) { + result_data[i] = input_data[vindex]; + result_has_value[i] = true; + } else { + result_has_value[i] = false; + } } } - for (idx_t col_idx = 2; col_idx < args.ColumnCount(); col_idx++) { + // now handle the remainder of the columns + for (idx_t col_idx = 1; col_idx < args.ColumnCount(); col_idx++) { + if (args.data[col_idx].GetVectorType() == VectorType::CONSTANT_VECTOR && + ConstantVector::IsNull(args.data[col_idx])) { + // ignore null vector + continue; + } + VectorData vdata; args.data[col_idx].Orrify(args.size(), vdata); auto input_data = (T *)vdata.data; if (!vdata.validity.AllValid()) { // potential new null entries: have to check the null mask - idx_t new_count = 0; - for (idx_t i = 0; i < rcount; i++) { - auto rindex = rsel.get_index(i); - auto vindex = vdata.sel->get_index(rindex); - if (!vdata.validity.RowIsValid(vindex)) { - // new null entry: set nullmask - result_mask.SetInvalid(rindex); - } else { + for (idx_t i = 0; i < args.size(); i++) { + auto vindex = vdata.sel->get_index(i); + if (vdata.validity.RowIsValid(vindex)) { // not a null entry: perform the operation and add to new set auto ivalue = input_data[vindex]; - if (OP::template Operation(ivalue, result_data[rindex])) { - result_data[rindex] = ivalue; + if (!result_has_value[i] || OP::template Operation(ivalue, result_data[i])) { + result_has_value[i] = true; + result_data[i] = ivalue; } - rsel.set_index(new_count++, rindex); } } - rcount = new_count; } else { // no new null entries: only need to perform the operation - for (idx_t i = 0; i < rcount; i++) { - auto rindex = rsel.get_index(i); - auto vindex = vdata.sel->get_index(rindex); + for (idx_t i = 0; i < args.size(); i++) { + auto vindex = vdata.sel->get_index(i); auto ivalue = input_data[vindex]; - if (OP::template Operation(ivalue, result_data[rindex])) { - result_data[rindex] = ivalue; + if (!result_has_value[i] || OP::template Operation(ivalue, result_data[i])) { + result_has_value[i] = true; + result_data[i] = ivalue; } } } } + for (idx_t i = 0; i < args.size(); i++) { + if (!result_has_value[i]) { + result_mask.SetInvalid(i); + } + } result.SetVectorType(result_type); } +template +ScalarFunction GetLeastGreatestFunction(const LogicalType &type) { + return ScalarFunction({type}, type, LeastGreatestFunction, false, nullptr, nullptr, nullptr, nullptr, type); +} + template static void RegisterLeastGreatest(BuiltinFunctions &set, const string &fun_name) { ScalarFunctionSet fun_set(fun_name); - fun_set.AddFunction(ScalarFunction({LogicalType::DATE}, LogicalType::DATE, LeastGreatestFunction, false, - nullptr, nullptr, nullptr, nullptr, LogicalType::DATE)); - fun_set.AddFunction(ScalarFunction({LogicalType::TIMESTAMP}, LogicalType::TIMESTAMP, - LeastGreatestFunction, false, nullptr, nullptr, nullptr, - nullptr, LogicalType::TIMESTAMP)); fun_set.AddFunction(ScalarFunction({LogicalType::BIGINT}, LogicalType::BIGINT, LeastGreatestFunction, false, nullptr, nullptr, nullptr, nullptr, LogicalType::BIGINT)); fun_set.AddFunction(ScalarFunction({LogicalType::HUGEINT}, LogicalType::HUGEINT, @@ -83525,6 +84044,14 @@ static void RegisterLeastGreatest(BuiltinFunctions &set, const string &fun_name) fun_set.AddFunction(ScalarFunction({LogicalType::VARCHAR}, LogicalType::VARCHAR, LeastGreatestFunction, false, nullptr, nullptr, nullptr, nullptr, LogicalType::VARCHAR)); + + fun_set.AddFunction(GetLeastGreatestFunction(LogicalType::TIMESTAMP)); + fun_set.AddFunction(GetLeastGreatestFunction(LogicalType::TIME)); + fun_set.AddFunction(GetLeastGreatestFunction(LogicalType::DATE)); + + fun_set.AddFunction(GetLeastGreatestFunction(LogicalType::TIMESTAMP_TZ)); + fun_set.AddFunction(GetLeastGreatestFunction(LogicalType::TIME_TZ)); + set.AddFunction(fun_set); } @@ -83659,7 +84186,7 @@ bool ClampIndex(INDEX_TYPE &index, const INPUT_TYPE &value) { } index = length + index; } else if (index > length) { - return false; + index = length; } return true; } @@ -83757,17 +84284,11 @@ static void ArraySliceFunction(DataChunk &args, ExpressionState &state, Vector & D_ASSERT(args.data.size() == 3); auto count = args.size(); - result.SetVectorType(VectorType::CONSTANT_VECTOR); - for (idx_t i = 0; i < args.ColumnCount(); i++) { - if (args.data[i].GetVectorType() != VectorType::CONSTANT_VECTOR) { - result.SetVectorType(VectorType::FLAT_VECTOR); - } - } - Vector &s = args.data[0]; Vector &b = args.data[1]; Vector &e = args.data[2]; + s.Normalify(count); switch (result.GetType().id()) { case LogicalTypeId::LIST: // Share the value dictionary as we are just going to slice it @@ -83780,6 +84301,14 @@ static void ArraySliceFunction(DataChunk &args, ExpressionState &state, Vector & default: throw NotImplementedException("Specifier type not implemented"); } + + result.SetVectorType(VectorType::CONSTANT_VECTOR); + for (idx_t i = 0; i < args.ColumnCount(); i++) { + if (args.data[i].GetVectorType() != VectorType::CONSTANT_VECTOR) { + result.SetVectorType(VectorType::FLAT_VECTOR); + break; + } + } } static unique_ptr ArraySliceBind(ClientContext &context, ScalarFunction &bound_function, @@ -83805,10 +84334,10 @@ static unique_ptr ArraySliceBind(ClientContext &context, ScalarFun void ArraySliceFun::RegisterFunction(BuiltinFunctions &set) { // the arguments and return types are actually set in the binder function - ScalarFunction fun("array_slice", {LogicalType::ANY, LogicalType::BIGINT, LogicalType::BIGINT}, LogicalType::ANY, + ScalarFunction fun({LogicalType::ANY, LogicalType::BIGINT, LogicalType::BIGINT}, LogicalType::ANY, ArraySliceFunction, false, ArraySliceBind); fun.varargs = LogicalType::ANY; - set.AddFunction(fun); + set.AddFunction({"array_slice", "list_slice"}, fun); } } // namespace duckdb @@ -83841,14 +84370,14 @@ class ListStatistics : public BaseStatistics { public: void Merge(const BaseStatistics &other) override; - FilterPropagateResult CheckZonemap(ExpressionType comparison_type, const Value &constant); + FilterPropagateResult CheckZonemap(ExpressionType comparison_type, const Value &constant) const; - unique_ptr Copy() override; - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(Deserializer &source, LogicalType type); - void Verify(Vector &vector, const SelectionVector &sel, idx_t count) override; + unique_ptr Copy() const override; + void Serialize(FieldWriter &serializer) const override; + static unique_ptr Deserialize(FieldReader &source, LogicalType type); + void Verify(Vector &vector, const SelectionVector &sel, idx_t count) const override; - string ToString() override; + string ToString() const override; }; } // namespace duckdb @@ -83941,7 +84470,7 @@ static unique_ptr ListConcatBind(ClientContext &context, ScalarFun D_ASSERT(rhs.id() == LogicalTypeId::LIST); // Resolve list type - auto child_type = LogicalType::SQLNULL; + LogicalType child_type = LogicalType::SQLNULL; for (const auto &argument : arguments) { child_type = LogicalType::MaxLogicalType(child_type, ListType::GetChildType(argument->return_type)); } @@ -84095,9 +84624,11 @@ static void ExecuteListExtractInternal(const idx_t count, VectorData &list, Vect ListExtractTemplate(count, list, offsets, child_vector, list_size, result); break; case LogicalTypeId::TIME: + case LogicalTypeId::TIME_TZ: ListExtractTemplate(count, list, offsets, child_vector, list_size, result); break; case LogicalTypeId::TIMESTAMP: + case LogicalTypeId::TIMESTAMP_TZ: ListExtractTemplate(count, list, offsets, child_vector, list_size, result); break; case LogicalTypeId::BLOB: @@ -84275,7 +84806,7 @@ static void ListValueFunction(DataChunk &args, ExpressionState &state, Vector &r static unique_ptr ListValueBind(ClientContext &context, ScalarFunction &bound_function, vector> &arguments) { // collect names and deconflict, construct return type - auto child_type = LogicalType::SQLNULL; + LogicalType child_type = LogicalType::SQLNULL; for (idx_t i = 0; i < arguments.size(); i++) { child_type = LogicalType::MaxLogicalType(child_type, arguments[i]->return_type); } @@ -84319,6 +84850,95 @@ void ListValueFun::RegisterFunction(BuiltinFunctions &set) { namespace duckdb { +struct NumericRangeInfo { + using TYPE = int64_t; + using INCREMENT_TYPE = int64_t; + + static int64_t DefaultStart() { + return 0; + } + static int64_t DefaultIncrement() { + return 1; + } + + static uint64_t ListLength(int64_t start_value, int64_t end_value, int64_t increment_value, bool inclusive_bound) { + if (increment_value == 0) { + return 0; + } + if (start_value > end_value && increment_value > 0) { + return 0; + } + if (start_value < end_value && increment_value < 0) { + return 0; + } + int64_t total_diff = AbsValue(end_value - start_value); + int64_t increment = AbsValue(increment_value); + int64_t total_values = total_diff / increment; + if (total_diff % increment == 0) { + if (inclusive_bound) { + total_values++; + } + } else { + total_values++; + } + return total_values; + } + + static void Increment(int64_t &input, int64_t increment) { + input += increment; + } +}; +struct TimestampRangeInfo { + using TYPE = timestamp_t; + using INCREMENT_TYPE = interval_t; + + static timestamp_t DefaultStart() { + throw InternalException("Default start not implemented for timestamp range"); + } + static interval_t DefaultIncrement() { + throw InternalException("Default increment not implemented for timestamp range"); + } + static uint64_t ListLength(timestamp_t start_value, timestamp_t end_value, interval_t increment_value, + bool inclusive_bound) { + bool is_positive = increment_value.months > 0 || increment_value.days > 0 || increment_value.micros > 0; + bool is_negative = increment_value.months < 0 || increment_value.days < 0 || increment_value.micros < 0; + if (!is_negative && !is_positive) { + // interval is 0: no result + return 0; + } + if (is_negative && is_positive) { + // we don't allow a mix of + throw InvalidInputException("Interval with mix of negative/positive entries not supported"); + } + if (start_value > end_value && is_positive) { + return 0; + } + if (start_value < end_value && is_negative) { + return 0; + } + int64_t total_values = 0; + if (is_negative) { + // negative interval, start_value is going down + while (inclusive_bound ? start_value >= end_value : start_value > end_value) { + start_value = Interval::Add(start_value, increment_value); + total_values++; + } + } else { + // positive interval, start_value is going up + while (inclusive_bound ? start_value <= end_value : start_value < end_value) { + start_value = Interval::Add(start_value, increment_value); + total_values++; + } + } + return total_values; + } + + static void Increment(timestamp_t &input, interval_t increment) { + input = Interval::Add(input, increment); + } +}; + +template class RangeInfoStruct { public: explicit RangeInfoStruct(DataChunk &args_p) : args(args_p) { @@ -84350,64 +84970,46 @@ class RangeInfoStruct { return true; } - int64_t StartListValue(idx_t row_idx) { + typename OP::TYPE StartListValue(idx_t row_idx) { if (args.ColumnCount() == 1) { - return 0; + return OP::DefaultStart(); } else { - auto data = (int64_t *)vdata[0].data; + auto data = (typename OP::TYPE *)vdata[0].data; auto idx = vdata[0].sel->get_index(row_idx); return data[idx]; } } - int64_t EndListValue(idx_t row_idx) { + typename OP::TYPE EndListValue(idx_t row_idx) { idx_t vdata_idx = args.ColumnCount() == 1 ? 0 : 1; - auto data = (int64_t *)vdata[vdata_idx].data; + auto data = (typename OP::TYPE *)vdata[vdata_idx].data; auto idx = vdata[vdata_idx].sel->get_index(row_idx); return data[idx]; } - int64_t ListIncrementValue(idx_t row_idx) { + typename OP::INCREMENT_TYPE ListIncrementValue(idx_t row_idx) { if (args.ColumnCount() < 3) { - return 1; + return OP::DefaultIncrement(); } else { - auto data = (int64_t *)vdata[2].data; + auto data = (typename OP::INCREMENT_TYPE *)vdata[2].data; auto idx = vdata[2].sel->get_index(row_idx); return data[idx]; } } - void GetListValues(idx_t row_idx, int64_t &start_value, int64_t &end_value, int64_t &increment_value) { + void GetListValues(idx_t row_idx, typename OP::TYPE &start_value, typename OP::TYPE &end_value, + typename OP::INCREMENT_TYPE &increment_value) { start_value = StartListValue(row_idx); end_value = EndListValue(row_idx); increment_value = ListIncrementValue(row_idx); } - uint64_t ListLength(idx_t row_idx, bool inclusive_bound) { - int64_t start_value; - int64_t end_value; - int64_t increment_value; + uint64_t ListLength(idx_t row_idx) { + typename OP::TYPE start_value; + typename OP::TYPE end_value; + typename OP::INCREMENT_TYPE increment_value; GetListValues(row_idx, start_value, end_value, increment_value); - if (increment_value == 0) { - return 0; - } - if (start_value > end_value && increment_value > 0) { - return 0; - } - if (start_value < end_value && increment_value < 0) { - return 0; - } - int64_t total_diff = AbsValue(end_value - start_value); - int64_t increment = AbsValue(increment_value); - int64_t total_values = total_diff / increment; - if (total_diff % increment == 0) { - if (inclusive_bound) { - total_values++; - } - } else { - total_values++; - } - return total_values; + return OP::ListLength(start_value, end_value, increment_value, INCLUSIVE_BOUND); } private: @@ -84415,11 +85017,11 @@ class RangeInfoStruct { VectorData vdata[3]; }; -template +template static void ListRangeFunction(DataChunk &args, ExpressionState &state, Vector &result) { D_ASSERT(result.GetType().id() == LogicalTypeId::LIST); - RangeInfoStruct info(args); + RangeInfoStruct info(args); idx_t args_size = 1; auto result_type = VectorType::CONSTANT_VECTOR; for (idx_t i = 0; i < args.ColumnCount(); i++) { @@ -84439,23 +85041,23 @@ static void ListRangeFunction(DataChunk &args, ExpressionState &state, Vector &r list_data[i].length = 0; } else { list_data[i].offset = total_size; - list_data[i].length = info.ListLength(i, INCLUSIVE_BOUND); + list_data[i].length = info.ListLength(i); total_size += list_data[i].length; } } // now construct the child vector of the list ListVector::Reserve(result, total_size); - auto range_data = FlatVector::GetData(ListVector::GetEntry(result)); + auto range_data = FlatVector::GetData(ListVector::GetEntry(result)); idx_t total_idx = 0; for (idx_t i = 0; i < args_size; i++) { - int64_t start_value = info.StartListValue(i); - int64_t increment = info.ListIncrementValue(i); + typename OP::TYPE start_value = info.StartListValue(i); + typename OP::INCREMENT_TYPE increment = info.ListIncrementValue(i); - int64_t range_value = start_value; + typename OP::TYPE range_value = start_value; for (idx_t range_idx = 0; range_idx < list_data[i].length; range_idx++) { range_data[total_idx++] = range_value; - range_value += increment; + OP::Increment(range_value, increment); } } @@ -84468,21 +85070,31 @@ static void ListRangeFunction(DataChunk &args, ExpressionState &state, Vector &r void ListRangeFun::RegisterFunction(BuiltinFunctions &set) { // the arguments and return types are actually set in the binder function ScalarFunctionSet range_set("range"); - range_set.AddFunction( - ScalarFunction({LogicalType::BIGINT}, LogicalType::LIST(LogicalType::BIGINT), ListRangeFunction)); + range_set.AddFunction(ScalarFunction({LogicalType::BIGINT}, LogicalType::LIST(LogicalType::BIGINT), + ListRangeFunction)); range_set.AddFunction(ScalarFunction({LogicalType::BIGINT, LogicalType::BIGINT}, - LogicalType::LIST(LogicalType::BIGINT), ListRangeFunction)); + LogicalType::LIST(LogicalType::BIGINT), + ListRangeFunction)); range_set.AddFunction(ScalarFunction({LogicalType::BIGINT, LogicalType::BIGINT, LogicalType::BIGINT}, - LogicalType::LIST(LogicalType::BIGINT), ListRangeFunction)); + LogicalType::LIST(LogicalType::BIGINT), + ListRangeFunction)); + range_set.AddFunction(ScalarFunction({LogicalType::TIMESTAMP, LogicalType::TIMESTAMP, LogicalType::INTERVAL}, + LogicalType::LIST(LogicalType::TIMESTAMP), + ListRangeFunction)); set.AddFunction(range_set); ScalarFunctionSet generate_series("generate_series"); - generate_series.AddFunction( - ScalarFunction({LogicalType::BIGINT}, LogicalType::LIST(LogicalType::BIGINT), ListRangeFunction)); + generate_series.AddFunction(ScalarFunction({LogicalType::BIGINT}, LogicalType::LIST(LogicalType::BIGINT), + ListRangeFunction)); generate_series.AddFunction(ScalarFunction({LogicalType::BIGINT, LogicalType::BIGINT}, - LogicalType::LIST(LogicalType::BIGINT), ListRangeFunction)); + LogicalType::LIST(LogicalType::BIGINT), + ListRangeFunction)); generate_series.AddFunction(ScalarFunction({LogicalType::BIGINT, LogicalType::BIGINT, LogicalType::BIGINT}, - LogicalType::LIST(LogicalType::BIGINT), ListRangeFunction)); + LogicalType::LIST(LogicalType::BIGINT), + ListRangeFunction)); + generate_series.AddFunction(ScalarFunction({LogicalType::TIMESTAMP, LogicalType::TIMESTAMP, LogicalType::INTERVAL}, + LogicalType::LIST(LogicalType::TIMESTAMP), + ListRangeFunction)); set.AddFunction(generate_series); } @@ -84643,13 +85255,14 @@ void FillResult(Value &values, Vector &result, idx_t row) { //! First Initialize List Vector idx_t current_offset = ListVector::GetListSize(result); //! Push Values to List Vector - for (idx_t i = 0; i < values.list_value.size(); i++) { - ListVector::PushBack(result, values.list_value[i]); + auto &list_values = ListValue::GetChildren(values); + for (idx_t i = 0; i < list_values.size(); i++) { + ListVector::PushBack(result, list_values[i]); } //! now set the pointer auto &entry = ((list_entry_t *)result.GetData())[row]; - entry.length = values.list_value.size(); + entry.length = list_values.size(); entry.offset = current_offset; } @@ -85034,7 +85647,7 @@ unique_ptr DecimalUnaryOpBind(ClientContext &context, ScalarFuncti void AbsFun::RegisterFunction(BuiltinFunctions &set) { ScalarFunctionSet abs("abs"); - for (auto &type : LogicalType::NUMERIC) { + for (auto &type : LogicalType::Numeric()) { if (type.id() == LogicalTypeId::DECIMAL) { abs.AddFunction(ScalarFunction({type}, type, nullptr, false, DecimalUnaryOpBind)); } else { @@ -85092,7 +85705,7 @@ struct SignOperator { void SignFun::RegisterFunction(BuiltinFunctions &set) { ScalarFunctionSet sign("sign"); - for (auto &type : LogicalType::NUMERIC) { + for (auto &type : LogicalType::Numeric()) { if (type.id() == LogicalTypeId::DECIMAL) { continue; } else { @@ -85168,7 +85781,7 @@ struct CeilDecimalOperator { void CeilFun::RegisterFunction(BuiltinFunctions &set) { ScalarFunctionSet ceil("ceil"); - for (auto &type : LogicalType::NUMERIC) { + for (auto &type : LogicalType::Numeric()) { scalar_function_t func = nullptr; bind_scalar_function_t bind_func = nullptr; if (type.IsIntegral()) { @@ -85224,7 +85837,7 @@ struct FloorDecimalOperator { void FloorFun::RegisterFunction(BuiltinFunctions &set) { ScalarFunctionSet floor("floor"); - for (auto &type : LogicalType::NUMERIC) { + for (auto &type : LogicalType::Numeric()) { scalar_function_t func = nullptr; bind_scalar_function_t bind_func = nullptr; if (type.IsIntegral()) { @@ -85368,7 +85981,7 @@ unique_ptr BindDecimalRoundPrecision(ClientContext &context, Scala throw NotImplementedException("ROUND(DECIMAL, INTEGER) with non-constant precision is not supported"); } Value val = ExpressionExecutor::EvaluateScalar(*arguments[1]).CastAs(LogicalType::INTEGER); - if (val.is_null) { + if (val.IsNull()) { throw NotImplementedException("ROUND(DECIMAL, INTEGER) with non-constant precision is not supported"); } // our new precision becomes the round value @@ -85376,7 +85989,7 @@ unique_ptr BindDecimalRoundPrecision(ClientContext &context, Scala // but ONLY if the round value is positive // if it is negative the scale becomes zero // i.e. ROUND(DECIMAL(18,3), -1) -> DECIMAL(18,0) - int32_t round_value = val.value_.integer; + int32_t round_value = IntegerValue::Get(val); uint8_t target_scale; auto width = DecimalType::GetWidth(decimal_type); auto scale = DecimalType::GetScale(decimal_type); @@ -85426,7 +86039,7 @@ unique_ptr BindDecimalRoundPrecision(ClientContext &context, Scala void RoundFun::RegisterFunction(BuiltinFunctions &set) { ScalarFunctionSet round("round"); - for (auto &type : LogicalType::NUMERIC) { + for (auto &type : LogicalType::Numeric()) { scalar_function_t round_prec_func = nullptr; scalar_function_t round_func = nullptr; bind_scalar_function_t bind_func = nullptr; @@ -86034,36 +86647,7 @@ date_t AddOperator::Operation(int32_t left, date_t right) { template <> date_t AddOperator::Operation(date_t left, interval_t right) { - date_t result; - if (right.months != 0) { - int32_t year, month, day; - Date::Convert(left, year, month, day); - int32_t year_diff = right.months / Interval::MONTHS_PER_YEAR; - year += year_diff; - month += right.months - year_diff * Interval::MONTHS_PER_YEAR; - if (month > Interval::MONTHS_PER_YEAR) { - year++; - month -= Interval::MONTHS_PER_YEAR; - } else if (month <= 0) { - year--; - month += Interval::MONTHS_PER_YEAR; - } - day = MinValue(day, Date::MonthDays(year, month)); - result = Date::FromDate(year, month, day); - } else { - result = left; - } - if (right.days != 0) { - if (!TryAddOperator::Operation(result.days, right.days, result.days)) { - throw OutOfRangeException("Date out of range"); - } - } - if (right.micros != 0) { - if (!TryAddOperator::Operation(result.days, int32_t(right.micros / Interval::MICROS_PER_DAY), result.days)) { - throw OutOfRangeException("Date out of range"); - } - } - return result; + return Interval::Add(left, right); } template <> @@ -86071,27 +86655,9 @@ date_t AddOperator::Operation(interval_t left, date_t right) { return AddOperator::Operation(right, left); } -dtime_t AddIntervalToTimeOperation(dtime_t left, interval_t right, date_t &date) { - int64_t diff = right.micros - ((right.micros / Interval::MICROS_PER_DAY) * Interval::MICROS_PER_DAY); - left += diff; - if (left.micros >= Interval::MICROS_PER_DAY) { - left.micros -= Interval::MICROS_PER_DAY; - date.days++; - } else if (left.micros < 0) { - left.micros += Interval::MICROS_PER_DAY; - date.days--; - } - return left; -} - template <> timestamp_t AddOperator::Operation(timestamp_t left, interval_t right) { - date_t date; - dtime_t time; - Timestamp::Convert(left, date, time); - auto new_date = AddOperator::Operation(date, right); - auto new_time = AddIntervalToTimeOperation(time, right, new_date); - return Timestamp::FromDatetime(new_date, new_time); + return Interval::Add(left, right); } template <> @@ -86223,7 +86789,7 @@ hugeint_t DecimalAddOverflowCheck::Operation(hugeint_t left, hugeint_t right) { template <> dtime_t AddTimeOperator::Operation(dtime_t left, interval_t right) { date_t date(0); - return AddIntervalToTimeOperation(left, right, date); + return Interval::Add(left, right, date); } template <> @@ -86422,7 +86988,7 @@ static unique_ptr PropagateNumericStats(ClientContext &context, auto &rstats = (NumericStatistics &)*child_stats[1]; Value new_min, new_max; bool potential_overflow = true; - if (!lstats.min.is_null && !lstats.max.is_null && !rstats.min.is_null && !rstats.max.is_null) { + if (!lstats.min.IsNull() && !lstats.max.IsNull() && !rstats.min.IsNull() && !rstats.max.IsNull()) { switch (expr.return_type.InternalType()) { case PhysicalType::INT8: potential_overflow = @@ -86565,7 +87131,7 @@ ScalarFunction AddFun::GetFunction(const LogicalType &left_type, const LogicalTy break; case LogicalTypeId::INTEGER: if (right_type.id() == LogicalTypeId::DATE) { - return ScalarFunction("+", {left_type, right_type}, LogicalType::DATE, + return ScalarFunction("+", {left_type, right_type}, right_type, ScalarFunction::BinaryFunction); } break; @@ -86607,7 +87173,7 @@ ScalarFunction AddFun::GetFunction(const LogicalType &left_type, const LogicalTy void AddFun::RegisterFunction(BuiltinFunctions &set) { ScalarFunctionSet functions("+"); - for (auto &type : LogicalType::NUMERIC) { + for (auto &type : LogicalType::Numeric()) { // unary add function is a nop, but only exists for numeric types functions.AddFunction(GetFunction(type)); // binary add function adds two numbers together @@ -86637,11 +87203,16 @@ void AddFun::RegisterFunction(BuiltinFunctions &set) { // - [subtract] //===--------------------------------------------------------------------===// struct NegateOperator { + template + static bool CanNegate(T input) { + using Limits = std::numeric_limits; + return !(Limits::is_integer && Limits::is_signed && Limits::lowest() == input); + } + template static inline TR Operation(TA input) { - using Limits = std::numeric_limits; auto cast = (TR)input; - if (Limits::is_integer && Limits::is_signed && Limits::lowest() == cast) { + if (!CanNegate(cast)) { throw OutOfRangeException("Overflow in negation of integer!"); } return -cast; @@ -86679,11 +87250,17 @@ unique_ptr DecimalNegateBind(ClientContext &context, ScalarFunctio struct NegatePropagateStatistics { template - static void Operation(LogicalType type, NumericStatistics &istats, Value &new_min, Value &new_max) { + static bool Operation(LogicalType type, NumericStatistics &istats, Value &new_min, Value &new_max) { + auto max_value = istats.max.GetValueUnsafe(); + auto min_value = istats.min.GetValueUnsafe(); + if (!NegateOperator::CanNegate(min_value) || !NegateOperator::CanNegate(max_value)) { + return true; + } // new min is -max - new_min = Value::Numeric(type, NegateOperator::Operation(istats.max.GetValueUnsafe())); + new_min = Value::Numeric(type, NegateOperator::Operation(max_value)); // new max is -min - new_max = Value::Numeric(type, NegateOperator::Operation(istats.min.GetValueUnsafe())); + new_max = Value::Numeric(type, NegateOperator::Operation(min_value)); + return false; } }; @@ -86697,24 +87274,33 @@ static unique_ptr NegateBindStatistics(ClientContext &context, B } auto &istats = (NumericStatistics &)*child_stats[0]; Value new_min, new_max; - if (!istats.min.is_null && !istats.max.is_null) { + bool potential_overflow = true; + if (!istats.min.IsNull() && !istats.max.IsNull()) { switch (expr.return_type.InternalType()) { case PhysicalType::INT8: - NegatePropagateStatistics::Operation(expr.return_type, istats, new_min, new_max); + potential_overflow = + NegatePropagateStatistics::Operation(expr.return_type, istats, new_min, new_max); break; case PhysicalType::INT16: - NegatePropagateStatistics::Operation(expr.return_type, istats, new_min, new_max); + potential_overflow = + NegatePropagateStatistics::Operation(expr.return_type, istats, new_min, new_max); break; case PhysicalType::INT32: - NegatePropagateStatistics::Operation(expr.return_type, istats, new_min, new_max); + potential_overflow = + NegatePropagateStatistics::Operation(expr.return_type, istats, new_min, new_max); break; case PhysicalType::INT64: - NegatePropagateStatistics::Operation(expr.return_type, istats, new_min, new_max); + potential_overflow = + NegatePropagateStatistics::Operation(expr.return_type, istats, new_min, new_max); break; default: return nullptr; } } + if (potential_overflow) { + 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)); if (istats.validity_stats) { stats->validity_stats = istats.validity_stats->Copy(); @@ -86797,7 +87383,7 @@ ScalarFunction SubtractFun::GetFunction(const LogicalType &left_type, const Logi void SubtractFun::RegisterFunction(BuiltinFunctions &set) { ScalarFunctionSet functions("-"); - for (auto &type : LogicalType::NUMERIC) { + for (auto &type : LogicalType::Numeric()) { // unary subtract function, negates the input (i.e. multiplies by -1) functions.AddFunction(GetFunction(type)); // binary subtract function "a - b", subtracts b from a @@ -86805,6 +87391,7 @@ void SubtractFun::RegisterFunction(BuiltinFunctions &set) { } // we can subtract dates from each other functions.AddFunction(GetFunction(LogicalType::DATE, LogicalType::DATE)); + // we can subtract integers from dates functions.AddFunction(GetFunction(LogicalType::DATE, LogicalType::INTEGER)); // we can subtract timestamps from each other functions.AddFunction(GetFunction(LogicalType::TIMESTAMP, LogicalType::TIMESTAMP)); @@ -86929,7 +87516,7 @@ unique_ptr BindDecimalMultiply(ClientContext &context, ScalarFunct void MultiplyFun::RegisterFunction(BuiltinFunctions &set) { ScalarFunctionSet functions("*"); - for (auto &type : LogicalType::NUMERIC) { + for (auto &type : LogicalType::Numeric()) { if (type.id() == LogicalTypeId::DECIMAL) { functions.AddFunction(ScalarFunction({type, type}, type, nullptr, false, BindDecimalMultiply)); } else if (TypeIsIntegral(type.InternalType()) && type.id() != LogicalTypeId::HUGEINT) { @@ -87057,7 +87644,7 @@ static scalar_function_t GetBinaryFunctionIgnoreZero(const LogicalType &type) { void DivideFun::RegisterFunction(BuiltinFunctions &set) { ScalarFunctionSet functions("/"); - for (auto &type : LogicalType::NUMERIC) { + for (auto &type : LogicalType::Numeric()) { if (type.id() == LogicalTypeId::DECIMAL) { continue; } else { @@ -87097,7 +87684,7 @@ hugeint_t ModuloOperator::Operation(hugeint_t left, hugeint_t right) { void ModFun::RegisterFunction(BuiltinFunctions &set) { ScalarFunctionSet functions("%"); - for (auto &type : LogicalType::NUMERIC) { + for (auto &type : LogicalType::Numeric()) { if (type.id() == LogicalTypeId::DECIMAL) { continue; } else { @@ -87202,7 +87789,7 @@ struct BitwiseANDOperator { void BitwiseAndFun::RegisterFunction(BuiltinFunctions &set) { ScalarFunctionSet functions("&"); - for (auto &type : LogicalType::INTEGRAL) { + for (auto &type : LogicalType::Integral()) { functions.AddFunction( ScalarFunction({type, type}, type, GetScalarIntegerBinaryFunction(type))); } @@ -87221,7 +87808,7 @@ struct BitwiseOROperator { void BitwiseOrFun::RegisterFunction(BuiltinFunctions &set) { ScalarFunctionSet functions("|"); - for (auto &type : LogicalType::INTEGRAL) { + for (auto &type : LogicalType::Integral()) { functions.AddFunction( ScalarFunction({type, type}, type, GetScalarIntegerBinaryFunction(type))); } @@ -87240,7 +87827,7 @@ struct BitwiseXOROperator { void BitwiseXorFun::RegisterFunction(BuiltinFunctions &set) { ScalarFunctionSet functions("xor"); - for (auto &type : LogicalType::INTEGRAL) { + for (auto &type : LogicalType::Integral()) { functions.AddFunction( ScalarFunction({type, type}, type, GetScalarIntegerBinaryFunction(type))); } @@ -87264,7 +87851,7 @@ struct BitwiseShiftLeftOperator { void LeftShiftFun::RegisterFunction(BuiltinFunctions &set) { ScalarFunctionSet functions("<<"); - for (auto &type : LogicalType::INTEGRAL) { + for (auto &type : LogicalType::Integral()) { functions.AddFunction( ScalarFunction({type, type}, type, GetScalarIntegerBinaryFunction(type))); } @@ -87283,7 +87870,7 @@ struct BitwiseShiftRightOperator { void RightShiftFun::RegisterFunction(BuiltinFunctions &set) { ScalarFunctionSet functions(">>"); - for (auto &type : LogicalType::INTEGRAL) { + for (auto &type : LogicalType::Integral()) { functions.AddFunction( ScalarFunction({type, type}, type, GetScalarIntegerBinaryFunction(type))); } @@ -87302,7 +87889,7 @@ struct BitwiseNotOperator { void BitwiseNotFun::RegisterFunction(BuiltinFunctions &set) { ScalarFunctionSet functions("~"); - for (auto &type : LogicalType::INTEGRAL) { + for (auto &type : LogicalType::Integral()) { functions.AddFunction(ScalarFunction({type}, type, GetScalarIntegerUnaryFunction(type))); } set.AddFunction(functions); @@ -87828,6 +88415,7 @@ struct CurrvalFun { + namespace duckdb { struct NextvalBindData : public FunctionData { @@ -87860,9 +88448,12 @@ struct NextSequenceValueOperator { static int64_t Operation(Transaction &transaction, SequenceCatalogEntry *seq) { lock_guard seqlock(seq->lock); int64_t result; + result = seq->counter; + bool overflow = !TryAddOperator::Operation(seq->counter, seq->increment, seq->counter); if (seq->cycle) { - result = seq->counter; - seq->counter += seq->increment; + if (overflow) { + throw SequenceException("overflow in sequence"); + } if (result < seq->min_value) { result = seq->max_value; seq->counter = seq->max_value + seq->increment; @@ -87871,13 +88462,11 @@ struct NextSequenceValueOperator { seq->counter = seq->min_value + seq->increment; } } else { - result = seq->counter; - seq->counter += seq->increment; - if (result < seq->min_value) { + if (result < seq->min_value || (overflow && seq->increment < 0)) { throw SequenceException("nextval: reached minimum value of sequence \"%s\" (%lld)", seq->name, seq->min_value); } - if (result > seq->max_value) { + if (result > seq->max_value || overflow) { throw SequenceException("nextval: reached maximum value of sequence \"%s\" (%lld)", seq->name, seq->max_value); } @@ -87934,10 +88523,10 @@ static unique_ptr NextValBind(ClientContext &context, ScalarFuncti if (arguments[0]->IsFoldable()) { // parameter to nextval function is a foldable constant // evaluate the constant and perform the catalog lookup already - Value seqname = ExpressionExecutor::EvaluateScalar(*arguments[0]); - if (!seqname.is_null) { + auto seqname = ExpressionExecutor::EvaluateScalar(*arguments[0]); + if (!seqname.IsNull()) { D_ASSERT(seqname.type().id() == LogicalTypeId::VARCHAR); - auto qname = QualifiedName::Parse(seqname.str_value); + auto qname = QualifiedName::Parse(StringValue::Get(seqname)); sequence = Catalog::GetCatalog(context).GetEntry(context, qname.schema, qname.name); } } @@ -88404,7 +88993,7 @@ static void ConcatWSFunction(DataChunk &args, ExpressionState &state, Vector &re } } switch (separator.GetVectorType()) { - case VectorType::CONSTANT_VECTOR: + case VectorType::CONSTANT_VECTOR: { if (ConstantVector::IsNull(separator)) { // constant NULL as separator: return constant NULL vector result.SetVectorType(VectorType::CONSTANT_VECTOR); @@ -88412,9 +89001,11 @@ static void ConcatWSFunction(DataChunk &args, ExpressionState &state, Vector &re return; } // no null values - TemplatedConcatWS(args, (string_t *)vdata.data, *vdata.sel, FlatVector::INCREMENTAL_SELECTION_VECTOR, - args.size(), result); + SelectionVector owned_sel; + auto sel = FlatVector::IncrementalSelectionVector(args.size(), owned_sel); + TemplatedConcatWS(args, (string_t *)vdata.data, *vdata.sel, *sel, args.size(), result); return; + } default: { // default case: loop over nullmask and create a non-null selection vector idx_t not_null_count = 0; @@ -88480,7 +89071,7 @@ static idx_t ContainsUnaligned(const unsigned char *haystack, idx_t haystack_siz idx_t base_offset) { if (NEEDLE_SIZE > haystack_size) { // needle is bigger than haystack: haystack cannot contain needle - return INVALID_INDEX; + return DConstants::INVALID_INDEX; } // contains for a small unaligned needle (3/5/6/7 bytes) // we perform unsigned integer comparisons to check for equality of the entire needle in a single comparison @@ -88511,7 +89102,7 @@ static idx_t ContainsUnaligned(const unsigned char *haystack, idx_t haystack_siz if (haystack_entry == needle_entry) { return base_offset + haystack_size - NEEDLE_SIZE; } - return INVALID_INDEX; + return DConstants::INVALID_INDEX; } template @@ -88519,7 +89110,7 @@ static idx_t ContainsAligned(const unsigned char *haystack, idx_t haystack_size, idx_t base_offset) { if (sizeof(UNSIGNED) > haystack_size) { // needle is bigger than haystack: haystack cannot contain needle - return INVALID_INDEX; + return DConstants::INVALID_INDEX; } // contains for a small needle aligned with unsigned integer (2/4/8) // similar to ContainsUnaligned, but simpler because we only need to do a reinterpret cast @@ -88531,14 +89122,14 @@ static idx_t ContainsAligned(const unsigned char *haystack, idx_t haystack_size, return base_offset + offset; } } - return INVALID_INDEX; + return DConstants::INVALID_INDEX; } idx_t ContainsGeneric(const unsigned char *haystack, idx_t haystack_size, const unsigned char *needle, idx_t needle_size, idx_t base_offset) { if (needle_size > haystack_size) { // needle is bigger than haystack: haystack cannot contain needle - return INVALID_INDEX; + return DConstants::INVALID_INDEX; } // this implementation is inspired by Raphael Javaux's faststrstr (https://github.com/RaphaelJ/fast_strstr) // generic contains; note that we can't use strstr because we don't have null-terminated strings anymore @@ -88559,7 +89150,7 @@ idx_t ContainsGeneric(const unsigned char *haystack, idx_t haystack_size, const } } if (offset >= haystack_size - needle_size) { - return INVALID_INDEX; + return DConstants::INVALID_INDEX; } sums_diff -= haystack[offset]; sums_diff += haystack[offset + needle_size]; @@ -88573,7 +89164,7 @@ idx_t ContainsFun::Find(const unsigned char *haystack, idx_t haystack_size, cons // start off by performing a memchr to find the first character of the auto location = memchr(haystack, needle[0], haystack_size); if (location == nullptr) { - return INVALID_INDEX; + return DConstants::INVALID_INDEX; } idx_t base_offset = (const unsigned char *)location - haystack; haystack_size -= base_offset; @@ -88616,7 +89207,7 @@ idx_t ContainsFun::Find(const string_t &haystack_s, const string_t &needle_s) { struct ContainsOperator { template static inline TR Operation(TA left, TB right) { - return ContainsFun::Find(left, right) != INVALID_INDEX; + return ContainsFun::Find(left, right) != DConstants::INVALID_INDEX; } }; @@ -88648,7 +89239,7 @@ struct InstrOperator { int64_t string_position = 0; auto location = ContainsFun::Find(haystack, needle); - if (location != INVALID_INDEX) { + if (location != DConstants::INVALID_INDEX) { auto len = (utf8proc_ssize_t)location; auto str = reinterpret_cast(haystack.GetDataUnsafe()); D_ASSERT(len <= (utf8proc_ssize_t)haystack.GetSize()); @@ -88667,7 +89258,7 @@ struct InstrAsciiOperator { template static inline TR Operation(TA haystack, TB needle) { auto location = ContainsFun::Find(haystack, needle); - return location == INVALID_INDEX ? 0 : location + 1; + return location == DConstants::INVALID_INDEX ? 0 : location + 1; } }; @@ -88696,6 +89287,8 @@ void InstrFun::RegisterFunction(BuiltinFunctions &set) { set.AddFunction(instr); instr.name = "strpos"; set.AddFunction(instr); + instr.name = "position"; + set.AddFunction(instr); } } // namespace duckdb @@ -89150,7 +89743,7 @@ struct LikeMatcher : public FunctionData { // find the pattern of the current segment idx_t next_offset = ContainsFun::Find(str_data, str_len, (const unsigned char *)segment.pattern.c_str(), segment.pattern.size()); - if (next_offset == INVALID_INDEX) { + if (next_offset == DConstants::INVALID_INDEX) { // could not find this pattern in the string: no match return false; } @@ -89175,7 +89768,7 @@ struct LikeMatcher : public FunctionData { // find the pattern of the current segment idx_t next_offset = ContainsFun::Find(str_data, str_len, (const unsigned char *)segment.pattern.c_str(), segment.pattern.size()); - return next_offset != INVALID_INDEX; + return next_offset != DConstants::INVALID_INDEX; } } @@ -89921,11 +90514,11 @@ unique_ptr BindPrintfFunction(ClientContext &context, ScalarFuncti break; case LogicalTypeId::DECIMAL: // decimal type: add cast to double - bound_function.arguments.push_back(LogicalType::DOUBLE); + bound_function.arguments.emplace_back(LogicalType::DOUBLE); break; default: // all other types: add cast to string - bound_function.arguments.push_back(LogicalType::VARCHAR); + bound_function.arguments.emplace_back(LogicalType::VARCHAR); break; } } @@ -91321,7 +91914,7 @@ static inline duckdb_re2::StringPiece CreateStringPiece(string_t &input) { return duckdb_re2::StringPiece(input.GetDataUnsafe(), input.GetSize()); } -static void ParseRegexOptions(string &options, duckdb_re2::RE2::Options &result, bool *global_replace = nullptr) { +static void ParseRegexOptions(const string &options, duckdb_re2::RE2::Options &result, bool *global_replace = nullptr) { for (idx_t i = 0; i < options.size(); i++) { switch (options[i]) { case 'c': @@ -91432,15 +92025,15 @@ static unique_ptr RegexpMatchesBind(ClientContext &context, Scalar throw InvalidInputException("Regex options field must be a constant"); } Value options_str = ExpressionExecutor::EvaluateScalar(*arguments[2]); - if (!options_str.is_null && options_str.type().id() == LogicalTypeId::VARCHAR) { - ParseRegexOptions(options_str.str_value, options); + if (!options_str.IsNull() && options_str.type().id() == LogicalTypeId::VARCHAR) { + ParseRegexOptions(StringValue::Get(options_str), options); } } if (arguments[1]->IsFoldable()) { Value pattern_str = ExpressionExecutor::EvaluateScalar(*arguments[1]); - if (!pattern_str.is_null && pattern_str.type().id() == LogicalTypeId::VARCHAR) { - return make_unique(options, pattern_str.str_value); + if (!pattern_str.IsNull() && pattern_str.type().id() == LogicalTypeId::VARCHAR) { + return make_unique(options, StringValue::Get(pattern_str)); } } return make_unique(options, ""); @@ -91483,8 +92076,8 @@ static unique_ptr RegexReplaceBind(ClientContext &context, ScalarF throw InvalidInputException("Regex options field must be a constant"); } Value options_str = ExpressionExecutor::EvaluateScalar(*arguments[3]); - if (!options_str.is_null && options_str.type().id() == LogicalTypeId::VARCHAR) { - ParseRegexOptions(options_str.str_value, data->options, &data->global_replace); + if (!options_str.IsNull() && options_str.type().id() == LogicalTypeId::VARCHAR) { + ParseRegexOptions(StringValue::Get(options_str), data->options, &data->global_replace); } } @@ -91545,8 +92138,8 @@ static unique_ptr RegexExtractBind(ClientContext &context, ScalarF string pattern = ""; if (constant_pattern) { Value pattern_str = ExpressionExecutor::EvaluateScalar(*arguments[1]); - if (!pattern_str.is_null && pattern_str.type().id() == LogicalTypeId::VARCHAR) { - pattern = pattern_str.str_value; + if (!pattern_str.IsNull() && pattern_str.type().id() == LogicalTypeId::VARCHAR) { + pattern = StringValue::Get(pattern_str); } } @@ -91556,7 +92149,7 @@ static unique_ptr RegexExtractBind(ClientContext &context, ScalarF throw InvalidInputException("Group index field field must be a constant!"); } Value group = ExpressionExecutor::EvaluateScalar(*arguments[2]); - if (!group.is_null) { + if (!group.IsNull()) { auto group_idx = group.GetValue(); if (group_idx < 0 || group_idx > 9) { throw InvalidInputException("Group index must be between 0 and 9!"); @@ -92175,7 +92768,7 @@ string_t SubstringASCII(Vector &result, string_t input, int64_t offset, int64_t return SubstringSlice(result, input_data, start, end - start); } -string_t SubstringFun::SubstringScalarFunction(Vector &result, string_t input, int32_t offset, int32_t length) { +string_t SubstringFun::SubstringScalarFunction(Vector &result, string_t input, int64_t offset, int64_t length) { auto input_data = input.GetDataUnsafe(); auto input_size = input.GetSize(); @@ -92218,7 +92811,7 @@ string_t SubstringFun::SubstringScalarFunction(Vector &result, string_t input, i // now scan the graphemes of the string to find the positions of the start and end characters int64_t current_character = 0; - idx_t start_pos = INVALID_INDEX, end_pos = input_size; + idx_t start_pos = DConstants::INVALID_INDEX, end_pos = input_size; utf8proc_grapheme_callback(input_data, input_size, [&](size_t gstart, size_t gend) { if (current_character == start) { start_pos = gstart; @@ -92229,7 +92822,7 @@ string_t SubstringFun::SubstringScalarFunction(Vector &result, string_t input, i current_character++; return true; }); - if (start_pos == INVALID_INDEX) { + if (start_pos == DConstants::INVALID_INDEX) { return SubstringEmptyString(result); } // after we have found these, we can slice the substring @@ -92242,16 +92835,16 @@ static void SubstringFunction(DataChunk &args, ExpressionState &state, Vector &r if (args.ColumnCount() == 3) { auto &length_vector = args.data[2]; - TernaryExecutor::Execute( + TernaryExecutor::Execute( input_vector, offset_vector, length_vector, result, args.size(), - [&](string_t input_string, int32_t offset, int32_t length) { + [&](string_t input_string, int64_t offset, int64_t length) { return SubstringFun::SubstringScalarFunction(result, input_string, offset, length); }); } else { - BinaryExecutor::Execute( - input_vector, offset_vector, result, args.size(), [&](string_t input_string, int32_t offset) { + BinaryExecutor::Execute( + input_vector, offset_vector, result, args.size(), [&](string_t input_string, int64_t offset) { return SubstringFun::SubstringScalarFunction(result, input_string, offset, - NumericLimits::Maximum()); + NumericLimits::Maximum() - offset); }); } } @@ -92262,15 +92855,15 @@ static void SubstringFunctionASCII(DataChunk &args, ExpressionState &state, Vect if (args.ColumnCount() == 3) { auto &length_vector = args.data[2]; - TernaryExecutor::Execute( + TernaryExecutor::Execute( input_vector, offset_vector, length_vector, result, args.size(), - [&](string_t input_string, int32_t offset, int32_t length) { + [&](string_t input_string, int64_t offset, int64_t length) { return SubstringASCII(result, input_string, offset, length); }); } else { - BinaryExecutor::Execute( - input_vector, offset_vector, result, args.size(), [&](string_t input_string, int32_t offset) { - return SubstringASCII(result, input_string, offset, NumericLimits::Maximum()); + BinaryExecutor::Execute( + input_vector, offset_vector, result, args.size(), [&](string_t input_string, int64_t offset) { + return SubstringASCII(result, input_string, offset, NumericLimits::Maximum() - offset); }); } } @@ -92292,10 +92885,10 @@ static unique_ptr SubstringPropagateStats(ClientContext &context void SubstringFun::RegisterFunction(BuiltinFunctions &set) { ScalarFunctionSet substr("substring"); - substr.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::INTEGER, LogicalType::INTEGER}, + substr.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::BIGINT, LogicalType::BIGINT}, LogicalType::VARCHAR, SubstringFunction, false, nullptr, nullptr, SubstringPropagateStats)); - substr.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::INTEGER}, LogicalType::VARCHAR, + substr.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::BIGINT}, LogicalType::VARCHAR, SubstringFunction, false, nullptr, nullptr, SubstringPropagateStats)); set.AddFunction(substr); substr.name = "substr"; @@ -92595,19 +93188,20 @@ class StructStatistics : public BaseStatistics { public: void Merge(const BaseStatistics &other) override; - FilterPropagateResult CheckZonemap(ExpressionType comparison_type, const Value &constant); + FilterPropagateResult CheckZonemap(ExpressionType comparison_type, const Value &constant) const; - unique_ptr Copy() override; - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(Deserializer &source, LogicalType type); - void Verify(Vector &vector, const SelectionVector &sel, idx_t count) override; + unique_ptr Copy() const override; + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(FieldReader &reader, LogicalType type); + void Verify(Vector &vector, const SelectionVector &sel, idx_t count) const override; - string ToString() override; + string ToString() const override; }; } // namespace duckdb + namespace duckdb { struct StructExtractBindData : public FunctionData { @@ -92671,14 +93265,15 @@ static unique_ptr StructExtractBind(ClientContext &context, Scalar if (key_child->return_type.id() != LogicalTypeId::VARCHAR || key_child->return_type.id() != LogicalTypeId::VARCHAR || !key_child->IsFoldable()) { - throw Exception("Key name for struct_extract needs to be a constant string"); + throw BinderException("Key name for struct_extract needs to be a constant string"); } Value key_val = ExpressionExecutor::EvaluateScalar(*key_child.get()); D_ASSERT(key_val.type().id() == LogicalTypeId::VARCHAR); - if (key_val.is_null || key_val.str_value.length() < 1) { - throw Exception("Key name for struct_extract needs to be neither NULL nor empty"); + auto &key_str = StringValue::Get(key_val); + if (key_val.IsNull() || key_str.empty()) { + throw BinderException("Key name for struct_extract needs to be neither NULL nor empty"); } - string key = StringUtil::Lower(key_val.str_value); + string key = StringUtil::Lower(key_str); LogicalType return_type; idx_t key_index = 0; @@ -92686,15 +93281,23 @@ static unique_ptr StructExtractBind(ClientContext &context, Scalar for (size_t i = 0; i < struct_children.size(); i++) { auto &child = struct_children[i]; - if (child.first == key) { + if (StringUtil::Lower(child.first) == key) { found_key = true; key_index = i; return_type = child.second; break; } } + if (!found_key) { - throw Exception("Could not find key in struct"); + vector candidates; + candidates.reserve(struct_children.size()); + for (auto &struct_child : struct_children) { + candidates.push_back(struct_child.first); + } + auto closest_settings = StringUtil::TopNLevenshtein(candidates, key); + auto message = StringUtil::CandidatesMessage(closest_settings, "Candidate Entries"); + throw BinderException("Could not find key \"%s\" in struct\n%s", key, message); } bound_function.return_type = return_type; @@ -92761,7 +93364,7 @@ static void StructPackFunction(DataChunk &args, ExpressionState &state, Vector & static unique_ptr StructPackBind(ClientContext &context, ScalarFunction &bound_function, vector> &arguments) { - unordered_set name_collision_set; + case_insensitive_set_t name_collision_set; // collect names and deconflict, construct return type if (arguments.empty()) { @@ -92843,8 +93446,7 @@ unique_ptr BindSystemFunction(ClientContext &context, ScalarFuncti static void CurrentQueryFunction(DataChunk &input, ExpressionState &state, Vector &result) { auto &info = SystemBindData::GetFrom(state); - - Value val(info.context.query); + Value val(info.context.GetCurrentQuery()); result.Reference(val); } @@ -92884,7 +93486,7 @@ void SystemFun::RegisterFunction(BuiltinFunctions &set) { auto varchar_list_type = LogicalType::LIST(LogicalType::VARCHAR); set.AddFunction( - ScalarFunction("current_query", {}, LogicalType::VARCHAR, CurrentQueryFunction, false, BindSystemFunction)); + ScalarFunction("current_query", {}, LogicalType::VARCHAR, CurrentQueryFunction, true, BindSystemFunction)); set.AddFunction( ScalarFunction("current_schema", {}, LogicalType::VARCHAR, CurrentSchemaFunction, false, BindSystemFunction)); set.AddFunction(ScalarFunction("current_schemas", {LogicalType::BOOLEAN}, varchar_list_type, CurrentSchemasFunction, @@ -92980,9 +93582,84 @@ static void GenerateUUIDFunction(DataChunk &args, ExpressionState &state, Vector } void UUIDFun::RegisterFunction(BuiltinFunctions &set) { + ScalarFunction uuid_function({}, LogicalType::UUID, GenerateUUIDFunction, true, UUIDRandomBind); // generate a random uuid - set.AddFunction( - ScalarFunction("gen_random_uuid", {}, LogicalType::UUID, GenerateUUIDFunction, true, UUIDRandomBind)); + set.AddFunction({"uuid", "gen_random_uuid"}, uuid_function); +} + +} // namespace duckdb + + +namespace duckdb { + +ScalarFunction::ScalarFunction(string name, vector arguments, LogicalType return_type, + scalar_function_t function, bool has_side_effects, bind_scalar_function_t bind, + dependency_function_t dependency, function_statistics_t statistics, + init_local_state_t init_local_state, LogicalType varargs) + : BaseScalarFunction(move(name), move(arguments), move(return_type), has_side_effects, move(varargs)), + function(move(function)), bind(bind), init_local_state(init_local_state), dependency(dependency), + statistics(statistics) { +} + +ScalarFunction::ScalarFunction(vector arguments, LogicalType return_type, scalar_function_t function, + bool has_side_effects, bind_scalar_function_t bind, dependency_function_t dependency, + function_statistics_t statistics, init_local_state_t init_local_state, + LogicalType varargs) + : ScalarFunction(string(), move(arguments), move(return_type), move(function), has_side_effects, bind, dependency, + statistics, init_local_state, move(varargs)) { +} + +bool ScalarFunction::operator==(const ScalarFunction &rhs) const { + return CompareScalarFunctionT(rhs.function) && bind == rhs.bind && dependency == rhs.dependency && + statistics == rhs.statistics; +} +bool ScalarFunction::operator!=(const ScalarFunction &rhs) const { + return !(*this == rhs); +} + +bool ScalarFunction::Equal(const ScalarFunction &rhs) const { + // number of types + if (this->arguments.size() != rhs.arguments.size()) { + return false; + } + // argument types + for (idx_t i = 0; i < this->arguments.size(); ++i) { + if (this->arguments[i] != rhs.arguments[i]) { + return false; + } + } + // return type + if (this->return_type != rhs.return_type) { + return false; + } + // varargs + if (this->varargs != rhs.varargs) { + return false; + } + + return true; // they are equal +} + +bool ScalarFunction::CompareScalarFunctionT(const scalar_function_t &other) const { + typedef void(scalar_function_ptr_t)(DataChunk &, ExpressionState &, Vector &); + + auto func_ptr = (scalar_function_ptr_t **)function.template target(); + auto other_ptr = (scalar_function_ptr_t **)other.template target(); + + // Case the functions were created from lambdas the target will return a nullptr + if (!func_ptr && !other_ptr) { + return true; + } + if (func_ptr == nullptr || other_ptr == nullptr) { + // scalar_function_t (std::functions) from lambdas cannot be compared + return false; + } + return ((size_t)*func_ptr == (size_t)*other_ptr); +} + +void ScalarFunction::NopFunction(DataChunk &input, ExpressionState &state, Vector &result) { + D_ASSERT(input.ColumnCount() >= 1); + result.Reference(input.data[0]); } } // namespace duckdb @@ -93011,6 +93688,21 @@ void UUIDFun::RegisterFunction(BuiltinFunctions &set) { +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/thread.hpp +// +// +//===----------------------------------------------------------------------===// + + + +#include + +namespace duckdb { +using std::thread; +} #include #include @@ -93090,7 +93782,7 @@ struct ArrowScanState : public FunctionOperatorData { explicit ArrowScanState(unique_ptr current_chunk) : chunk(move(current_chunk)) { } unique_ptr stream; - unique_ptr chunk; + shared_ptr chunk; idx_t chunk_offset = 0; vector column_ids; //! Store child vectors for Arrow Dictionary Vectors (col-idx,vector) @@ -93113,7 +93805,7 @@ struct ArrowTableFunction { private: //! Binds an arrow table static unique_ptr ArrowScanBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, + named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names); @@ -93156,7 +93848,7 @@ struct ArrowTableFunction { //! Gets Arrow Table's Cardinality static unique_ptr ArrowScanCardinality(ClientContext &context, const FunctionData *bind_data); //! Gets the progress on the table scan, used for Progress Bars - static int ArrowProgress(ClientContext &context, const FunctionData *bind_data_p); + static double ArrowProgress(ClientContext &context, const FunctionData *bind_data_p); }; } // namespace duckdb @@ -93169,6 +93861,7 @@ struct ArrowTableFunction { + #include namespace duckdb { @@ -93313,20 +94006,16 @@ LogicalType GetArrowLogicalType(ArrowSchema &schema, } unique_ptr ArrowTableFunction::ArrowScanBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, + named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { - auto stream_factory_ptr = inputs[0].GetPointer(); - unique_ptr (*stream_factory_produce)( + typedef unique_ptr (*stream_factory_produce_t)( uintptr_t stream_factory_ptr, std::pair, std::vector> & project_columns, - TableFilterCollection * filters) = - (unique_ptr(*)(uintptr_t stream_factory_ptr, - std::pair, std::vector> & - project_columns, - TableFilterCollection * filters)) inputs[1] - .GetPointer(); + TableFilterCollection * filters); + auto stream_factory_ptr = inputs[0].GetPointer(); + auto stream_factory_produce = (stream_factory_produce_t)inputs[1].GetPointer(); auto rows_per_thread = inputs[2].GetValue(); std::pair, std::vector> project_columns; #ifndef DUCKDB_NO_THREADS @@ -94147,6 +94836,8 @@ void ArrowTableFunction::ArrowToDuckDB(ArrowScanState &scan_state, if (array.length != scan_state.chunk->arrow_array.length) { throw InvalidInputException("arrow_scan: array length mismatch"); } + output.data[idx].GetBuffer()->SetAuxiliaryData(make_unique(scan_state.chunk), + VectorAuxiliaryDataType::ARROW_AUXILIARY); if (array.dictionary) { ColumnArrowToDuckDBDictionary(output.data[idx], array, scan_state, output.size(), arrow_convert_data, col_idx, arrow_convert_idx); @@ -94202,7 +94893,7 @@ void ArrowTableFunction::ArrowScanFunctionParallel(ClientContext &context, const idx_t ArrowTableFunction::ArrowScanMaxThreads(ClientContext &context, const FunctionData *bind_data_p) { auto &bind_data = (const ArrowScanFunctionData &)*bind_data_p; - if (bind_data.number_of_rows <= 0 || context.verify_parallelism) { + if (bind_data.number_of_rows <= 0 || ClientConfig::GetConfig(context).verify_parallelism) { return context.db->NumberOfThreads(); } return ((bind_data.number_of_rows + bind_data.rows_per_thread - 1) / bind_data.rows_per_thread) + 1; @@ -94255,12 +94946,12 @@ unique_ptr ArrowTableFunction::ArrowScanCardinality(ClientContex return make_unique(bind_data.number_of_rows, bind_data.number_of_rows); } -int ArrowTableFunction::ArrowProgress(ClientContext &context, const FunctionData *bind_data_p) { +double ArrowTableFunction::ArrowProgress(ClientContext &context, const FunctionData *bind_data_p) { auto &bind_data = (const ArrowScanFunctionData &)*bind_data_p; if (bind_data.number_of_rows == 0) { return 100; } - auto percentage = bind_data.lines_read * 100 / bind_data.number_of_rows; + auto percentage = bind_data.lines_read * 100.0 / bind_data.number_of_rows; return percentage; } @@ -94321,11 +95012,11 @@ struct UnnestTableFunction { namespace duckdb { static unique_ptr CheckpointBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, + named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { - return_types.push_back(LogicalType::BOOLEAN); + return_types.emplace_back(LogicalType::BOOLEAN); names.emplace_back("Success"); return nullptr; } @@ -94450,7 +95141,7 @@ static bool ParseBoolean(vector &set) { set[0].type().id() == LogicalTypeId::DECIMAL) { throw BinderException("Expected a boolean value (e.g. TRUE or 1)"); } - return set[0].CastAs(LogicalType::BOOLEAN).value_.boolean; + return BooleanValue::Get(set[0].CastAs(LogicalType::BOOLEAN)); } static string ParseString(vector &set) { @@ -94477,11 +95168,7 @@ static int64_t ParseInteger(vector &set) { //===--------------------------------------------------------------------===// static bool ParseBaseOption(BufferedCSVReaderOptions &options, string &loption, vector &set) { if (StringUtil::StartsWith(loption, "delim") || StringUtil::StartsWith(loption, "sep")) { - options.delimiter = ParseString(set); - options.has_delimiter = true; - if (options.delimiter.length() == 0) { - throw BinderException("DELIM or SEP must not be empty"); - } + options.SetDelimiter(ParseString(set)); } else if (loption == "quote") { options.quote = ParseString(set); options.has_quote = true; @@ -94499,13 +95186,11 @@ static bool ParseBaseOption(BufferedCSVReaderOptions &options, string &loption, throw BinderException("Copy is only supported for UTF-8 encoded files, ENCODING 'UTF-8'"); } } else if (loption == "compression") { - options.compression = ParseString(set); - if (!(options.compression == "infer" || options.compression == "gzip" || options.compression == "none" || - options.compression.empty())) { - throw BinderException("read_csv currently only supports 'gzip' compression."); - } + options.compression = FileCompressionTypeFromString(ParseString(set)); } else if (loption == "skip") { options.skip_rows = ParseInteger(set); + } else if (loption == "max_line_size" || loption == "maximum_line_size") { + options.maximum_line_size = ParseInteger(set); } else { // unrecognized option in base CSV return false; @@ -94743,12 +95428,12 @@ 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(), - options.delimiter.size()) != INVALID_INDEX) { + 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(), - options.quote.size()) != INVALID_INDEX) { + options.quote.size()) != DConstants::INVALID_INDEX) { return true; } return false; @@ -94778,10 +95463,10 @@ static void WriteQuotedString(Serializer &serializer, WriteCSVData &csv_data, co // complex CSV // check for quote or escape separately if (ContainsFun::Find((const unsigned char *)str, len, (const unsigned char *)options.quote.c_str(), - options.quote.size()) != INVALID_INDEX) { + 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(), - options.escape.size()) != INVALID_INDEX) { + options.escape.size()) != DConstants::INVALID_INDEX) { requires_escape = true; } } @@ -94819,14 +95504,15 @@ struct LocalReadCSVData : public LocalFunctionData { }; struct GlobalWriteCSVData : public GlobalFunctionData { - GlobalWriteCSVData(FileSystem &fs, const string &file_path, FileOpener *opener) : fs(fs) { + GlobalWriteCSVData(FileSystem &fs, const string &file_path, FileOpener *opener, FileCompressionType compression) + : fs(fs) { handle = fs.OpenFile(file_path, FileFlags::FILE_FLAGS_WRITE | FileFlags::FILE_FLAGS_FILE_CREATE_NEW, - FileLockType::WRITE_LOCK, FileSystem::DEFAULT_COMPRESSION, opener); + FileLockType::WRITE_LOCK, compression, opener); } void WriteData(const_data_ptr_t data, idx_t size) { lock_guard flock(lock); - fs.Write(*handle, (void *)data, size); + handle->Write((void *)data, size); } FileSystem &fs; @@ -94852,7 +95538,7 @@ static unique_ptr WriteCSVInitializeGlobal(ClientContext &co auto &csv_data = (WriteCSVData &)bind_data; auto &options = csv_data.options; auto global_data = make_unique(FileSystem::GetFileSystem(context), csv_data.files[0], - FileSystem::GetFileOpener(context)); + FileSystem::GetFileOpener(context), options.compression); if (options.header) { BufferedSerializer serializer; @@ -94940,6 +95626,15 @@ static void WriteCSVCombine(ClientContext &context, FunctionData &bind_data, Glo } } +//===--------------------------------------------------------------------===// +// Finalize +//===--------------------------------------------------------------------===// +void WriteCSVFinalize(ClientContext &context, FunctionData &bind_data, GlobalFunctionData &gstate) { + auto &global_state = (GlobalWriteCSVData &)gstate; + global_state.handle->Close(); + global_state.handle.reset(); +} + void CSVCopyFunction::RegisterFunction(BuiltinFunctions &set) { CopyFunction info("csv"); info.copy_to_bind = WriteCSVBind; @@ -94947,6 +95642,7 @@ void CSVCopyFunction::RegisterFunction(BuiltinFunctions &set) { info.copy_to_initialize_global = WriteCSVInitializeGlobal; info.copy_to_sink = WriteCSVSink; info.copy_to_combine = WriteCSVCombine; + info.copy_to_finalize = WriteCSVFinalize; info.copy_from_bind = ReadCSVBind; info.copy_from_function = ReadCSVTableFunction::GetFunction(); @@ -94962,6 +95658,7 @@ void CSVCopyFunction::RegisterFunction(BuiltinFunctions &set) { + namespace duckdb { struct GlobFunctionBindData : public TableFunctionData { @@ -94969,14 +95666,18 @@ struct GlobFunctionBindData : public TableFunctionData { }; static unique_ptr GlobFunctionBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, + named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { + auto &config = DBConfig::GetConfig(context); + if (!config.enable_external_access) { + throw PermissionException("Globbing is disabled through configuration"); + } auto result = make_unique(); auto &fs = FileSystem::GetFileSystem(context); - result->files = fs.Glob(inputs[0].str_value); - return_types.push_back(LogicalType::VARCHAR); + result->files = fs.Glob(StringValue::Get(inputs[0])); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("file"); return move(result); } @@ -95081,6 +95782,14 @@ struct DuckDBDependenciesFun { static void RegisterFunction(BuiltinFunctions &set); }; +struct DuckDBFunctionsFun { + static void RegisterFunction(BuiltinFunctions &set); +}; + +struct DuckDBKeywordsFun { + static void RegisterFunction(BuiltinFunctions &set); +}; + struct DuckDBIndexesFun { static void RegisterFunction(BuiltinFunctions &set); }; @@ -95089,6 +95798,10 @@ struct DuckDBSequencesFun { static void RegisterFunction(BuiltinFunctions &set); }; +struct DuckDBSettingsFun { + static void RegisterFunction(BuiltinFunctions &set); +}; + struct DuckDBTablesFun { static void RegisterFunction(BuiltinFunctions &set); }; @@ -95101,6 +95814,10 @@ struct DuckDBViewsFun { static void RegisterFunction(BuiltinFunctions &set); }; +struct TestAllTypesFun { + static void RegisterFunction(BuiltinFunctions &set); +}; + } // namespace duckdb @@ -95126,37 +95843,37 @@ struct PragmaDetailedProfilingOutputData : public TableFunctionData { }; static unique_ptr PragmaDetailedProfilingOutputBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, + named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { names.emplace_back("OPERATOR_ID"); - return_types.push_back(LogicalType::INTEGER); + return_types.emplace_back(LogicalType::INTEGER); names.emplace_back("ANNOTATION"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("ID"); - return_types.push_back(LogicalType::INTEGER); + return_types.emplace_back(LogicalType::INTEGER); names.emplace_back("NAME"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("TIME"); - return_types.push_back(LogicalType::DOUBLE); + return_types.emplace_back(LogicalType::DOUBLE); names.emplace_back("CYCLES_PER_TUPLE"); - return_types.push_back(LogicalType::DOUBLE); + return_types.emplace_back(LogicalType::DOUBLE); names.emplace_back("SAMPLE_SIZE"); - return_types.push_back(LogicalType::INTEGER); + return_types.emplace_back(LogicalType::INTEGER); names.emplace_back("INPUT_SIZE"); - return_types.push_back(LogicalType::INTEGER); + return_types.emplace_back(LogicalType::INTEGER); names.emplace_back("EXTRA_INFO"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); return make_unique(return_types); } @@ -95302,26 +96019,24 @@ struct PragmaLastProfilingOutputData : public TableFunctionData { vector types; }; -static unique_ptr PragmaLastProfilingOutputBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, - vector &input_table_types, - vector &input_table_names, - vector &return_types, - vector &names) { +static unique_ptr +PragmaLastProfilingOutputBind(ClientContext &context, vector &inputs, named_parameter_map_t &named_parameters, + vector &input_table_types, vector &input_table_names, + vector &return_types, vector &names) { names.emplace_back("OPERATOR_ID"); - return_types.push_back(LogicalType::INTEGER); + return_types.emplace_back(LogicalType::INTEGER); names.emplace_back("NAME"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("TIME"); - return_types.push_back(LogicalType::DOUBLE); + return_types.emplace_back(LogicalType::DOUBLE); names.emplace_back("CARDINALITY"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("DESCRIPTION"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); return make_unique(return_types); } @@ -95421,7 +96136,7 @@ struct RangeFunctionBindData : public TableFunctionData { template static unique_ptr -RangeFunctionBind(ClientContext &context, vector &inputs, unordered_map &named_parameters, +RangeFunctionBind(ClientContext &context, vector &inputs, named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { auto result = make_unique(); @@ -95447,7 +96162,7 @@ RangeFunctionBind(ClientContext &context, vector &inputs, unordered_mapstart < result->end && result->increment < 0) { throw BinderException("start is smaller than end, but increment is negative: cannot generate infinite series"); } - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); if (GENERATE_SERIES) { // generate_series has inclusive bounds on the RHS if (result->increment < 0) { @@ -95532,7 +96247,7 @@ struct RangeDateTimeBindData : public TableFunctionData { template static unique_ptr -RangeDateTimeBind(ClientContext &context, vector &inputs, unordered_map &named_parameters, +RangeDateTimeBind(ClientContext &context, vector &inputs, named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { auto result = make_unique(); @@ -95661,42 +96376,6 @@ void BuiltinFunctions::RegisterTableFunctions() { -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/expression/constant_expression.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - -namespace duckdb { - -//! ConstantExpression represents a constant value in the query -class ConstantExpression : public ParsedExpression { -public: - explicit ConstantExpression(Value val); - - //! The constant value referenced - Value value; - -public: - string ToString() const override; - - static bool Equals(const ConstantExpression *a, const ConstantExpression *b); - hash_t Hash() const override; - - unique_ptr Copy() const override; - - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(ExpressionType type, Deserializer &source); -}; - -} // namespace duckdb //===----------------------------------------------------------------------===// @@ -95735,9 +96414,9 @@ class TableFunctionRef : public TableRef { unique_ptr Copy() override; //! Serializes a blob into a BaseTableRef - void Serialize(Serializer &serializer) override; + void Serialize(FieldWriter &serializer) const override; //! Deserializes a blob back into a BaseTableRef - static unique_ptr Deserialize(Deserializer &source); + static unique_ptr Deserialize(FieldReader &source); }; } // namespace duckdb @@ -95748,13 +96427,17 @@ class TableFunctionRef : public TableRef { namespace duckdb { static unique_ptr ReadCSVBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, + named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { + auto &config = DBConfig::GetConfig(context); + if (!config.enable_external_access) { + throw PermissionException("Scanning CSV files is disabled through configuration"); + } auto result = make_unique(); auto &options = result->options; - string file_pattern = inputs[0].str_value; + auto &file_pattern = StringValue::Get(inputs[0]); auto &fs = FileSystem::GetFileSystem(context); result->files = fs.Glob(file_pattern); @@ -95763,23 +96446,23 @@ static unique_ptr ReadCSVBind(ClientContext &context, vector(); if (sample_size < 1 && sample_size != -1) { throw BinderException("Unsupported parameter for SAMPLE_SIZE: cannot be smaller than 1"); @@ -95794,7 +96477,7 @@ static unique_ptr ReadCSVBind(ClientContext &context, vector(); if (options.sample_chunk_size > STANDARD_VECTOR_SIZE) { throw BinderException( @@ -95803,65 +96486,66 @@ static unique_ptr ReadCSVBind(ClientContext &context, vector(); if (options.sample_chunks < 1) { throw BinderException("Unsupported parameter for SAMPLE_CHUNKS: cannot be smaller than 1"); } - } else if (kv.first == "all_varchar") { - options.all_varchar = kv.second.value_.boolean; - } else if (kv.first == "dateformat") { + } else if (loption == "all_varchar") { + options.all_varchar = BooleanValue::Get(kv.second); + } else if (loption == "dateformat") { options.has_format[LogicalTypeId::DATE] = true; auto &date_format = options.date_format[LogicalTypeId::DATE]; - date_format.format_specifier = kv.second.str_value; + date_format.format_specifier = StringValue::Get(kv.second); string error = StrTimeFormat::ParseFormatSpecifier(date_format.format_specifier, date_format); if (!error.empty()) { throw InvalidInputException("Could not parse DATEFORMAT: %s", error.c_str()); } - } else if (kv.first == "timestampformat") { + } else if (loption == "timestampformat") { options.has_format[LogicalTypeId::TIMESTAMP] = true; auto ×tamp_format = options.date_format[LogicalTypeId::TIMESTAMP]; - timestamp_format.format_specifier = kv.second.str_value; + timestamp_format.format_specifier = StringValue::Get(kv.second); string error = StrTimeFormat::ParseFormatSpecifier(timestamp_format.format_specifier, timestamp_format); if (!error.empty()) { throw InvalidInputException("Could not parse TIMESTAMPFORMAT: %s", error.c_str()); } - } else if (kv.first == "normalize_names") { - options.normalize_names = kv.second.value_.boolean; - } else if (kv.first == "columns") { + } else if (loption == "normalize_names") { + options.normalize_names = BooleanValue::Get(kv.second); + } else if (loption == "columns") { auto &child_type = kv.second.type(); if (child_type.id() != LogicalTypeId::STRUCT) { throw BinderException("read_csv columns requires a a struct as input"); } - D_ASSERT(StructType::GetChildCount(child_type) == kv.second.struct_value.size()); - for (idx_t i = 0; i < kv.second.struct_value.size(); i++) { + 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 = kv.second.struct_value[i]; + auto &val = struct_children[i]; names.push_back(name); if (val.type().id() != LogicalTypeId::VARCHAR) { throw BinderException("read_csv requires a type specification as string"); } - return_types.emplace_back(TransformStringToLogicalType(val.str_value.c_str())); + return_types.emplace_back(TransformStringToLogicalType(StringValue::Get(val))); } if (names.empty()) { throw BinderException("read_csv requires at least a single column as input!"); } - } else if (kv.first == "compression") { - options.compression = kv.second.str_value; - } else if (kv.first == "filename") { - result->include_file_name = kv.second.value_.boolean; - } else if (kv.first == "skip") { + } else if (loption == "compression") { + options.compression = FileCompressionTypeFromString(StringValue::Get(kv.second)); + } else if (loption == "filename") { + result->include_file_name = BooleanValue::Get(kv.second); + } else if (loption == "skip") { options.skip_rows = kv.second.GetValue(); + } else if (loption == "max_line_size" || loption == "maximum_line_size") { + options.maximum_line_size = kv.second.GetValue(); + } else { + throw InternalException("Unrecognized parameter %s", kv.first); } } if (!options.auto_detect && return_types.empty()) { throw BinderException("read_csv requires columns to be specified. Use read_csv_auto or set read_csv(..., " "AUTO_DETECT=TRUE) to automatically guess columns."); } - if (!(options.compression == "infer" || options.compression == "gzip" || options.compression == "none" || - options.compression.empty())) { - throw BinderException("read_csv currently only supports 'gzip' compression."); - } if (options.auto_detect) { options.file_path = result->files[0]; auto initial_reader = make_unique(context, options); @@ -95878,7 +96562,7 @@ static unique_ptr ReadCSVBind(ClientContext &context, vectorinclude_file_name) { - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("filename"); } return move(result); @@ -95903,13 +96587,13 @@ static unique_ptr ReadCSVInit(ClientContext &context, cons result->csv_reader = make_unique(context, bind_data.options, bind_data.sql_types); } bind_data.bytes_read = 0; - bind_data.file_size = result->csv_reader->file_size; + bind_data.file_size = result->csv_reader->GetFileSize(); result->file_index = 1; return move(result); } static unique_ptr ReadCSVAutoBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, + named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { @@ -95960,14 +96644,16 @@ static void ReadCSVAddNamedParameters(TableFunction &table_function) { table_function.named_parameters["compression"] = LogicalType::VARCHAR; table_function.named_parameters["filename"] = LogicalType::BOOLEAN; table_function.named_parameters["skip"] = LogicalType::BIGINT; + table_function.named_parameters["max_line_size"] = LogicalType::VARCHAR; + table_function.named_parameters["maximum_line_size"] = LogicalType::VARCHAR; } -int CSVReaderProgress(ClientContext &context, const FunctionData *bind_data_p) { +double CSVReaderProgress(ClientContext &context, const FunctionData *bind_data_p) { auto &bind_data = (ReadCSVData &)*bind_data_p; if (bind_data.file_size == 0) { return 100; } - auto percentage = bind_data.bytes_read * 100 / bind_data.file_size; + auto percentage = (bind_data.bytes_read * 100.0) / bind_data.file_size; return percentage; } @@ -95989,8 +96675,13 @@ void ReadCSVTableFunction::RegisterFunction(BuiltinFunctions &set) { unique_ptr ReadCSVReplacement(const string &table_name, void *data) { auto lower_name = StringUtil::Lower(table_name); - if (!StringUtil::EndsWith(lower_name, ".csv") && !StringUtil::EndsWith(lower_name, ".tsv") && - !StringUtil::EndsWith(lower_name, ".csv.gz")) { + // remove any compression + if (StringUtil::EndsWith(lower_name, ".gz")) { + lower_name = lower_name.substr(0, lower_name.size() - 3); + } else if (StringUtil::EndsWith(lower_name, ".zst")) { + lower_name = lower_name.substr(0, lower_name.size() - 4); + } + if (!StringUtil::EndsWith(lower_name, ".csv") && !StringUtil::EndsWith(lower_name, ".tsv")) { return nullptr; } auto table_function = make_unique(); @@ -96029,7 +96720,7 @@ struct RepeatOperatorData : public FunctionOperatorData { }; static unique_ptr RepeatBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, + named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { // the repeat function returns the type of the first argument @@ -96076,12 +96767,12 @@ void RepeatTableFunction::RegisterFunction(BuiltinFunctions &set) { namespace duckdb { static unique_ptr SummaryFunctionBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, + named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("summary"); for (idx_t i = 0; i < input_table_types.size(); i++) { @@ -96144,54 +96835,54 @@ struct DuckDBColumnsData : public FunctionOperatorData { }; static unique_ptr DuckDBColumnsBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, + named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { names.emplace_back("schema_oid"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("schema_name"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("table_oid"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("table_name"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("column_name"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("column_index"); - return_types.push_back(LogicalType::INTEGER); + return_types.emplace_back(LogicalType::INTEGER); names.emplace_back("internal"); - return_types.push_back(LogicalType::BOOLEAN); + return_types.emplace_back(LogicalType::BOOLEAN); names.emplace_back("column_default"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("is_nullable"); - return_types.push_back(LogicalType::BOOLEAN); + return_types.emplace_back(LogicalType::BOOLEAN); names.emplace_back("data_type"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("data_type_id"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("character_maximum_length"); - return_types.push_back(LogicalType::INTEGER); + return_types.emplace_back(LogicalType::INTEGER); names.emplace_back("numeric_precision"); - return_types.push_back(LogicalType::INTEGER); + return_types.emplace_back(LogicalType::INTEGER); names.emplace_back("numeric_precision_radix"); - return_types.push_back(LogicalType::INTEGER); + return_types.emplace_back(LogicalType::INTEGER); names.emplace_back("numeric_scale"); - return_types.push_back(LogicalType::INTEGER); + return_types.emplace_back(LogicalType::INTEGER); return nullptr; } @@ -96479,34 +97170,34 @@ struct DuckDBConstraintsData : public FunctionOperatorData { }; static unique_ptr DuckDBConstraintsBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, + named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { names.emplace_back("schema_name"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("schema_oid"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("table_name"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("table_oid"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("constraint_index"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); // CHECK, PRIMARY KEY or UNIQUE names.emplace_back("constraint_type"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("constraint_text"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("expression"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("constraint_column_indexes"); ; @@ -96683,30 +97374,30 @@ struct DuckDBDependenciesData : public FunctionOperatorData { }; static unique_ptr DuckDBDependenciesBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, + named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { names.emplace_back("classid"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("objid"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("objsubid"); - return_types.push_back(LogicalType::INTEGER); + return_types.emplace_back(LogicalType::INTEGER); names.emplace_back("refclassid"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("refobjid"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("refobjsubid"); - return_types.push_back(LogicalType::INTEGER); + return_types.emplace_back(LogicalType::INTEGER); names.emplace_back("deptype"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); return nullptr; } @@ -96792,6 +97483,420 @@ void DuckDBDependenciesFun::RegisterFunction(BuiltinFunctions &set) { + + +namespace duckdb { + +struct DuckDBFunctionsData : public FunctionOperatorData { + DuckDBFunctionsData() : offset(0), offset_in_entry(0) { + } + + vector entries; + idx_t offset; + idx_t offset_in_entry; +}; + +static unique_ptr DuckDBFunctionsBind(ClientContext &context, vector &inputs, + named_parameter_map_t &named_parameters, + vector &input_table_types, + vector &input_table_names, + vector &return_types, vector &names) { + names.emplace_back("schema_name"); + return_types.emplace_back(LogicalType::VARCHAR); + + names.emplace_back("function_name"); + return_types.emplace_back(LogicalType::VARCHAR); + + names.emplace_back("function_type"); + return_types.emplace_back(LogicalType::VARCHAR); + + names.emplace_back("description"); + return_types.emplace_back(LogicalType::VARCHAR); + + names.emplace_back("return_type"); + return_types.emplace_back(LogicalType::VARCHAR); + + names.emplace_back("parameters"); + return_types.push_back(LogicalType::LIST(LogicalType::VARCHAR)); + + names.emplace_back("parameter_types"); + return_types.push_back(LogicalType::LIST(LogicalType::VARCHAR)); + + names.emplace_back("varargs"); + return_types.emplace_back(LogicalType::VARCHAR); + + names.emplace_back("macro_definition"); + return_types.emplace_back(LogicalType::VARCHAR); + + return nullptr; +} + +static void ExtractFunctionsFromSchema(ClientContext &context, SchemaCatalogEntry &schema, + DuckDBFunctionsData &result) { + schema.Scan(context, CatalogType::SCALAR_FUNCTION_ENTRY, + [&](CatalogEntry *entry) { result.entries.push_back(entry); }); + schema.Scan(context, CatalogType::TABLE_FUNCTION_ENTRY, + [&](CatalogEntry *entry) { result.entries.push_back(entry); }); + schema.Scan(context, CatalogType::PRAGMA_FUNCTION_ENTRY, + [&](CatalogEntry *entry) { result.entries.push_back(entry); }); +} + +unique_ptr DuckDBFunctionsInit(ClientContext &context, const FunctionData *bind_data, + const vector &column_ids, + TableFilterCollection *filters) { + auto result = make_unique(); + + // scan all the schemas for tables and collect themand collect them + auto schemas = Catalog::GetCatalog(context).schemas->GetEntries(context); + for (auto &schema : schemas) { + ExtractFunctionsFromSchema(context, *schema, *result); + }; + ExtractFunctionsFromSchema(context, *context.temporary_objects, *result); + + std::sort(result->entries.begin(), result->entries.end(), + [&](CatalogEntry *a, CatalogEntry *b) { return (int)a->type < (int)b->type; }); + return move(result); +} + +struct ScalarFunctionExtractor { + static idx_t FunctionCount(ScalarFunctionCatalogEntry &entry) { + return entry.functions.size(); + } + + static Value GetFunctionType() { + return Value("scalar"); + } + + static Value GetFunctionDescription(ScalarFunctionCatalogEntry &entry, idx_t offset) { + return Value(); + } + + static Value GetReturnType(ScalarFunctionCatalogEntry &entry, idx_t offset) { + return Value(entry.functions[offset].return_type.ToString()); + } + + static Value GetParameters(ScalarFunctionCatalogEntry &entry, idx_t offset) { + vector results; + for (idx_t i = 0; i < entry.functions[offset].arguments.size(); i++) { + results.emplace_back("col" + to_string(i)); + } + return Value::LIST(LogicalType::VARCHAR, move(results)); + } + + static Value GetParameterTypes(ScalarFunctionCatalogEntry &entry, idx_t offset) { + vector results; + for (idx_t i = 0; i < entry.functions[offset].arguments.size(); i++) { + results.emplace_back(entry.functions[offset].arguments[i].ToString()); + } + return Value::LIST(LogicalType::VARCHAR, move(results)); + } + + static Value GetVarArgs(ScalarFunctionCatalogEntry &entry, idx_t offset) { + return entry.functions[offset].varargs.id() == LogicalTypeId::INVALID + ? Value() + : Value(entry.functions[offset].varargs.ToString()); + } + + static Value GetMacroDefinition(ScalarFunctionCatalogEntry &entry, idx_t offset) { + return Value(); + } +}; + +struct AggregateFunctionExtractor { + static idx_t FunctionCount(AggregateFunctionCatalogEntry &entry) { + return entry.functions.size(); + } + + static Value GetFunctionType() { + return Value("aggregate"); + } + + static Value GetFunctionDescription(AggregateFunctionCatalogEntry &entry, idx_t offset) { + return Value(); + } + + static Value GetReturnType(AggregateFunctionCatalogEntry &entry, idx_t offset) { + return Value(entry.functions[offset].return_type.ToString()); + } + + static Value GetParameters(AggregateFunctionCatalogEntry &entry, idx_t offset) { + vector results; + for (idx_t i = 0; i < entry.functions[offset].arguments.size(); i++) { + results.emplace_back("col" + to_string(i)); + } + return Value::LIST(LogicalType::VARCHAR, move(results)); + } + + static Value GetParameterTypes(AggregateFunctionCatalogEntry &entry, idx_t offset) { + vector results; + for (idx_t i = 0; i < entry.functions[offset].arguments.size(); i++) { + results.emplace_back(entry.functions[offset].arguments[i].ToString()); + } + return Value::LIST(LogicalType::VARCHAR, move(results)); + } + + static Value GetVarArgs(AggregateFunctionCatalogEntry &entry, idx_t offset) { + return entry.functions[offset].varargs.id() == LogicalTypeId::INVALID + ? Value() + : Value(entry.functions[offset].varargs.ToString()); + } + + static Value GetMacroDefinition(AggregateFunctionCatalogEntry &entry, idx_t offset) { + return Value(); + } +}; + +struct MacroExtractor { + static idx_t FunctionCount(MacroCatalogEntry &entry) { + return 1; + } + + static Value GetFunctionType() { + return Value("macro"); + } + + static Value GetFunctionDescription(MacroCatalogEntry &entry, idx_t offset) { + return Value(); + } + + static Value GetReturnType(MacroCatalogEntry &entry, idx_t offset) { + return Value(); + } + + static Value GetParameters(MacroCatalogEntry &entry, idx_t offset) { + vector results; + for (auto ¶m : entry.function->parameters) { + D_ASSERT(param->type == ExpressionType::COLUMN_REF); + auto &colref = (ColumnRefExpression &)*param; + results.emplace_back(colref.GetColumnName()); + } + for (auto ¶m_entry : entry.function->default_parameters) { + results.emplace_back(param_entry.first); + } + return Value::LIST(LogicalType::VARCHAR, move(results)); + } + + static Value GetParameterTypes(MacroCatalogEntry &entry, idx_t offset) { + vector results; + for (idx_t i = 0; i < entry.function->parameters.size(); i++) { + results.emplace_back(LogicalType::VARCHAR); + } + for (idx_t i = 0; i < entry.function->default_parameters.size(); i++) { + results.emplace_back(LogicalType::VARCHAR); + } + return Value::LIST(LogicalType::VARCHAR, move(results)); + } + + static Value GetVarArgs(MacroCatalogEntry &entry, idx_t offset) { + return Value(); + } + + static Value GetMacroDefinition(MacroCatalogEntry &entry, idx_t offset) { + return entry.function->expression->ToString(); + } +}; + +struct TableFunctionExtractor { + static idx_t FunctionCount(TableFunctionCatalogEntry &entry) { + return entry.functions.size(); + } + + static Value GetFunctionType() { + return Value("table"); + } + + static Value GetFunctionDescription(TableFunctionCatalogEntry &entry, idx_t offset) { + return Value(); + } + + static Value GetReturnType(TableFunctionCatalogEntry &entry, idx_t offset) { + return Value(); + } + + static Value GetParameters(TableFunctionCatalogEntry &entry, idx_t offset) { + vector results; + for (idx_t i = 0; i < entry.functions[offset].arguments.size(); i++) { + results.emplace_back("col" + to_string(i)); + } + for (auto ¶m : entry.functions[offset].named_parameters) { + results.emplace_back(param.first); + } + return Value::LIST(LogicalType::VARCHAR, move(results)); + } + + static Value GetParameterTypes(TableFunctionCatalogEntry &entry, idx_t offset) { + vector results; + for (idx_t i = 0; i < entry.functions[offset].arguments.size(); i++) { + results.emplace_back(entry.functions[offset].arguments[i].ToString()); + } + for (auto ¶m : entry.functions[offset].named_parameters) { + results.emplace_back(param.second.ToString()); + } + return Value::LIST(LogicalType::VARCHAR, move(results)); + } + + static Value GetVarArgs(TableFunctionCatalogEntry &entry, idx_t offset) { + return entry.functions[offset].varargs.id() == LogicalTypeId::INVALID + ? Value() + : Value(entry.functions[offset].varargs.ToString()); + } + + static Value GetMacroDefinition(TableFunctionCatalogEntry &entry, idx_t offset) { + return Value(); + } +}; + +struct PragmaFunctionExtractor { + static idx_t FunctionCount(PragmaFunctionCatalogEntry &entry) { + return entry.functions.size(); + } + + static Value GetFunctionType() { + return Value("pragma"); + } + + static Value GetFunctionDescription(PragmaFunctionCatalogEntry &entry, idx_t offset) { + return Value(); + } + + static Value GetReturnType(PragmaFunctionCatalogEntry &entry, idx_t offset) { + return Value(); + } + + static Value GetParameters(PragmaFunctionCatalogEntry &entry, idx_t offset) { + vector results; + for (idx_t i = 0; i < entry.functions[offset].arguments.size(); i++) { + results.emplace_back("col" + to_string(i)); + } + for (auto ¶m : entry.functions[offset].named_parameters) { + results.emplace_back(param.first); + } + return Value::LIST(LogicalType::VARCHAR, move(results)); + } + + static Value GetParameterTypes(PragmaFunctionCatalogEntry &entry, idx_t offset) { + vector results; + for (idx_t i = 0; i < entry.functions[offset].arguments.size(); i++) { + results.emplace_back(entry.functions[offset].arguments[i].ToString()); + } + for (auto ¶m : entry.functions[offset].named_parameters) { + results.emplace_back(param.second.ToString()); + } + return Value::LIST(LogicalType::VARCHAR, move(results)); + } + + static Value GetVarArgs(PragmaFunctionCatalogEntry &entry, idx_t offset) { + return entry.functions[offset].varargs.id() == LogicalTypeId::INVALID + ? Value() + : Value(entry.functions[offset].varargs.ToString()); + } + + static Value GetMacroDefinition(PragmaFunctionCatalogEntry &entry, idx_t offset) { + return Value(); + } +}; + +template +bool ExtractFunctionData(StandardEntry *entry, idx_t function_idx, DataChunk &output, idx_t output_offset) { + auto &function = (T &)*entry; + // schema_name, LogicalType::VARCHAR + output.SetValue(0, output_offset, Value(entry->schema->name)); + + // function_name, LogicalType::VARCHAR + output.SetValue(1, output_offset, Value(entry->name)); + + // function_type, LogicalType::VARCHAR + output.SetValue(2, output_offset, Value(OP::GetFunctionType())); + + // function_description, LogicalType::VARCHAR + output.SetValue(3, output_offset, OP::GetFunctionDescription(function, function_idx)); + + // return_type, LogicalType::VARCHAR + output.SetValue(4, output_offset, OP::GetReturnType(function, function_idx)); + + // parameters, LogicalType::LIST(LogicalType::VARCHAR) + output.SetValue(5, output_offset, OP::GetParameters(function, function_idx)); + + // parameter_types, LogicalType::LIST(LogicalType::VARCHAR) + output.SetValue(6, output_offset, OP::GetParameterTypes(function, function_idx)); + + // varargs, LogicalType::VARCHAR + output.SetValue(7, output_offset, OP::GetVarArgs(function, function_idx)); + + // macro_definition, LogicalType::VARCHAR + output.SetValue(8, output_offset, OP::GetMacroDefinition(function, function_idx)); + + return function_idx + 1 == OP::FunctionCount(function); +} + +void DuckDBFunctionsFunction(ClientContext &context, const FunctionData *bind_data, + FunctionOperatorData *operator_state, DataChunk *input, DataChunk &output) { + auto &data = (DuckDBFunctionsData &)*operator_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 standard_entry = (StandardEntry *)entry; + bool finished = false; + + switch (entry->type) { + case CatalogType::SCALAR_FUNCTION_ENTRY: + finished = ExtractFunctionData( + standard_entry, data.offset_in_entry, output, count); + break; + case CatalogType::AGGREGATE_FUNCTION_ENTRY: + finished = ExtractFunctionData( + standard_entry, data.offset_in_entry, output, count); + break; + case CatalogType::MACRO_ENTRY: + finished = ExtractFunctionData(standard_entry, data.offset_in_entry, + output, count); + break; + case CatalogType::TABLE_FUNCTION_ENTRY: + finished = ExtractFunctionData( + standard_entry, data.offset_in_entry, output, count); + break; + case CatalogType::PRAGMA_FUNCTION_ENTRY: + finished = ExtractFunctionData( + standard_entry, data.offset_in_entry, output, count); + break; + default: + throw InternalException("FIXME: unrecognized function type in duckdb_functions"); + } + if (finished) { + // finished with this function, move to the next function + data.offset++; + data.offset_in_entry = 0; + } else { + // more functions remain + data.offset_in_entry++; + } + count++; + } + output.SetCardinality(count); +} + +void DuckDBFunctionsFun::RegisterFunction(BuiltinFunctions &set) { + set.AddFunction( + TableFunction("duckdb_functions", {}, DuckDBFunctionsFunction, DuckDBFunctionsBind, DuckDBFunctionsInit)); +} + +} // namespace duckdb + + + + + + + + + + namespace duckdb { struct DuckDBIndexesData : public FunctionOperatorData { @@ -96803,39 +97908,39 @@ struct DuckDBIndexesData : public FunctionOperatorData { }; static unique_ptr DuckDBIndexesBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, + named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { names.emplace_back("schema_name"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("schema_oid"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("index_name"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("index_oid"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("table_name"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("table_oid"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("is_unique"); - return_types.push_back(LogicalType::BOOLEAN); + return_types.emplace_back(LogicalType::BOOLEAN); names.emplace_back("is_primary"); - return_types.push_back(LogicalType::BOOLEAN); + return_types.emplace_back(LogicalType::BOOLEAN); names.emplace_back("expressions"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("sql"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); return nullptr; } @@ -96912,6 +98017,90 @@ void DuckDBIndexesFun::RegisterFunction(BuiltinFunctions &set) { +namespace duckdb { + +struct DuckDBKeywordsData : public FunctionOperatorData { + DuckDBKeywordsData() : offset(0) { + } + + vector entries; + idx_t offset; +}; + +static unique_ptr DuckDBKeywordsBind(ClientContext &context, vector &inputs, + named_parameter_map_t &named_parameters, + vector &input_table_types, + vector &input_table_names, vector &return_types, + vector &names) { + names.emplace_back("keyword_name"); + return_types.emplace_back(LogicalType::VARCHAR); + + names.emplace_back("keyword_category"); + return_types.emplace_back(LogicalType::VARCHAR); + + return nullptr; +} + +unique_ptr DuckDBKeywordsInit(ClientContext &context, const FunctionData *bind_data, + const vector &column_ids, + TableFilterCollection *filters) { + auto result = make_unique(); + result->entries = Parser::KeywordList(); + return move(result); +} + +void DuckDBKeywordsFunction(ClientContext &context, const FunctionData *bind_data, FunctionOperatorData *operator_state, + DataChunk *input, DataChunk &output) { + auto &data = (DuckDBKeywordsData &)*operator_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++]; + + // keyword_name, VARCHAR + output.SetValue(0, count, Value(entry.name)); + // keyword_category, VARCHAR + string category_name; + switch (entry.category) { + case KeywordCategory::KEYWORD_RESERVED: + category_name = "reserved"; + break; + case KeywordCategory::KEYWORD_UNRESERVED: + category_name = "unreserved"; + break; + case KeywordCategory::KEYWORD_TYPE_FUNC: + category_name = "type_function"; + break; + case KeywordCategory::KEYWORD_COL_NAME: + category_name = "column_name"; + break; + default: + throw InternalException("Unrecognized keyword category"); + } + output.SetValue(1, count, Value(move(category_name))); + + count++; + } + output.SetCardinality(count); +} + +void DuckDBKeywordsFun::RegisterFunction(BuiltinFunctions &set) { + set.AddFunction( + TableFunction("duckdb_keywords", {}, DuckDBKeywordsFunction, DuckDBKeywordsBind, DuckDBKeywordsInit)); +} + +} // namespace duckdb + + + + + + namespace duckdb { @@ -96924,21 +98113,21 @@ struct DuckDBSchemasData : public FunctionOperatorData { }; static unique_ptr DuckDBSchemasBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, + named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { names.emplace_back("oid"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("schema_name"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("internal"); - return_types.push_back(LogicalType::BOOLEAN); + return_types.emplace_back(LogicalType::BOOLEAN); names.emplace_back("sql"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); return nullptr; } @@ -97009,45 +98198,45 @@ struct DuckDBSequencesData : public FunctionOperatorData { }; static unique_ptr DuckDBSequencesBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, + named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { names.emplace_back("schema_name"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("schema_oid"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("sequence_name"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("sequence_oid"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("temporary"); - return_types.push_back(LogicalType::BOOLEAN); + return_types.emplace_back(LogicalType::BOOLEAN); names.emplace_back("start_value"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("min_value"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("max_value"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("increment_by"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("cycle"); - return_types.push_back(LogicalType::BOOLEAN); + return_types.emplace_back(LogicalType::BOOLEAN); names.emplace_back("last_value"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("sql"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); return nullptr; } @@ -97126,6 +98315,116 @@ void DuckDBSequencesFun::RegisterFunction(BuiltinFunctions &set) { +namespace duckdb { + +struct DuckDBSettingValue { + string name; + string value; + string description; + string input_type; +}; + +struct DuckDBSettingsData : public FunctionOperatorData { + DuckDBSettingsData() : offset(0) { + } + + vector settings; + idx_t offset; +}; + +static unique_ptr DuckDBSettingsBind(ClientContext &context, vector &inputs, + named_parameter_map_t &named_parameters, + vector &input_table_types, + vector &input_table_names, vector &return_types, + vector &names) { + names.emplace_back("name"); + return_types.emplace_back(LogicalType::VARCHAR); + + names.emplace_back("value"); + return_types.emplace_back(LogicalType::VARCHAR); + + names.emplace_back("description"); + return_types.emplace_back(LogicalType::VARCHAR); + + names.emplace_back("input_type"); + return_types.emplace_back(LogicalType::VARCHAR); + + return nullptr; +} + +unique_ptr DuckDBSettingsInit(ClientContext &context, const FunctionData *bind_data, + const vector &column_ids, + TableFilterCollection *filters) { + auto result = make_unique(); + + auto &config = DBConfig::GetConfig(context); + auto options_count = DBConfig::GetOptionCount(); + for (idx_t i = 0; i < options_count; i++) { + auto option = DBConfig::GetOptionByIndex(i); + D_ASSERT(option); + DuckDBSettingValue value; + value.name = option->name; + value.value = option->get_setting(context).ToString(); + value.description = option->description; + value.input_type = LogicalTypeIdToString(option->parameter_type); + + result->settings.push_back(move(value)); + } + for (auto &ext_param : config.extension_parameters) { + Value setting_val; + string setting_str_val; + if (context.TryGetCurrentSetting(ext_param.first, setting_val)) { + setting_str_val = setting_val.ToString(); + } + DuckDBSettingValue value; + value.name = ext_param.first; + value.value = move(setting_str_val); + value.description = ext_param.second.description; + value.input_type = ext_param.second.type.ToString(); + + result->settings.push_back(move(value)); + } + return move(result); +} + +void DuckDBSettingsFunction(ClientContext &context, const FunctionData *bind_data, FunctionOperatorData *operator_state, + DataChunk *input, DataChunk &output) { + auto &data = (DuckDBSettingsData &)*operator_state; + if (data.offset >= data.settings.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.settings.size() && count < STANDARD_VECTOR_SIZE) { + auto &entry = data.settings[data.offset++]; + + // return values: + // name, LogicalType::VARCHAR + output.SetValue(0, count, Value(entry.name)); + // value, LogicalType::VARCHAR + output.SetValue(1, count, Value(entry.value)); + // description, LogicalType::VARCHAR + output.SetValue(2, count, Value(entry.description)); + // input_type, LogicalType::VARCHAR + output.SetValue(3, count, Value(entry.input_type)); + count++; + } + output.SetCardinality(count); +} + +void DuckDBSettingsFun::RegisterFunction(BuiltinFunctions &set) { + set.AddFunction( + TableFunction("duckdb_settings", {}, DuckDBSettingsFunction, DuckDBSettingsBind, DuckDBSettingsInit)); +} + +} // namespace duckdb + + + + + @@ -97143,45 +98442,45 @@ struct DuckDBTablesData : public FunctionOperatorData { }; static unique_ptr DuckDBTablesBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, + named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { names.emplace_back("schema_name"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("schema_oid"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("table_name"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("table_oid"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("internal"); - return_types.push_back(LogicalType::BOOLEAN); + return_types.emplace_back(LogicalType::BOOLEAN); names.emplace_back("temporary"); - return_types.push_back(LogicalType::BOOLEAN); + return_types.emplace_back(LogicalType::BOOLEAN); names.emplace_back("has_primary_key"); - return_types.push_back(LogicalType::BOOLEAN); + return_types.emplace_back(LogicalType::BOOLEAN); names.emplace_back("estimated_size"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("column_count"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("index_count"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("check_constraint_count"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("sql"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); return nullptr; } @@ -97296,31 +98595,31 @@ struct DuckDBTypesData : public FunctionOperatorData { }; static unique_ptr DuckDBTypesBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, + named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { names.emplace_back("schema_name"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("schema_oid"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("type_oid"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("type_name"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("type_size"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); // NUMERIC, STRING, DATETIME, BOOLEAN, COMPOSITE, USER names.emplace_back("type_category"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("internal"); - return_types.push_back(LogicalType::BOOLEAN); + return_types.emplace_back(LogicalType::BOOLEAN); return nullptr; } @@ -97328,7 +98627,7 @@ static unique_ptr DuckDBTypesBind(ClientContext &context, vector DuckDBTypesInit(ClientContext &context, const FunctionData *bind_data, const vector &column_ids, TableFilterCollection *filters) { auto result = make_unique(); - result->types = LogicalType::ALL_TYPES; + result->types = LogicalType::AllTypes(); // FIXME: add user-defined types here (when we have them) return move(result); } @@ -97383,6 +98682,8 @@ void DuckDBTypesFunction(ClientContext &context, const FunctionData *bind_data, case LogicalTypeId::TIMESTAMP: case LogicalTypeId::TIMESTAMP_NS: case LogicalTypeId::INTERVAL: + case LogicalTypeId::TIME_TZ: + case LogicalTypeId::TIMESTAMP_TZ: category = "DATETIME"; break; case LogicalTypeId::CHAR: @@ -97433,33 +98734,33 @@ struct DuckDBViewsData : public FunctionOperatorData { }; static unique_ptr DuckDBViewsBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, + named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { names.emplace_back("schema_name"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("schema_oid"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("view_name"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("view_oid"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("internal"); - return_types.push_back(LogicalType::BOOLEAN); + return_types.emplace_back(LogicalType::BOOLEAN); names.emplace_back("temporary"); - return_types.push_back(LogicalType::BOOLEAN); + return_types.emplace_back(LogicalType::BOOLEAN); names.emplace_back("column_count"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("sql"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); return nullptr; } @@ -97544,12 +98845,12 @@ struct PragmaCollateData : public FunctionOperatorData { }; static unique_ptr PragmaCollateBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, + named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { names.emplace_back("collname"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); return nullptr; } @@ -97604,18 +98905,18 @@ struct PragmaDatabaseListData : public FunctionOperatorData { }; static unique_ptr PragmaDatabaseListBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, + named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { names.emplace_back("seq"); - return_types.push_back(LogicalType::INTEGER); + return_types.emplace_back(LogicalType::INTEGER); names.emplace_back("name"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("file"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); return nullptr; } @@ -97665,33 +98966,33 @@ struct PragmaDatabaseSizeData : public FunctionOperatorData { }; static unique_ptr PragmaDatabaseSizeBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, + named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { names.emplace_back("database_size"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("block_size"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("total_blocks"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("used_blocks"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("free_blocks"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("wal_size"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("memory_usage"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("memory_limit"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); return nullptr; } @@ -97769,27 +99070,27 @@ struct PragmaFunctionsData : public FunctionOperatorData { }; static unique_ptr PragmaFunctionsBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, + named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { names.emplace_back("name"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("type"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("parameters"); return_types.push_back(LogicalType::LIST(LogicalType::VARCHAR)); names.emplace_back("varargs"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("return_type"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("side_effects"); - return_types.push_back(LogicalType::BOOLEAN); + return_types.emplace_back(LogicalType::BOOLEAN); return nullptr; } @@ -97905,51 +99206,51 @@ struct PragmaStorageOperatorData : public FunctionOperatorData { }; static unique_ptr PragmaStorageInfoBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, + named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { names.emplace_back("row_group_id"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("column_name"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("column_id"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("column_path"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("segment_id"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("segment_type"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("start"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("count"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("compression"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("stats"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("has_updates"); - return_types.push_back(LogicalType::BOOLEAN); + return_types.emplace_back(LogicalType::BOOLEAN); names.emplace_back("persistent"); - return_types.push_back(LogicalType::BOOLEAN); + return_types.emplace_back(LogicalType::BOOLEAN); names.emplace_back("block_id"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("block_offset"); - return_types.push_back(LogicalType::BIGINT); + return_types.emplace_back(LogicalType::BIGINT); auto qname = QualifiedName::Parse(inputs[0].GetValue()); @@ -98032,27 +99333,27 @@ struct PragmaTableOperatorData : public FunctionOperatorData { }; static unique_ptr PragmaTableInfoBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, + named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { names.emplace_back("cid"); - return_types.push_back(LogicalType::INTEGER); + return_types.emplace_back(LogicalType::INTEGER); names.emplace_back("name"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("type"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("notnull"); - return_types.push_back(LogicalType::BOOLEAN); + return_types.emplace_back(LogicalType::BOOLEAN); names.emplace_back("dflt_value"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("pk"); - return_types.push_back(LogicalType::BOOLEAN); + return_types.emplace_back(LogicalType::BOOLEAN); auto qname = QualifiedName::Parse(inputs[0].GetValue()); @@ -98186,6 +99487,226 @@ void PragmaTableInfo::RegisterFunction(BuiltinFunctions &set) { } // namespace duckdb + +namespace duckdb { + +struct TestAllTypesData : public FunctionOperatorData { + TestAllTypesData() : offset(0) { + } + + vector> entries; + idx_t offset; +}; + +struct TestType { + TestType(LogicalType type_p, string name_p) + : type(move(type_p)), name(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)) { + } + + LogicalType type; + string name; + Value min_value; + Value max_value; +}; + +static vector GetTestTypes() { + vector result; + // scalar types/numerics + result.emplace_back(LogicalType::BOOLEAN, "bool"); + result.emplace_back(LogicalType::TINYINT, "tinyint"); + result.emplace_back(LogicalType::SMALLINT, "smallint"); + result.emplace_back(LogicalType::INTEGER, "int"); + result.emplace_back(LogicalType::BIGINT, "bigint"); + result.emplace_back(LogicalType::HUGEINT, "hugeint"); + result.emplace_back(LogicalType::UTINYINT, "utinyint"); + result.emplace_back(LogicalType::USMALLINT, "usmallint"); + result.emplace_back(LogicalType::UINTEGER, "uint"); + result.emplace_back(LogicalType::UBIGINT, "ubigint"); + result.emplace_back(LogicalType::DATE, "date"); + result.emplace_back(LogicalType::TIME, "time"); + result.emplace_back(LogicalType::TIMESTAMP, "timestamp"); + result.emplace_back(LogicalType::TIMESTAMP_S, "timestamp_s"); + result.emplace_back(LogicalType::TIMESTAMP_MS, "timestamp_ms"); + result.emplace_back(LogicalType::TIMESTAMP_NS, "timestamp_ns"); + result.emplace_back(LogicalType::TIME_TZ, "time_tz"); + result.emplace_back(LogicalType::TIMESTAMP_TZ, "timestamp_tz"); + result.emplace_back(LogicalType::FLOAT, "float"); + result.emplace_back(LogicalType::DOUBLE, "double"); + result.emplace_back(LogicalType::DECIMAL(4, 1), "dec_4_1"); + result.emplace_back(LogicalType::DECIMAL(9, 4), "dec_9_4"); + result.emplace_back(LogicalType::DECIMAL(18, 6), "dec_18_6"); + result.emplace_back(LogicalType::DECIMAL(38, 10), "dec38_10"); + result.emplace_back(LogicalType::UUID, "uuid"); + // interval + interval_t min_interval; + min_interval.months = 0; + min_interval.days = 0; + min_interval.micros = 0; + + interval_t max_interval; + max_interval.months = 999; + max_interval.days = 999; + max_interval.micros = 999999999; + result.emplace_back(LogicalType::INTERVAL, "interval", Value::INTERVAL(min_interval), + Value::INTERVAL(max_interval)); + // strings/blobs + result.emplace_back(LogicalType::VARCHAR, "varchar", Value("🦆🦆🦆🦆🦆🦆"), Value("goose")); + result.emplace_back(LogicalType::BLOB, "blob", Value::BLOB("thisisalongblob\\x00withnullbytes"), + Value("\\x00\\x00\\x00a")); + + // enums + Vector small_enum(LogicalType::VARCHAR, 2); + auto small_enum_ptr = FlatVector::GetData(small_enum); + small_enum_ptr[0] = StringVector::AddStringOrBlob(small_enum, "DUCK_DUCK_ENUM"); + small_enum_ptr[1] = StringVector::AddStringOrBlob(small_enum, "GOOSE"); + result.emplace_back(LogicalType::ENUM("small_enum", small_enum, 2), "small_enum"); + + Vector medium_enum(LogicalType::VARCHAR, 300); + auto medium_enum_ptr = FlatVector::GetData(medium_enum); + for (idx_t i = 0; i < 300; i++) { + medium_enum_ptr[i] = StringVector::AddStringOrBlob(medium_enum, string("enum_") + to_string(i)); + } + result.emplace_back(LogicalType::ENUM("medium_enum", medium_enum, 300), "medium_enum"); + + // this is a big one... not sure if we should push this one here, but it's required for completeness + Vector large_enum(LogicalType::VARCHAR, 70000); + auto large_enum_ptr = FlatVector::GetData(large_enum); + for (idx_t i = 0; i < 70000; i++) { + large_enum_ptr[i] = StringVector::AddStringOrBlob(large_enum, string("enum_") + to_string(i)); + } + result.emplace_back(LogicalType::ENUM("large_enum", large_enum, 70000), "large_enum"); + + // arrays + auto int_list_type = LogicalType::LIST(LogicalType::INTEGER); + auto empty_int_list = Value::EMPTYLIST(LogicalType::INTEGER); + auto int_list = Value::LIST({Value::INTEGER(42), Value::INTEGER(999), Value(LogicalType::INTEGER), + Value(LogicalType::INTEGER), Value::INTEGER(-42)}); + result.emplace_back(int_list_type, "int_array", empty_int_list, int_list); + + auto varchar_list_type = LogicalType::LIST(LogicalType::VARCHAR); + auto empty_varchar_list = Value::EMPTYLIST(LogicalType::VARCHAR); + auto varchar_list = + Value::LIST({Value("🦆🦆🦆🦆🦆🦆"), Value("goose"), Value(LogicalType::VARCHAR), Value("")}); + result.emplace_back(varchar_list_type, "varchar_array", empty_varchar_list, varchar_list); + + // nested arrays + auto nested_list_type = LogicalType::LIST(int_list_type); + auto empty_nested_list = Value::EMPTYLIST(int_list_type); + auto nested_int_list = Value::LIST({empty_int_list, int_list, Value(int_list_type), empty_int_list, int_list}); + result.emplace_back(nested_list_type, "nested_int_array", empty_nested_list, nested_int_list); + + // structs + 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)); + + 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)); + + 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)); + + result.emplace_back(struct_type, "struct", min_struct_val, max_struct_val); + + // structs with lists + 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)); + + 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)); + + 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)); + + result.emplace_back(struct_list_type, "struct_of_arrays", move(min_struct_val_list), 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)); + + // 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)); + + return result; +} + +static unique_ptr TestAllTypesBind(ClientContext &context, vector &inputs, + named_parameter_map_t &named_parameters, + vector &input_table_types, + vector &input_table_names, vector &return_types, + vector &names) { + auto test_types = GetTestTypes(); + for (auto &test_type : test_types) { + return_types.push_back(move(test_type.type)); + names.push_back(move(test_type.name)); + } + return nullptr; +} + +unique_ptr TestAllTypesInit(ClientContext &context, const FunctionData *bind_data, + const vector &column_ids, TableFilterCollection *filters) { + auto result = make_unique(); + auto test_types = GetTestTypes(); + // 3 rows: min, max and NULL + 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)); + } + return move(result); +} + +void TestAllTypesFunction(ClientContext &context, const FunctionData *bind_data, FunctionOperatorData *operator_state, + DataChunk *input, DataChunk &output) { + auto &data = (TestAllTypesData &)*operator_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 &vals = data.entries[data.offset++]; + for (idx_t col_idx = 0; col_idx < vals.size(); col_idx++) { + output.SetValue(col_idx, count, vals[col_idx]); + } + count++; + } + output.SetCardinality(count); +} + +void TestAllTypesFun::RegisterFunction(BuiltinFunctions &set) { + set.AddFunction(TableFunction("test_all_types", {}, TestAllTypesFunction, TestAllTypesBind, TestAllTypesInit)); +} + +} // namespace duckdb + + //===----------------------------------------------------------------------===// // DuckDB // @@ -98202,20 +99723,36 @@ void PragmaTableInfo::RegisterFunction(BuiltinFunctions &set) { +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/aggregate_handling.hpp +// +// +//===----------------------------------------------------------------------===// + + + + namespace duckdb { +//===---- enum class AggregateHandling : uint8_t { STANDARD_HANDLING, // standard handling as in the SELECT clause NO_AGGREGATES_ALLOWED, // no aggregates allowed: any aggregates in this node will result in an error FORCE_AGGREGATES // force aggregates: any non-aggregate select list entry will become a GROUP }; +} // namespace duckdb + + +namespace duckdb { + //! SelectNode represents a standard SELECT statement class SelectNode : public QueryNode { public: - SelectNode() : QueryNode(QueryNodeType::SELECT_NODE), aggregate_handling(AggregateHandling::STANDARD_HANDLING) { - } + SelectNode(); //! The projection list vector> select_list; @@ -98227,6 +99764,8 @@ class SelectNode : public QueryNode { GroupByNode groups; //! HAVING clause unique_ptr having; + //! QUALIFY clause + unique_ptr qualify; //! Aggregate handling during binding AggregateHandling aggregate_handling; //! The SAMPLE clause @@ -98239,12 +99778,14 @@ class SelectNode : public QueryNode { public: bool Equals(const QueryNode *other) const override; //! Create a copy of this SelectNode - unique_ptr Copy() override; - //! Serializes a SelectNode to a stand-alone binary blob - void Serialize(Serializer &serializer) override; - //! Deserializes a blob back into a SelectNode - static unique_ptr Deserialize(Deserializer &source); + unique_ptr Copy() const override; + + //! Serializes a QueryNode to a stand-alone binary blob + void Serialize(FieldWriter &writer) const override; + //! Deserializes a blob back into a QueryNode + static unique_ptr Deserialize(FieldReader &reader); }; + } // namespace duckdb //===----------------------------------------------------------------------===// @@ -98281,8 +99822,8 @@ class StarExpression : public ParsedExpression { unique_ptr Copy() const override; - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(ExpressionType type, Deserializer &source); + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(ExpressionType type, FieldReader &source); }; } // namespace duckdb @@ -98305,13 +99846,17 @@ void BuiltinFunctions::RegisterSQLiteFunctions() { DuckDBColumnsFun::RegisterFunction(*this); DuckDBConstraintsFun::RegisterFunction(*this); + DuckDBFunctionsFun::RegisterFunction(*this); + DuckDBKeywordsFun::RegisterFunction(*this); DuckDBIndexesFun::RegisterFunction(*this); DuckDBSchemasFun::RegisterFunction(*this); DuckDBDependenciesFun::RegisterFunction(*this); DuckDBSequencesFun::RegisterFunction(*this); + DuckDBSettingsFun::RegisterFunction(*this); DuckDBTablesFun::RegisterFunction(*this); DuckDBTypesFun::RegisterFunction(*this); DuckDBViewsFun::RegisterFunction(*this); + TestAllTypesFun::RegisterFunction(*this); } } // namespace duckdb @@ -98425,14 +99970,14 @@ bool TableScanParallelStateNext(ClientContext &context, const FunctionData *bind state.column_ids); } -int TableScanProgress(ClientContext &context, const FunctionData *bind_data_p) { +double TableScanProgress(ClientContext &context, const FunctionData *bind_data_p) { auto &bind_data = (TableScanBindData &)*bind_data_p; idx_t total_rows = bind_data.table->storage->GetTotalRows(); if (total_rows == 0 || total_rows < STANDARD_VECTOR_SIZE) { //! Table is either empty or smaller than a vector size, so it is finished return 100; } - auto percentage = (bind_data.chunk_count * STANDARD_VECTOR_SIZE * 100) / total_rows; + auto percentage = double(bind_data.chunk_count * STANDARD_VECTOR_SIZE * 100.0) / total_rows; if (percentage > 100) { //! In case the last chunk has less elements than STANDARD_VECTOR_SIZE, if our percentage is over 100 //! It means we finished this table. @@ -98458,7 +100003,7 @@ unique_ptr TableScanCardinality(ClientContext &context, const Fu // Index Scan //===--------------------------------------------------------------------===// struct IndexScanOperatorData : public FunctionOperatorData { - explicit IndexScanOperatorData(data_ptr_t row_id_data) : row_ids(LOGICAL_ROW_TYPE, row_id_data) { + explicit IndexScanOperatorData(data_ptr_t row_id_data) : row_ids(LogicalType::ROW_TYPE, row_id_data) { } Vector row_ids; @@ -98617,23 +100162,23 @@ void TableScanPushdownComplexFilter(ClientContext &context, LogicalGet &get, Fun break; } } - if (!equal_value.is_null || !low_value.is_null || !high_value.is_null) { + 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); unique_ptr index_state; - if (!equal_value.is_null) { + if (!equal_value.IsNull()) { // equality predicate index_state = index.InitializeScanSinglePredicate(transaction, equal_value, ExpressionType::COMPARE_EQUAL); - } else if (!low_value.is_null && !high_value.is_null) { + } else if (!low_value.IsNull() && !high_value.IsNull()) { // two-sided predicate index_state = index.InitializeScanTwoPredicates(transaction, low_value, low_comparison_type, high_value, high_comparison_type); - } else if (!low_value.is_null) { + } else if (!low_value.IsNull()) { // less than predicate index_state = index.InitializeScanSinglePredicate(transaction, low_value, low_comparison_type); } else { - D_ASSERT(!high_value.is_null); + D_ASSERT(!high_value.IsNull()); index_state = index.InitializeScanSinglePredicate(transaction, high_value, high_comparison_type); } if (index.Scan(transaction, storage, *index_state, STANDARD_VECTOR_SIZE, bind_data.result_ids)) { @@ -98679,6 +100224,14 @@ TableFunction TableScanFunction::GetFunction() { return scan_function; } +TableCatalogEntry *TableScanFunction::GetTableEntry(const TableFunction &function, const FunctionData *bind_data_p) { + if (function.function != TableScanFunc || !bind_data_p) { + return nullptr; + } + auto &bind_data = (TableScanBindData &)*bind_data_p; + return bind_data.table; +} + } // namespace duckdb @@ -98700,7 +100253,7 @@ struct UnnestOperatorData : public FunctionOperatorData { }; static unique_ptr UnnestBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, + named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { return_types.push_back(ListType::GetChildType(inputs[0].type())); @@ -98718,7 +100271,7 @@ static void UnnestFunction(ClientContext &context, const FunctionData *bind_data auto &bind_data = (UnnestFunctionData &)*bind_data_p; auto &state = (UnnestOperatorData &)*operator_state; - auto &list_value = bind_data.value.list_value; + auto &list_value = ListValue::GetChildren(bind_data.value); idx_t count = 0; for (; state.current_count < list_value.size() && count < STANDARD_VECTOR_SIZE; state.current_count++) { output.data[0].SetValue(count, list_value[state.current_count]); @@ -98745,14 +100298,14 @@ struct PragmaVersionData : public FunctionOperatorData { }; static unique_ptr PragmaVersionBind(ClientContext &context, vector &inputs, - unordered_map &named_parameters, + named_parameter_map_t &named_parameters, vector &input_table_types, vector &input_table_names, vector &return_types, vector &names) { names.emplace_back("library_version"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("source_id"); - return_types.push_back(LogicalType::VARCHAR); + return_types.emplace_back(LogicalType::VARCHAR); return nullptr; } @@ -98787,6 +100340,66 @@ const char *DuckDB::LibraryVersion() { return DUCKDB_VERSION; } +string DuckDB::Platform() { + string os = "linux"; + string arch = "amd64"; +#ifdef _WIN32 + os = "windows"; +#elif defined(__APPLE__) + os = "osx"; +#endif +#if defined(__aarch64__) || defined(__ARM_ARCH_ISA_A64) + arch = "arm64"; +#endif + return os + "_" + arch; +} + +} // namespace duckdb + + +namespace duckdb { + +FunctionOperatorData::~FunctionOperatorData() { +} + +TableFilterCollection::TableFilterCollection(TableFilterSet *table_filters) : table_filters(table_filters) { +} + +TableFunction::TableFunction(string name, vector arguments, table_function_t function, + table_function_bind_t bind, table_function_init_t init, table_statistics_t statistics, + table_function_cleanup_t cleanup, table_function_dependency_t dependency, + table_function_cardinality_t cardinality, + table_function_pushdown_complex_filter_t pushdown_complex_filter, + table_function_to_string_t to_string, table_function_max_threads_t max_threads, + table_function_init_parallel_state_t init_parallel_state, + table_function_parallel_t parallel_function, table_function_init_parallel_t parallel_init, + table_function_parallel_state_next_t parallel_state_next, bool projection_pushdown, + bool filter_pushdown, table_function_progress_t query_progress) + : SimpleNamedParameterFunction(move(name), move(arguments)), bind(bind), init(init), function(function), + statistics(statistics), cleanup(cleanup), dependency(dependency), cardinality(cardinality), + pushdown_complex_filter(pushdown_complex_filter), to_string(to_string), max_threads(max_threads), + init_parallel_state(init_parallel_state), parallel_function(parallel_function), parallel_init(parallel_init), + parallel_state_next(parallel_state_next), table_scan_progress(query_progress), + projection_pushdown(projection_pushdown), filter_pushdown(filter_pushdown) { +} + +TableFunction::TableFunction(const vector &arguments, table_function_t function, + table_function_bind_t bind, table_function_init_t init, table_statistics_t statistics, + table_function_cleanup_t cleanup, table_function_dependency_t dependency, + table_function_cardinality_t cardinality, + table_function_pushdown_complex_filter_t pushdown_complex_filter, + table_function_to_string_t to_string, table_function_max_threads_t max_threads, + table_function_init_parallel_state_t init_parallel_state, + table_function_parallel_t parallel_function, table_function_init_parallel_t parallel_init, + table_function_parallel_state_next_t parallel_state_next, bool projection_pushdown, + bool filter_pushdown, table_function_progress_t query_progress) + : TableFunction(string(), arguments, function, bind, init, statistics, cleanup, dependency, cardinality, + pushdown_complex_filter, to_string, max_threads, init_parallel_state, parallel_function, + parallel_init, parallel_state_next, projection_pushdown, filter_pushdown, query_progress) { +} +TableFunction::TableFunction() : SimpleNamedParameterFunction("", {}) { +} + } // namespace duckdb @@ -98826,10 +100439,42 @@ void UDFWrapper::RegisterAggrFunction(AggregateFunction aggr_function, ClientCon + + namespace duckdb { +BaseAppender::BaseAppender() : column(0) { +} + +BaseAppender::BaseAppender(vector types_p) : types(move(types_p)), column(0) { + InitializeChunk(); +} + +BaseAppender::~BaseAppender() { +} + +void BaseAppender::Destructor() { + if (Exception::UncaughtException()) { + return; + } + // flush any remaining chunks, but only if we are not cleaning up the appender as part of an exception stack unwind + // wrapped in a try/catch because Close() can throw if the table was dropped in the meantime + try { + Close(); + } catch (...) { + } +} + +InternalAppender::InternalAppender(ClientContext &context_p, TableCatalogEntry &table_p) + : BaseAppender(table_p.GetTypes()), context(context_p), table(table_p) { +} + +InternalAppender::~InternalAppender() { + Destructor(); +} + Appender::Appender(Connection &con, const string &schema_name, const string &table_name) - : context(con.context), column(0) { + : BaseAppender(), context(con.context) { description = con.TableInfo(schema_name, table_name); if (!description) { // table could not be found @@ -98845,26 +100490,18 @@ Appender::Appender(Connection &con, const string &table_name) : Appender(con, DE } Appender::~Appender() { - if (std::uncaught_exception()) { - return; - } - // flush any remaining chunks, but only if we are not cleaning up the appender as part of an exception stack unwind - // wrapped in a try/catch because Close() can throw if the table was dropped in the meantime - try { - Close(); - } catch (...) { - } + Destructor(); } -void Appender::InitializeChunk() { +void BaseAppender::InitializeChunk() { chunk = make_unique(); chunk->Initialize(types); } -void Appender::BeginRow() { +void BaseAppender::BeginRow() { } -void Appender::EndRow() { +void BaseAppender::EndRow() { // check that all rows have been appended to if (column != chunk->ColumnCount()) { throw InvalidInputException("Call to EndRow before all rows have been appended to!"); @@ -98877,12 +100514,12 @@ void Appender::EndRow() { } template -void Appender::AppendValueInternal(Vector &col, SRC input) { +void BaseAppender::AppendValueInternal(Vector &col, SRC input) { FlatVector::GetData(col)[chunk->size()] = Cast::Operation(input); } template -void Appender::AppendValueInternal(T input) { +void BaseAppender::AppendValueInternal(T input) { if (column >= types.size()) { throw InvalidInputException("Too many appends for chunk!"); } @@ -98935,71 +100572,71 @@ void Appender::AppendValueInternal(T input) { } template <> -void Appender::Append(bool value) { +void BaseAppender::Append(bool value) { AppendValueInternal(value); } template <> -void Appender::Append(int8_t value) { +void BaseAppender::Append(int8_t value) { AppendValueInternal(value); } template <> -void Appender::Append(int16_t value) { +void BaseAppender::Append(int16_t value) { AppendValueInternal(value); } template <> -void Appender::Append(int32_t value) { +void BaseAppender::Append(int32_t value) { AppendValueInternal(value); } template <> -void Appender::Append(int64_t value) { +void BaseAppender::Append(int64_t value) { AppendValueInternal(value); } template <> -void Appender::Append(hugeint_t value) { +void BaseAppender::Append(hugeint_t value) { AppendValueInternal(value); } template <> -void Appender::Append(uint8_t value) { +void BaseAppender::Append(uint8_t value) { AppendValueInternal(value); } template <> -void Appender::Append(uint16_t value) { +void BaseAppender::Append(uint16_t value) { AppendValueInternal(value); } template <> -void Appender::Append(uint32_t value) { +void BaseAppender::Append(uint32_t value) { AppendValueInternal(value); } template <> -void Appender::Append(uint64_t value) { +void BaseAppender::Append(uint64_t value) { AppendValueInternal(value); } template <> -void Appender::Append(const char *value) { +void BaseAppender::Append(const char *value) { AppendValueInternal(string_t(value)); } -void Appender::Append(const char *value, uint32_t length) { +void BaseAppender::Append(const char *value, uint32_t length) { AppendValueInternal(string_t(value, length)); } template <> -void Appender::Append(string_t value) { +void BaseAppender::Append(string_t value) { AppendValueInternal(value); } template <> -void Appender::Append(float value) { +void BaseAppender::Append(float value) { if (!Value::FloatIsValid(value)) { throw InvalidInputException("Float value is out of range!"); } @@ -99007,7 +100644,7 @@ void Appender::Append(float value) { } template <> -void Appender::Append(double value) { +void BaseAppender::Append(double value) { if (!Value::DoubleIsValid(value)) { throw InvalidInputException("Double value is out of range!"); } @@ -99015,27 +100652,27 @@ void Appender::Append(double value) { } template <> -void Appender::Append(date_t value) { +void BaseAppender::Append(date_t value) { AppendValueInternal(value.days); } template <> -void Appender::Append(dtime_t value) { +void BaseAppender::Append(dtime_t value) { AppendValueInternal(value.micros); } template <> -void Appender::Append(timestamp_t value) { +void BaseAppender::Append(timestamp_t value) { AppendValueInternal(value.value); } template <> -void Appender::Append(interval_t value) { +void BaseAppender::Append(interval_t value) { AppendValueInternal(value); } template <> -void Appender::Append(Value value) { // NOLINT: template shtuff +void BaseAppender::Append(Value value) { // NOLINT: template shtuff if (column >= chunk->ColumnCount()) { throw InvalidInputException("Too many appends for chunk!"); } @@ -99043,7 +100680,7 @@ void Appender::Append(Value value) { // NOLINT: template shtuff } template <> -void Appender::Append(std::nullptr_t value) { +void BaseAppender::Append(std::nullptr_t value) { if (column >= chunk->ColumnCount()) { throw InvalidInputException("Too many appends for chunk!"); } @@ -99051,12 +100688,12 @@ void Appender::Append(std::nullptr_t value) { FlatVector::SetNull(col, chunk->size(), true); } -void Appender::AppendValue(const Value &value) { +void BaseAppender::AppendValue(const Value &value) { chunk->SetValue(column, chunk->size(), value); column++; } -void Appender::FlushChunk() { +void BaseAppender::FlushChunk() { if (chunk->size() == 0) { return; } @@ -99067,7 +100704,7 @@ void Appender::FlushChunk() { } } -void Appender::Flush() { +void BaseAppender::Flush() { // check that all vectors have the same length before appending if (column != 0) { throw InvalidInputException("Failed to Flush appender: incomplete append to row!"); @@ -99077,13 +100714,23 @@ void Appender::Flush() { if (collection.Count() == 0) { return; } - context->Append(*description, collection); + FlushInternal(collection); collection.Reset(); column = 0; } -void Appender::Close() { +void Appender::FlushInternal(ChunkCollection &collection) { + context->Append(*description, collection); +} + +void InternalAppender::FlushInternal(ChunkCollection &collection) { + for (auto &chunk : collection.Chunks()) { + table.storage->Append(table, context, *chunk); + } +} + +void BaseAppender::Close() { if (column == 0 || column == types.size()) { Flush(); } @@ -99395,7 +101042,7 @@ idx_t duckdb_arrow_rows_changed(duckdb_arrow result) { idx_t row_count = wrapper->result->collection.Count(); if (row_count > 0 && StatementTypeReturnChanges(wrapper->result->statement_type)) { auto row_changes = wrapper->result->GetValue(0, 0); - if (!row_changes.is_null && row_changes.TryCastAs(LogicalType::BIGINT)) { + if (!row_changes.IsNull() && row_changes.TryCastAs(LogicalType::BIGINT)) { rows_changed = row_changes.GetValue(); } } @@ -99670,10 +101317,12 @@ duckdb_type ConvertCPPTypeToC(const LogicalType &sql_type) { case LogicalTypeId::TIMESTAMP_SEC: case LogicalTypeId::TIMESTAMP_MS: case LogicalTypeId::TIMESTAMP_NS: + case LogicalTypeId::TIMESTAMP_TZ: return DUCKDB_TYPE_TIMESTAMP; case LogicalTypeId::DATE: return DUCKDB_TYPE_DATE; case LogicalTypeId::TIME: + case LogicalTypeId::TIME_TZ: return DUCKDB_TYPE_TIME; case LogicalTypeId::VARCHAR: return DUCKDB_TYPE_VARCHAR; @@ -99957,7 +101606,7 @@ namespace duckdb { template void WriteData(duckdb_result *out, ChunkCollection &source, idx_t col) { idx_t row = 0; - auto target = (T *)out->columns[col].data; + auto target = (T *)out->__deprecated_columns[col].__deprecated_data; for (auto &chunk : source.Chunks()) { auto source = FlatVector::GetData(chunk->data[col]); auto &mask = FlatVector::Validity(chunk->data[col]); @@ -99980,46 +101629,49 @@ duckdb_state duckdb_translate_result(MaterializedQueryResult *result, duckdb_res memset(out, 0, sizeof(duckdb_result)); if (!result->success) { // write the error message - out->error_message = strdup(result->error.c_str()); + out->__deprecated_error_message = strdup(result->error.c_str()); return DuckDBError; } // copy the data // first write the meta data - out->column_count = result->types.size(); - out->row_count = result->collection.Count(); - out->rows_changed = 0; - if (out->row_count > 0 && StatementTypeReturnChanges(result->statement_type)) { + out->__deprecated_column_count = result->types.size(); + out->__deprecated_row_count = result->collection.Count(); + out->__deprecated_rows_changed = 0; + if (out->__deprecated_row_count > 0 && StatementTypeReturnChanges(result->statement_type)) { // update total changes auto row_changes = result->GetValue(0, 0); - if (!row_changes.is_null && row_changes.TryCastAs(LogicalType::BIGINT)) { - out->rows_changed = row_changes.GetValue(); + if (!row_changes.IsNull() && row_changes.TryCastAs(LogicalType::BIGINT)) { + out->__deprecated_rows_changed = row_changes.GetValue(); } } - out->columns = (duckdb_column *)duckdb_malloc(sizeof(duckdb_column) * out->column_count); - if (!out->columns) { // LCOV_EXCL_START + out->__deprecated_columns = (duckdb_column *)duckdb_malloc(sizeof(duckdb_column) * out->__deprecated_column_count); + if (!out->__deprecated_columns) { // LCOV_EXCL_START // malloc failure return DuckDBError; } // LCOV_EXCL_STOP // zero initialize the columns (so we can cleanly delete it in case a malloc fails) - memset(out->columns, 0, sizeof(duckdb_column) * out->column_count); - for (idx_t i = 0; i < out->column_count; i++) { - out->columns[i].type = ConvertCPPTypeToC(result->types[i]); - out->columns[i].name = strdup(result->names[i].c_str()); - out->columns[i].nullmask = (bool *)duckdb_malloc(sizeof(bool) * out->row_count); - out->columns[i].data = duckdb_malloc(GetCTypeSize(out->columns[i].type) * out->row_count); - if (!out->columns[i].nullmask || !out->columns[i].name || !out->columns[i].data) { // LCOV_EXCL_START + memset(out->__deprecated_columns, 0, sizeof(duckdb_column) * out->__deprecated_column_count); + for (idx_t i = 0; i < out->__deprecated_column_count; i++) { + out->__deprecated_columns[i].__deprecated_type = ConvertCPPTypeToC(result->types[i]); + out->__deprecated_columns[i].__deprecated_name = strdup(result->names[i].c_str()); + out->__deprecated_columns[i].__deprecated_nullmask = + (bool *)duckdb_malloc(sizeof(bool) * out->__deprecated_row_count); + out->__deprecated_columns[i].__deprecated_data = + duckdb_malloc(GetCTypeSize(out->__deprecated_columns[i].__deprecated_type) * out->__deprecated_row_count); + if (!out->__deprecated_columns[i].__deprecated_nullmask || !out->__deprecated_columns[i].__deprecated_name || + !out->__deprecated_columns[i].__deprecated_data) { // LCOV_EXCL_START // malloc failure return DuckDBError; } // LCOV_EXCL_STOP } // now write the data - for (idx_t col = 0; col < out->column_count; col++) { + for (idx_t col = 0; col < out->__deprecated_column_count; col++) { // first set the nullmask idx_t row = 0; for (auto &chunk : result->collection.Chunks()) { for (idx_t k = 0; k < chunk->size(); k++) { - out->columns[col].nullmask[row++] = FlatVector::IsNull(chunk->data[col], k); + out->__deprecated_columns[col].__deprecated_nullmask[row++] = FlatVector::IsNull(chunk->data[col], k); } } // then write the data @@ -100061,14 +101713,16 @@ duckdb_state duckdb_translate_result(MaterializedQueryResult *result, duckdb_res WriteData(out, result->collection, col); break; case LogicalTypeId::TIME: + case LogicalTypeId::TIME_TZ: WriteData(out, result->collection, col); break; case LogicalTypeId::TIMESTAMP: + case LogicalTypeId::TIMESTAMP_TZ: WriteData(out, result->collection, col); break; case LogicalTypeId::VARCHAR: { idx_t row = 0; - auto target = (const char **)out->columns[col].data; + auto target = (const char **)out->__deprecated_columns[col].__deprecated_data; for (auto &chunk : result->collection.Chunks()) { auto source = FlatVector::GetData(chunk->data[col]); for (idx_t k = 0; k < chunk->size(); k++) { @@ -100088,7 +101742,7 @@ duckdb_state duckdb_translate_result(MaterializedQueryResult *result, duckdb_res } case LogicalTypeId::BLOB: { idx_t row = 0; - auto target = (duckdb_blob *)out->columns[col].data; + auto target = (duckdb_blob *)out->__deprecated_columns[col].__deprecated_data; for (auto &chunk : result->collection.Chunks()) { auto source = FlatVector::GetData(chunk->data[col]); for (idx_t k = 0; k < chunk->size(); k++) { @@ -100110,7 +101764,7 @@ duckdb_state duckdb_translate_result(MaterializedQueryResult *result, duckdb_res case LogicalTypeId::TIMESTAMP_MS: case LogicalTypeId::TIMESTAMP_SEC: { idx_t row = 0; - auto target = (timestamp_t *)out->columns[col].data; + auto target = (timestamp_t *)out->__deprecated_columns[col].__deprecated_data; for (auto &chunk : result->collection.Chunks()) { auto source = FlatVector::GetData(chunk->data[col]); @@ -100132,7 +101786,7 @@ duckdb_state duckdb_translate_result(MaterializedQueryResult *result, duckdb_res } case LogicalTypeId::HUGEINT: { idx_t row = 0; - auto target = (duckdb_hugeint *)out->columns[col].data; + auto target = (duckdb_hugeint *)out->__deprecated_columns[col].__deprecated_data; for (auto &chunk : result->collection.Chunks()) { auto source = FlatVector::GetData(chunk->data[col]); for (idx_t k = 0; k < chunk->size(); k++) { @@ -100147,7 +101801,7 @@ duckdb_state duckdb_translate_result(MaterializedQueryResult *result, duckdb_res } case LogicalTypeId::INTERVAL: { idx_t row = 0; - auto target = (duckdb_interval *)out->columns[col].data; + auto target = (duckdb_interval *)out->__deprecated_columns[col].__deprecated_data; for (auto &chunk : result->collection.Chunks()) { auto source = FlatVector::GetData(chunk->data[col]); for (idx_t k = 0; k < chunk->size(); k++) { @@ -100172,102 +101826,102 @@ duckdb_state duckdb_translate_result(MaterializedQueryResult *result, duckdb_res } // namespace duckdb -static void duckdb_destroy_column(duckdb_column column, idx_t count) { - if (column.data) { - if (column.type == DUCKDB_TYPE_VARCHAR) { +static void DuckdbDestroyColumn(duckdb_column column, idx_t count) { + if (column.__deprecated_data) { + if (column.__deprecated_type == DUCKDB_TYPE_VARCHAR) { // varchar, delete individual strings - auto data = (char **)column.data; + auto data = (char **)column.__deprecated_data; for (idx_t i = 0; i < count; i++) { if (data[i]) { duckdb_free(data[i]); } } - } else if (column.type == DUCKDB_TYPE_BLOB) { + } else if (column.__deprecated_type == DUCKDB_TYPE_BLOB) { // blob, delete individual blobs - auto data = (duckdb_blob *)column.data; + auto data = (duckdb_blob *)column.__deprecated_data; for (idx_t i = 0; i < count; i++) { if (data[i].data) { duckdb_free((void *)data[i].data); } } } - duckdb_free(column.data); + duckdb_free(column.__deprecated_data); } - if (column.nullmask) { - duckdb_free(column.nullmask); + if (column.__deprecated_nullmask) { + duckdb_free(column.__deprecated_nullmask); } - if (column.name) { - duckdb_free(column.name); + if (column.__deprecated_name) { + duckdb_free(column.__deprecated_name); } } void duckdb_destroy_result(duckdb_result *result) { - if (result->error_message) { - duckdb_free(result->error_message); + if (result->__deprecated_error_message) { + duckdb_free(result->__deprecated_error_message); } - if (result->columns) { - for (idx_t i = 0; i < result->column_count; i++) { - duckdb_destroy_column(result->columns[i], result->row_count); + if (result->__deprecated_columns) { + for (idx_t i = 0; i < result->__deprecated_column_count; i++) { + DuckdbDestroyColumn(result->__deprecated_columns[i], result->__deprecated_row_count); } - duckdb_free(result->columns); + duckdb_free(result->__deprecated_columns); } memset(result, 0, sizeof(duckdb_result)); } const char *duckdb_column_name(duckdb_result *result, idx_t col) { - if (!result || col >= result->column_count) { + if (!result || col >= result->__deprecated_column_count) { return nullptr; } - return result->columns[col].name; + return result->__deprecated_columns[col].__deprecated_name; } duckdb_type duckdb_column_type(duckdb_result *result, idx_t col) { - if (!result || col >= result->column_count) { + if (!result || col >= result->__deprecated_column_count) { return DUCKDB_TYPE_INVALID; } - return result->columns[col].type; + return result->__deprecated_columns[col].__deprecated_type; } idx_t duckdb_column_count(duckdb_result *result) { if (!result) { return 0; } - return result->column_count; + return result->__deprecated_column_count; } idx_t duckdb_row_count(duckdb_result *result) { if (!result) { return 0; } - return result->row_count; + return result->__deprecated_row_count; } idx_t duckdb_rows_changed(duckdb_result *result) { if (!result) { return 0; } - return result->rows_changed; + return result->__deprecated_rows_changed; } void *duckdb_column_data(duckdb_result *result, idx_t col) { - if (!result || col >= result->column_count) { + if (!result || col >= result->__deprecated_column_count) { return nullptr; } - return result->columns[col].data; + return result->__deprecated_columns[col].__deprecated_data; } bool *duckdb_nullmask_data(duckdb_result *result, idx_t col) { - if (!result || col >= result->column_count) { + if (!result || col >= result->__deprecated_column_count) { return nullptr; } - return result->columns[col].nullmask; + return result->__deprecated_columns[col].__deprecated_nullmask; } char *duckdb_result_error(duckdb_result *result) { if (!result) { return nullptr; } - return result->error_message; + return result->__deprecated_error_message; } @@ -100298,8 +101952,8 @@ namespace duckdb { //===--------------------------------------------------------------------===// template T UnsafeFetch(duckdb_result *result, idx_t col, idx_t row) { - D_ASSERT(row < result->row_count); - return ((T *)result->columns[col].data)[row]; + D_ASSERT(row < result->__deprecated_row_count); + return ((T *)result->__deprecated_columns[col].__deprecated_data)[row]; } //===--------------------------------------------------------------------===// @@ -100420,10 +102074,10 @@ RESULT_TYPE TryCastCInternal(duckdb_result *result, idx_t col, idx_t row) { } static bool CanFetchValue(duckdb_result *result, idx_t col, idx_t row) { - if (!result || col >= result->column_count || row >= result->row_count) { + if (!result || col >= result->__deprecated_column_count || row >= result->__deprecated_row_count) { return false; } - if (result->columns[col].nullmask[row]) { + if (result->__deprecated_columns[col].__deprecated_nullmask[row]) { return false; } return true; @@ -100434,7 +102088,7 @@ static RESULT_TYPE GetInternalCValue(duckdb_result *result, idx_t col, idx_t row if (!CanFetchValue(result, col, row)) { return FetchDefaultValue::Operation(); } - switch (result->columns[col].type) { + switch (result->__deprecated_columns[col].__deprecated_type) { case DUCKDB_TYPE_BOOLEAN: return TryCastCInternal(result, col, row); case DUCKDB_TYPE_TINYINT: @@ -100575,7 +102229,7 @@ char *duckdb_value_varchar_internal(duckdb_result *result, idx_t col, idx_t row) } duckdb_blob duckdb_value_blob(duckdb_result *result, idx_t col, idx_t row) { - if (CanFetchValue(result, col, row) && result->columns[col].type == DUCKDB_TYPE_BLOB) { + if (CanFetchValue(result, col, row) && result->__deprecated_columns[col].__deprecated_type == DUCKDB_TYPE_BLOB) { auto internal_result = UnsafeFetch(result, col, row); duckdb_blob result_blob; @@ -100588,10 +102242,10 @@ duckdb_blob duckdb_value_blob(duckdb_result *result, idx_t col, idx_t row) { } bool duckdb_value_is_null(duckdb_result *result, idx_t col, idx_t row) { - if (!result || col >= result->column_count || row >= result->row_count) { + if (!result || col >= result->__deprecated_column_count || row >= result->__deprecated_row_count) { return false; } - return result->columns[col].nullmask[row]; + return result->__deprecated_columns[col].__deprecated_nullmask[row]; } //===----------------------------------------------------------------------===// @@ -100620,7 +102274,7 @@ namespace duckdb { class Value; -//! Abstact type that provide client-spcific context to FileSystem. +//! Abstract type that provide client-specific context to FileSystem. class FileOpener { public: virtual ~FileOpener() {}; @@ -100839,6 +102493,9 @@ class DropStatement : public SQLStatement { unique_ptr info; +protected: + DropStatement(const DropStatement &other); + public: unique_ptr Copy() const override; }; @@ -100868,38 +102525,15 @@ class ExecuteStatement : public SQLStatement { string name; vector> values; -public: - unique_ptr Copy() const override; -}; -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/statement/explain_statement.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - -namespace duckdb { - -class ExplainStatement : public SQLStatement { -public: - explicit ExplainStatement(unique_ptr stmt); - - unique_ptr stmt; +protected: + ExecuteStatement(const ExecuteStatement &other); public: unique_ptr Copy() const override; }; - } // namespace duckdb + //===----------------------------------------------------------------------===// // DuckDB // @@ -100922,6 +102556,9 @@ class PrepareStatement : public SQLStatement { unique_ptr statement; string name; +protected: + PrepareStatement(const PrepareStatement &other); + public: unique_ptr Copy() const override; }; @@ -101007,6 +102644,9 @@ class RelationStatement : public SQLStatement { shared_ptr relation; +protected: + RelationStatement(const RelationStatement &other) = default; + public: unique_ptr Copy() const override; }; @@ -101049,6 +102689,9 @@ class PragmaStatement : public SQLStatement { unique_ptr info; +protected: + PragmaStatement(const PragmaStatement &other); + public: unique_ptr Copy() const override; }; @@ -101086,32 +102729,31 @@ class PragmaHandler { namespace duckdb { -class ClientContextLock { -public: - explicit ClientContextLock(mutex &context_lock) : client_guard(context_lock) { - } - - ~ClientContextLock() { - } - -private: - lock_guard client_guard; +struct ActiveQueryContext { + //! The query that is currently being executed + string query; + //! The currently open result + BaseQueryResult *open_result = nullptr; + //! Prepared statement data + shared_ptr prepared; + //! The query executor + unique_ptr executor; + //! The progress bar + unique_ptr progress_bar; }; ClientContext::ClientContext(shared_ptr database) - : profiler(make_unique()), query_profiler_history(make_unique()), - db(move(database)), transaction(db->GetTransactionManager(), *this), interrupted(false), executor(*this), + : profiler(make_shared(*this)), query_profiler_history(make_unique()), + db(move(database)), transaction(db->GetTransactionManager(), *this), interrupted(false), temporary_objects(make_unique(&db->GetCatalog(), TEMP_SCHEMA, true)), catalog_search_path(make_unique(*this)), - file_opener(make_unique(*this)), open_result(nullptr) { + file_opener(make_unique(*this)) { std::random_device rd; random_engine.seed(rd()); - - progress_bar = make_unique(&executor, wait_time); } ClientContext::~ClientContext() { - if (std::uncaught_exception()) { + if (Exception::UncaughtException()) { return; } // destroy the client context and rollback if there is an active transaction @@ -101134,87 +102776,162 @@ void ClientContext::Destroy() { CleanupInternal(*lock); } -void ClientContext::Cleanup() { - auto lock = LockContext(); - CleanupInternal(*lock); +unique_ptr ClientContext::Fetch(ClientContextLock &lock, StreamQueryResult &result) { + D_ASSERT(IsActiveResult(lock, &result)); + D_ASSERT(active_query->executor); + return FetchInternal(lock, *active_query->executor, result); } -unique_ptr ClientContext::Fetch() { - auto lock = LockContext(); - if (!open_result) { - throw InternalException("Fetch was called, but there is no open result (or the result was previously closed)"); - } +unique_ptr ClientContext::FetchInternal(ClientContextLock &lock, Executor &executor, + BaseQueryResult &result) { + bool invalidate_query = true; try { // fetch the chunk and return it - auto chunk = FetchInternal(*lock); + auto chunk = executor.FetchChunk(); + if (!chunk || chunk->size() == 0) { + CleanupInternal(lock, &result); + } return chunk; + } catch (StandardException &ex) { + // standard exceptions do not invalidate the current transaction + result.error = ex.what(); + invalidate_query = false; } catch (std::exception &ex) { - open_result->error = ex.what(); + result.error = ex.what(); } catch (...) { // LCOV_EXCL_START - open_result->error = "Unhandled exception in Fetch"; + result.error = "Unhandled exception in FetchInternal"; } // LCOV_EXCL_STOP - open_result->success = false; - CleanupInternal(*lock); + result.success = false; + CleanupInternal(lock, &result, invalidate_query); return nullptr; } -string ClientContext::FinalizeQuery(ClientContextLock &lock, bool success) { +void ClientContext::BeginTransactionInternal(ClientContextLock &lock, bool requires_valid_transaction) { + // check if we are on AutoCommit. In this case we should start a transaction + D_ASSERT(!active_query); + if (requires_valid_transaction && transaction.HasActiveTransaction() && + transaction.ActiveTransaction().IsInvalidated()) { + throw Exception("Failed: transaction has been invalidated!"); + } + active_query = make_unique(); + if (transaction.IsAutoCommit()) { + transaction.BeginTransaction(); + } +} + +void ClientContext::BeginQueryInternal(ClientContextLock &lock, const string &query) { + BeginTransactionInternal(lock, false); + LogQueryInternal(lock, query); + active_query->query = query; + query_progress = -1; + ActiveTransaction().active_query = db->GetTransactionManager().GetQueryNumber(); +} + +string ClientContext::EndQueryInternal(ClientContextLock &lock, bool success, bool invalidate_transaction) { profiler->EndQuery(); - executor.Reset(); + D_ASSERT(active_query.get()); string error; - if (transaction.HasActiveTransaction()) { - ActiveTransaction().active_query = MAXIMUM_QUERY_ID; - // Move the query profiler into the history - auto &prev_profilers = query_profiler_history->GetPrevProfilers(); - prev_profilers.emplace_back(transaction.ActiveTransaction().active_query, move(profiler)); - // Reinitialize the query profiler - profiler = make_unique(); - // Propagate settings of the saved query into the new profiler. - profiler->Propagate(*prev_profilers.back().second); - if (prev_profilers.size() >= query_profiler_history->GetPrevProfilersSize()) { - prev_profilers.pop_front(); - } - try { + try { + if (transaction.HasActiveTransaction()) { + // Move the query profiler into the history + auto &prev_profilers = query_profiler_history->GetPrevProfilers(); + prev_profilers.emplace_back(transaction.ActiveTransaction().active_query, move(profiler)); + // Reinitialize the query profiler + profiler = make_shared(*this); + // Propagate settings of the saved query into the new profiler. + profiler->Propagate(*prev_profilers.back().second); + if (prev_profilers.size() >= query_profiler_history->GetPrevProfilersSize()) { + prev_profilers.pop_front(); + } + + ActiveTransaction().active_query = MAXIMUM_QUERY_ID; if (transaction.IsAutoCommit()) { if (success) { - // query was successful: commit transaction.Commit(); } else { - // query was unsuccessful: rollback transaction.Rollback(); } + } else if (invalidate_transaction) { + D_ASSERT(!success); + ActiveTransaction().Invalidate(); } - } catch (std::exception &ex) { - error = ex.what(); - } catch (...) { // LCOV_EXCL_START - error = "Unhandled exception!"; - } // LCOV_EXCL_STOP - } + } + } catch (std::exception &ex) { + error = ex.what(); + } catch (...) { // LCOV_EXCL_START + error = "Unhandled exception!"; + } // LCOV_EXCL_STOP + active_query.reset(); + query_progress = -1; return error; } -void ClientContext::CleanupInternal(ClientContextLock &lock) { - if (!open_result) { - // no result currently open +void ClientContext::CleanupInternal(ClientContextLock &lock, BaseQueryResult *result, bool invalidate_transaction) { + if (!active_query) { + // no query currently active return; } + if (active_query->executor) { + active_query->executor->CancelTasks(); + } + active_query->progress_bar.reset(); - auto error = FinalizeQuery(lock, open_result->success); - if (open_result->success) { + auto error = EndQueryInternal(lock, result ? result->success : false, invalidate_transaction); + if (result && result->success) { // if an error occurred while committing report it in the result - open_result->error = error; - open_result->success = error.empty(); + result->error = error; + result->success = error.empty(); } + D_ASSERT(!active_query); +} - open_result->is_open = false; - open_result = nullptr; +Executor &ClientContext::GetExecutor() { + D_ASSERT(active_query); + D_ASSERT(active_query->executor); + return *active_query->executor; +} - this->query = string(); +const string &ClientContext::GetCurrentQuery() { + D_ASSERT(active_query); + return active_query->query; } -unique_ptr ClientContext::FetchInternal(ClientContextLock &) { - return executor.FetchChunk(); +unique_ptr ClientContext::FetchResultInternal(ClientContextLock &lock, PendingQueryResult &pending, + bool allow_stream_result) { + D_ASSERT(active_query); + D_ASSERT(active_query->open_result == &pending); + D_ASSERT(active_query->prepared); + auto &prepared = *active_query->prepared; + bool create_stream_result = prepared.allow_stream_result && allow_stream_result; + if (create_stream_result) { + active_query->progress_bar.reset(); + query_progress = -1; + + // successfully compiled SELECT clause and it is the last statement + // return a StreamQueryResult so the client can call Fetch() on it and stream the result + auto stream_result = + make_unique(pending.statement_type, shared_from_this(), pending.types, pending.names); + active_query->open_result = stream_result.get(); + return move(stream_result); + } + // create a materialized result by continuously fetching + auto result = make_unique(pending.statement_type, pending.types, pending.names); + while (true) { + auto chunk = FetchInternal(lock, GetExecutor(), *result); + if (!chunk || chunk->size() == 0) { + break; + } +#ifdef DEBUG + for (idx_t i = 0; i < chunk->ColumnCount(); i++) { + if (pending.types[i].id() == LogicalTypeId::VARCHAR) { + chunk->data[i].UTFVerify(chunk->size()); + } + } +#endif + result->collection.Append(*chunk); + } + return move(result); } shared_ptr ClientContext::CreatePreparedStatement(ClientContextLock &lock, const string &query, @@ -101222,11 +102939,12 @@ shared_ptr ClientContext::CreatePreparedStatement(ClientC StatementType statement_type = statement->type; auto result = make_shared(statement_type); - profiler->StartPhase("planner"); + auto &profiler = QueryProfiler::Get(*this); + profiler.StartPhase("planner"); Planner planner(*this); planner.CreatePlan(move(statement)); D_ASSERT(planner.plan); - profiler->EndPhase(); + profiler.EndPhase(); auto plan = move(planner.plan); #ifdef DEBUG @@ -101241,23 +102959,23 @@ shared_ptr ClientContext::CreatePreparedStatement(ClientC result->value_map = move(planner.value_map); result->catalog_version = Transaction::GetTransaction(*this).catalog_version; - if (enable_optimizer) { - profiler->StartPhase("optimizer"); + if (config.enable_optimizer) { + profiler.StartPhase("optimizer"); Optimizer optimizer(*planner.binder, *this); plan = optimizer.Optimize(move(plan)); D_ASSERT(plan); - profiler->EndPhase(); + profiler.EndPhase(); #ifdef DEBUG plan->Verify(); #endif } - profiler->StartPhase("physical_planner"); + 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)); - profiler->EndPhase(); + profiler.EndPhase(); #ifdef DEBUG D_ASSERT(!physical_plan->ToString().empty()); @@ -101266,20 +102984,20 @@ shared_ptr ClientContext::CreatePreparedStatement(ClientC return result; } -int ClientContext::GetProgress() { - D_ASSERT(progress_bar); - return progress_bar->GetCurrentPercentage(); +double ClientContext::GetProgress() { + return query_progress.load(); } -unique_ptr ClientContext::ExecutePreparedStatement(ClientContextLock &lock, const string &query, - shared_ptr statement_p, - vector bound_values, bool allow_stream_result) { +unique_ptr ClientContext::PendingPreparedStatement(ClientContextLock &lock, + shared_ptr statement_p, + vector bound_values) { + D_ASSERT(active_query); auto &statement = *statement_p; if (ActiveTransaction().IsInvalidated() && statement.requires_valid_transaction) { throw Exception("Current transaction is aborted (please ROLLBACK)"); } - auto &config = DBConfig::GetConfig(*this); - if (config.access_mode == AccessMode::READ_ONLY && !statement.read_only) { + auto &db_config = DBConfig::GetConfig(*this); + if (db_config.access_mode == AccessMode::READ_ONLY && !statement.read_only) { throw Exception(StringUtil::Format("Cannot execute statement of type \"%s\" in read-only mode!", StatementTypeToString(statement.statement_type))); } @@ -101287,47 +103005,42 @@ unique_ptr ClientContext::ExecutePreparedStatement(ClientContextLoc // bind the bound values before execution statement.Bind(move(bound_values)); - bool create_stream_result = statement.allow_stream_result && allow_stream_result; - if (enable_progress_bar) { - progress_bar->Initialize(wait_time); - progress_bar->Start(); + 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); + active_query->progress_bar->Start(); + query_progress = 0; } - // store the physical plan in the context for calls to Fetch() executor.Initialize(statement.plan.get()); - auto types = executor.GetTypes(); - D_ASSERT(types == statement.types); + D_ASSERT(!active_query->open_result); - if (create_stream_result) { - if (enable_progress_bar) { - progress_bar->Stop(); - } - // successfully compiled SELECT clause and it is the last statement - // return a StreamQueryResult so the client can call Fetch() on it and stream the result - return make_unique(statement.statement_type, shared_from_this(), statement.types, - statement.names, move(statement_p)); - } - // create a materialized result by continuously fetching - auto result = make_unique(statement.statement_type, statement.types, statement.names); - while (true) { - auto chunk = FetchInternal(lock); - if (chunk->size() == 0) { - break; - } -#ifdef DEBUG - for (idx_t i = 0; i < chunk->ColumnCount(); i++) { - if (statement.types[i].id() == LogicalTypeId::VARCHAR) { - chunk->data[i].UTFVerify(chunk->size()); - } + auto pending_result = make_unique(shared_from_this(), *statement_p, move(types)); + active_query->prepared = move(statement_p); + active_query->open_result = pending_result.get(); + return pending_result; +} + +PendingExecutionResult ClientContext::ExecuteTaskInternal(ClientContextLock &lock, PendingQueryResult &result) { + D_ASSERT(active_query); + D_ASSERT(active_query->open_result == &result); + try { + auto result = active_query->executor->ExecuteTask(); + if (active_query->progress_bar) { + active_query->progress_bar->Update(result == PendingExecutionResult::RESULT_READY); + query_progress = active_query->progress_bar->GetCurrentPercentage(); } -#endif - result->collection.Append(*chunk); - } - if (enable_progress_bar) { - progress_bar->Stop(); - } - return move(result); + return result; + } catch (std::exception &ex) { + result.error = ex.what(); + } catch (...) { // LCOV_EXCL_START + result.error = "Unhandled exception in ExecuteTaskInternal"; + } // LCOV_EXCL_STOP + EndQueryInternal(lock, false, true); + result.success = false; + return PendingExecutionResult::EXECUTION_ERROR; } void ClientContext::InitialCleanup(ClientContextLock &lock) { @@ -101342,7 +103055,7 @@ vector> ClientContext::ParseStatements(const string &qu } vector> ClientContext::ParseStatementsInternal(ClientContextLock &lock, const string &query) { - Parser parser; + Parser parser(GetParserOptions()); parser.ParseQuery(query); PragmaHandler handler(*this); @@ -101374,7 +103087,7 @@ unique_ptr ClientContext::ExtractPlan(const string &query) { plan = move(planner.plan); - if (enable_optimizer) { + if (config.enable_optimizer) { Optimizer optimizer(*planner.binder, *this); plan = optimizer.Optimize(move(plan)); } @@ -101430,64 +103143,112 @@ unique_ptr ClientContext::Prepare(const string &query) { } } +unique_ptr ClientContext::PendingQueryPreparedInternal(ClientContextLock &lock, const string &query, + shared_ptr &prepared, + vector &values) { + try { + InitialCleanup(lock); + } catch (std::exception &ex) { + return make_unique(ex.what()); + } + return PendingStatementOrPreparedStatementInternal(lock, query, nullptr, prepared, &values); +} + +unique_ptr +ClientContext::PendingQuery(const string &query, shared_ptr &prepared, vector &values) { + auto lock = LockContext(); + return PendingQueryPreparedInternal(*lock, query, prepared, values); +} + unique_ptr ClientContext::Execute(const string &query, shared_ptr &prepared, vector &values, bool allow_stream_result) { auto lock = LockContext(); - try { - InitialCleanup(*lock); - } catch (std::exception &ex) { - return make_unique(ex.what()); + auto pending = PendingQueryPreparedInternal(*lock, query, prepared, values); + if (!pending->success) { + return make_unique(pending->error); } - LogQueryInternal(*lock, query); - return RunStatementOrPreparedStatement(*lock, query, nullptr, prepared, &values, allow_stream_result); + return pending->ExecuteInternal(*lock, allow_stream_result); } -unique_ptr ClientContext::RunStatementInternal(ClientContextLock &lock, const string &query, - unique_ptr statement, - bool allow_stream_result) { +unique_ptr ClientContext::PendingStatementInternal(ClientContextLock &lock, const string &query, + unique_ptr statement) { // prepare the query for execution auto prepared = CreatePreparedStatement(lock, query, move(statement)); // by default, no values are bound vector bound_values; // execute the prepared statement - return ExecutePreparedStatement(lock, query, move(prepared), move(bound_values), allow_stream_result); + return PendingPreparedStatement(lock, move(prepared), move(bound_values)); +} + +unique_ptr ClientContext::RunStatementInternal(ClientContextLock &lock, const string &query, + unique_ptr statement, + bool allow_stream_result, bool verify) { + auto pending = PendingQueryInternal(lock, move(statement), verify); + if (!pending->success) { + return make_unique(move(pending->error)); + } + return ExecutePendingQueryInternal(lock, *pending, allow_stream_result); } -unique_ptr ClientContext::RunStatementOrPreparedStatement(ClientContextLock &lock, const string &query, - unique_ptr statement, - shared_ptr &prepared, - vector *values, - bool allow_stream_result) { - this->query = query; +bool ClientContext::IsActiveResult(ClientContextLock &lock, BaseQueryResult *result) { + if (!active_query) { + return false; + } + return active_query->open_result == result; +} - unique_ptr result; - // check if we are on AutoCommit. In this case we should start a transaction. - if (transaction.IsAutoCommit()) { - transaction.BeginTransaction(); +static bool IsExplainAnalyze(SQLStatement *statement) { + if (!statement) { + return false; } - ActiveTransaction().active_query = db->GetTransactionManager().GetQueryNumber(); - if (statement && query_verification_enabled) { + if (statement->type != StatementType::EXPLAIN_STATEMENT) { + return false; + } + auto &explain = (ExplainStatement &)*statement; + return explain.explain_type == ExplainType::EXPLAIN_ANALYZE; +} + +unique_ptr ClientContext::PendingStatementOrPreparedStatementInternal( + ClientContextLock &lock, const string &query, unique_ptr statement, + shared_ptr &prepared, vector *values) { + // check if we are on AutoCommit. In this case we should start a transaction. + if (statement && config.query_verification_enabled) { // query verification is enabled // create a copy of the statement, and use the copy // this way we verify that the copy correctly copies all properties auto copied_statement = statement->Copy(); if (statement->type == StatementType::SELECT_STATEMENT) { // in case this is a select query, we verify the original statement - string error = VerifyQuery(lock, query, move(statement)); + string error; + try { + error = VerifyQuery(lock, query, move(statement)); + } catch (std::exception &ex) { + error = ex.what(); + } if (!error.empty()) { - // query failed: abort now - FinalizeQuery(lock, false); // error in verifying query - return make_unique(error); + return make_unique(error); } } statement = move(copied_statement); } + return PendingStatementOrPreparedStatement(lock, query, move(statement), prepared, values); +} + +unique_ptr +ClientContext::PendingStatementOrPreparedStatement(ClientContextLock &lock, const string &query, + unique_ptr statement, + shared_ptr &prepared, vector *values) { + unique_ptr result; + + BeginQueryInternal(lock, query); // start the profiler - profiler->StartQuery(query); + auto &profiler = QueryProfiler::Get(*this); + profiler.StartQuery(query, IsExplainAnalyze(statement ? statement.get() : prepared->unbound_statement.get())); + bool invalidate_query = true; try { if (statement) { - result = RunStatementInternal(lock, query, move(statement), allow_stream_result); + result = PendingStatementInternal(lock, query, move(statement)); } else { auto &catalog = Catalog::GetCatalog(*this); if (prepared->unbound_statement && catalog.GetCatalogVersion() != prepared->catalog_version) { @@ -101500,68 +103261,22 @@ unique_ptr ClientContext::RunStatementOrPreparedStatement(ClientCon new_prepared->unbound_statement = move(prepared->unbound_statement); prepared = move(new_prepared); } - result = ExecutePreparedStatement(lock, query, prepared, *values, allow_stream_result); + result = PendingPreparedStatement(lock, prepared, *values); } } catch (StandardException &ex) { // standard exceptions do not invalidate the current transaction - result = make_unique(ex.what()); + result = make_unique(ex.what()); + invalidate_query = false; } catch (std::exception &ex) { // other types of exceptions do invalidate the current transaction - if (transaction.HasActiveTransaction()) { - ActiveTransaction().Invalidate(); - } - result = make_unique(ex.what()); + result = make_unique(ex.what()); } if (!result->success) { - // initial failures should always be reported as MaterializedResult - D_ASSERT(result->type != QueryResultType::STREAM_RESULT); // query failed: abort now - FinalizeQuery(lock, false); + EndQueryInternal(lock, false, invalidate_query); return result; } - // query succeeded, append to list of results - if (result->type == QueryResultType::STREAM_RESULT) { - // store as currently open result if it is a stream result - this->open_result = (StreamQueryResult *)result.get(); - } else { - // finalize the query if it is not a stream result - string error = FinalizeQuery(lock, true); - if (!error.empty()) { - // failure in committing transaction - return make_unique(error); - } - } - return result; -} - -unique_ptr ClientContext::RunStatement(ClientContextLock &lock, const string &query, - unique_ptr statement, bool allow_stream_result) { - shared_ptr prepared; - return RunStatementOrPreparedStatement(lock, query, move(statement), prepared, nullptr, allow_stream_result); -} - -unique_ptr ClientContext::RunStatements(ClientContextLock &lock, const string &query, - vector> &statements, - bool allow_stream_result) { - // now we have a list of statements - // iterate over them and execute them one by one - unique_ptr result; - QueryResult *last_result = nullptr; - for (idx_t i = 0; i < statements.size(); i++) { - auto &statement = statements[i]; - bool is_last_statement = i + 1 == statements.size(); - auto current_result = RunStatement(lock, query, move(statement), allow_stream_result && is_last_statement); - // now append the result to the list of results - if (!last_result) { - // first result of the query - result = move(current_result); - last_result = result.get(); - } else { - // later results; attach to the result chain - last_result->next = move(current_result); - last_result = last_result->next.get(); - } - } + D_ASSERT(active_query->open_result == result.get()); return result; } @@ -101587,34 +103302,96 @@ void ClientContext::LogQueryInternal(ClientContextLock &, const string &query) { } unique_ptr ClientContext::Query(unique_ptr statement, bool allow_stream_result) { - auto lock = LockContext(); - LogQueryInternal(*lock, statement->query.substr(statement->stmt_location, statement->stmt_length)); - - vector> statements; - statements.push_back(move(statement)); - - return RunStatements(*lock, query, statements, allow_stream_result); + auto pending_query = PendingQuery(move(statement)); + return pending_query->Execute(allow_stream_result); } unique_ptr ClientContext::Query(const string &query, bool allow_stream_result) { auto lock = LockContext(); - LogQueryInternal(*lock, query); + string error; vector> statements; + if (!ParseStatements(*lock, query, statements, error)) { + return make_unique(move(error)); + } + if (statements.empty()) { + // no statements, return empty successful result + return make_unique(StatementType::INVALID_STATEMENT); + } + + unique_ptr result; + QueryResult *last_result = nullptr; + for (idx_t i = 0; i < statements.size(); i++) { + auto &statement = statements[i]; + bool is_last_statement = i + 1 == statements.size(); + bool stream_result = allow_stream_result && is_last_statement; + auto pending_query = PendingQueryInternal(*lock, move(statement)); + unique_ptr current_result; + if (!pending_query->success) { + current_result = make_unique(pending_query->error); + } else { + current_result = ExecutePendingQueryInternal(*lock, *pending_query, stream_result); + } + // now append the result to the list of results + if (!last_result) { + // first result of the query + result = move(current_result); + last_result = result.get(); + } else { + // later results; attach to the result chain + last_result->next = move(current_result); + last_result = last_result->next.get(); + } + } + return result; +} + +bool ClientContext::ParseStatements(ClientContextLock &lock, const string &query, + vector> &result, string &error) { try { - InitialCleanup(*lock); + InitialCleanup(lock); // parse the query and transform it into a set of statements - statements = ParseStatementsInternal(*lock, query); + result = ParseStatementsInternal(lock, query); + return true; } catch (std::exception &ex) { - return make_unique(ex.what()); + error = ex.what(); + return false; } +} - if (statements.empty()) { - // no statements, return empty successful result - return make_unique(StatementType::INVALID_STATEMENT); +unique_ptr ClientContext::PendingQuery(const string &query) { + auto lock = LockContext(); + + string error; + vector> statements; + if (!ParseStatements(*lock, query, statements, error)) { + return make_unique(move(error)); + } + if (statements.size() != 1) { + return make_unique("PendingQuery can only take a single statement"); } + return PendingQueryInternal(*lock, move(statements[0])); +} - return RunStatements(*lock, query, statements, allow_stream_result); +unique_ptr ClientContext::PendingQuery(unique_ptr statement) { + auto lock = LockContext(); + return PendingQueryInternal(*lock, move(statement)); +} + +unique_ptr ClientContext::PendingQueryInternal(ClientContextLock &lock, + unique_ptr statement, bool verify) { + auto query = statement->query; + shared_ptr prepared; + if (verify) { + return PendingStatementOrPreparedStatementInternal(lock, query, move(statement), prepared, nullptr); + } else { + return PendingStatementOrPreparedStatement(lock, query, move(statement), prepared, nullptr); + } +} + +unique_ptr ClientContext::ExecutePendingQueryInternal(ClientContextLock &lock, PendingQueryResult &query, + bool allow_stream_result) { + return query.ExecuteInternal(lock, allow_stream_result); } void ClientContext::Interrupt() { @@ -101623,12 +103400,14 @@ void ClientContext::Interrupt() { void ClientContext::EnableProfiling() { auto lock = LockContext(); - profiler->Enable(); + auto &config = ClientConfig::GetConfig(*this); + config.enable_profiler = true; } void ClientContext::DisableProfiling() { auto lock = LockContext(); - profiler->Disable(); + auto &config = ClientConfig::GetConfig(*this); + config.enable_profiler = false; } string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query, unique_ptr statement) { @@ -101690,9 +103469,10 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query, #endif // disable profiling if it is enabled - bool profiling_is_enabled = profiler->IsEnabled(); + auto &config = ClientConfig::GetConfig(*this); + bool profiling_is_enabled = config.enable_profiler; if (profiling_is_enabled) { - profiler->Disable(); + config.enable_profiler = false; } // see below @@ -101709,20 +103489,20 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query, // execute the original statement try { - auto result = RunStatementInternal(lock, query, move(statement), false); + auto result = RunStatementInternal(lock, query, move(statement), false, false); original_result = unique_ptr_cast(move(result)); } catch (std::exception &ex) { original_result->error = ex.what(); original_result->success = false; - interrupted = false; } + interrupted = false; // check explain, only if q does not already contain EXPLAIN if (original_result->success) { auto explain_q = "EXPLAIN " + query; auto explain_stmt = make_unique(move(statement_copy_for_explain)); try { - RunStatementInternal(lock, explain_q, move(explain_stmt), false); + RunStatementInternal(lock, explain_q, move(explain_stmt), false, false); } catch (std::exception &ex) { // LCOV_EXCL_START return "EXPLAIN failed but query did not (" + string(ex.what()) + ")"; } // LCOV_EXCL_STOP @@ -101730,36 +103510,36 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query, // now execute the copied statement try { - auto result = RunStatementInternal(lock, query, move(copied_stmt), false); + auto result = RunStatementInternal(lock, query, move(copied_stmt), false, false); copied_result = unique_ptr_cast(move(result)); } catch (std::exception &ex) { copied_result->error = ex.what(); copied_result->success = false; - interrupted = false; } + interrupted = false; // now execute the deserialized statement try { - auto result = RunStatementInternal(lock, query, move(deserialized_stmt), false); + auto result = RunStatementInternal(lock, query, move(deserialized_stmt), false, false); deserialized_result = unique_ptr_cast(move(result)); } catch (std::exception &ex) { deserialized_result->error = ex.what(); deserialized_result->success = false; - interrupted = false; } + interrupted = false; // now execute the unoptimized statement - enable_optimizer = false; + config.enable_optimizer = false; try { - auto result = RunStatementInternal(lock, query, move(unoptimized_stmt), false); + auto result = RunStatementInternal(lock, query, move(unoptimized_stmt), false, false); unoptimized_result = unique_ptr_cast(move(result)); } catch (std::exception &ex) { unoptimized_result->error = ex.what(); unoptimized_result->success = false; - interrupted = false; } - enable_optimizer = true; + interrupted = false; + config.enable_optimizer = true; if (profiling_is_enabled) { - profiler->Enable(); + config.enable_profiler = true; } // now compare the results @@ -101813,7 +103593,7 @@ bool ClientContext::UpdateFunctionInfoFromEntry(ScalarFunctionCatalogEntry *exis void ClientContext::RegisterFunction(CreateFunctionInfo *info) { RunFunctionInTransaction([&]() { auto &catalog = Catalog::GetCatalog(*this); - ScalarFunctionCatalogEntry *existing_function = (ScalarFunctionCatalogEntry *)catalog.GetEntry( + auto existing_function = (ScalarFunctionCatalogEntry *)catalog.GetEntry( *this, CatalogType::SCALAR_FUNCTION_ENTRY, info->schema, info->name, true); if (existing_function) { if (UpdateFunctionInfoFromEntry(existing_function, (CreateScalarFunctionInfo *)info)) { @@ -101835,6 +103615,7 @@ void ClientContext::RunFunctionInTransactionInternal(ClientContextLock &lock, co // check if we are on AutoCommit. In this case we should start a transaction bool require_new_transaction = transaction.IsAutoCommit() && !transaction.HasActiveTransaction(); if (require_new_transaction) { + D_ASSERT(!active_query); transaction.BeginTransaction(); } try { @@ -101917,12 +103698,31 @@ void ClientContext::TryBindRelation(Relation &relation, vector }); } +unordered_set ClientContext::GetTableNames(const string &query) { + auto lock = LockContext(); + + auto statements = ParseStatementsInternal(*lock, query); + if (statements.size() != 1) { + throw InvalidInputException("Expected a single statement"); + } + + unordered_set result; + RunFunctionInTransactionInternal(*lock, [&]() { + // bind the expressions + auto binder = Binder::CreateBinder(*this); + binder->SetBindingMode(BindingMode::EXTRACT_NAMES); + binder->Bind(*statements[0]); + result = binder->GetTableNames(); + }); + return result; +} + unique_ptr ClientContext::Execute(const shared_ptr &relation) { auto lock = LockContext(); InitialCleanup(*lock); string query; - if (query_verification_enabled) { + if (config.query_verification_enabled) { // run the ToString method of any relation we run, mostly to ensure it doesn't crash relation->ToString(); relation->GetAlias(); @@ -101930,12 +103730,14 @@ 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(); - RunStatement(*lock, query, move(select), false); + RunStatementInternal(*lock, query, move(select), false); } } auto &expected_columns = relation->Columns(); auto relation_stmt = make_unique(relation); - auto result = RunStatement(*lock, query, move(relation_stmt), false); + + unique_ptr result; + result = RunStatementInternal(*lock, query, move(relation_stmt), false); if (!result->success) { return result; } @@ -101971,8 +103773,17 @@ unique_ptr ClientContext::Execute(const shared_ptr &relat } bool ClientContext::TryGetCurrentSetting(const std::string &key, Value &result) { - const auto &session_config_map = set_variables; - const auto &global_config_map = db->config.set_variables; + // first check the built-in settings + auto &db_config = DBConfig::GetConfig(*this); + auto option = db_config.GetOptionByName(key); + if (option) { + result = option->get_setting(*this); + return true; + } + + // then check the session values + const auto &session_config_map = config.set_variables; + const auto &global_config_map = db_config.set_variables; auto session_value = session_config_map.find(key); bool found_session_value = session_value != session_config_map.end(); @@ -101986,6 +103797,12 @@ bool ClientContext::TryGetCurrentSetting(const std::string &key, Value &result) return true; } +ParserOptions ClientContext::GetParserOptions() { + ParserOptions options; + options.preserve_identifier_case = ClientConfig::GetConfig(*this).preserve_identifier_case; + return options; +} + } // namespace duckdb @@ -102000,27 +103817,318 @@ bool ClientContextFileOpener::TryGetCurrentSetting(const string &key, Value &res } // namespace duckdb +//===----------------------------------------------------------------------===// +// 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 DebugManyFreeListBlocks { + static constexpr const char *Name = "debug_many_free_list_blocks"; + static constexpr const char *Description = "DEBUG SETTING: add additional blocks to the free list"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::BOOLEAN; + static void SetGlobal(DatabaseInstance *db, DBConfig &config, 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 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 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 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 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 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 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); +}; -static ConfigurationOption internal_options[] = { - {ConfigurationOptionType::ACCESS_MODE, "access_mode", - "Access mode of the database ([AUTOMATIC], READ_ONLY or READ_WRITE)", LogicalTypeId::VARCHAR}, - {ConfigurationOptionType::DEFAULT_ORDER_TYPE, "default_order", - "The order type used when none is specified ([ASC] or DESC)", LogicalTypeId::VARCHAR}, - {ConfigurationOptionType::DEFAULT_NULL_ORDER, "default_null_order", - "Null ordering used when none is specified ([NULLS_FIRST] or NULLS_LAST)", LogicalTypeId::VARCHAR}, - {ConfigurationOptionType::ENABLE_EXTERNAL_ACCESS, "enable_external_access", - "Allow the database to access external state (through e.g. COPY TO/FROM, CSV readers, pandas replacement scans, " - "etc)", - LogicalTypeId::BOOLEAN}, - {ConfigurationOptionType::ENABLE_OBJECT_CACHE, "enable_object_cache", - "Whether or not object cache is used to cache e.g. Parquet metadata", LogicalTypeId::BOOLEAN}, - {ConfigurationOptionType::MAXIMUM_MEMORY, "max_memory", "The maximum memory of the system (e.g. 1GB)", - LogicalTypeId::VARCHAR}, - {ConfigurationOptionType::THREADS, "threads", "The number of total threads used by the system", - LogicalTypeId::BIGINT}, - {ConfigurationOptionType::INVALID, nullptr, nullptr, LogicalTypeId::INVALID}}; +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 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); +}; + +} // namespace duckdb + + +namespace duckdb { + +#define DUCKDB_GLOBAL(_PARAM) \ + { _PARAM::Name, _PARAM::Description, _PARAM::InputType, _PARAM::SetGlobal, nullptr, _PARAM::GetSetting } +#define DUCKDB_GLOBAL_ALIAS(_ALIAS, _PARAM) \ + { _ALIAS, _PARAM::Description, _PARAM::InputType, _PARAM::SetGlobal, nullptr, _PARAM::GetSetting } + +#define DUCKDB_LOCAL(_PARAM) \ + { _PARAM::Name, _PARAM::Description, _PARAM::InputType, nullptr, _PARAM::SetLocal, _PARAM::GetSetting } +#define DUCKDB_LOCAL_ALIAS(_ALIAS, _PARAM) \ + { _ALIAS, _PARAM::Description, _PARAM::InputType, nullptr, _PARAM::SetLocal, _PARAM::GetSetting } + +#define DUCKDB_GLOBAL_LOCAL(_PARAM) \ + { _PARAM::Name, _PARAM::Description, _PARAM::InputType, _PARAM::SetGlobal, _PARAM::SetLocal, _PARAM::GetSetting } +#define DUCKDB_GLOBAL_LOCAL_ALIAS(_ALIAS, _PARAM) \ + { _ALIAS, _PARAM::Description, _PARAM::InputType, _PARAM::SetGlobal, _PARAM::SetLocal, _PARAM::GetSetting } +#define FINAL_SETTING \ + { nullptr, nullptr, LogicalTypeId::INVALID, nullptr, nullptr, nullptr } + +static ConfigurationOption internal_options[] = {DUCKDB_GLOBAL(AccessModeSetting), + DUCKDB_GLOBAL(CheckpointThresholdSetting), + DUCKDB_GLOBAL(DebugCheckpointAbort), + DUCKDB_LOCAL(DebugForceExternal), + DUCKDB_GLOBAL(DebugManyFreeListBlocks), + DUCKDB_GLOBAL(DebugWindowMode), + DUCKDB_GLOBAL_LOCAL(DefaultCollationSetting), + DUCKDB_GLOBAL(DefaultOrderSetting), + DUCKDB_GLOBAL(DefaultNullOrderSetting), + DUCKDB_GLOBAL(DisabledOptimizersSetting), + DUCKDB_GLOBAL(EnableExternalAccessSetting), + DUCKDB_GLOBAL(EnableObjectCacheSetting), + DUCKDB_LOCAL(EnableProfilingSetting), + DUCKDB_LOCAL(EnableProgressBarSetting), + DUCKDB_LOCAL(ExplainOutputSetting), + DUCKDB_GLOBAL(ForceCompressionSetting), + DUCKDB_LOCAL(LogQueryPathSetting), + DUCKDB_GLOBAL(MaximumMemorySetting), + DUCKDB_GLOBAL_ALIAS("memory_limit", MaximumMemorySetting), + DUCKDB_GLOBAL_ALIAS("null_order", DefaultNullOrderSetting), + DUCKDB_LOCAL(PerfectHashThresholdSetting), + DUCKDB_LOCAL(PreserveIdentifierCase), + DUCKDB_LOCAL(ProfilerHistorySize), + DUCKDB_LOCAL(ProfileOutputSetting), + DUCKDB_LOCAL(ProfilingModeSetting), + DUCKDB_LOCAL_ALIAS("profiling_output", ProfileOutputSetting), + DUCKDB_LOCAL(ProgressBarTimeSetting), + DUCKDB_LOCAL(SchemaSetting), + DUCKDB_LOCAL(SearchPathSetting), + DUCKDB_GLOBAL(TempDirectorySetting), + DUCKDB_GLOBAL(ThreadsSetting), + DUCKDB_GLOBAL_ALIAS("wal_autocheckpoint", CheckpointThresholdSetting), + DUCKDB_GLOBAL_ALIAS("worker_threads", ThreadsSetting), + FINAL_SETTING}; vector DBConfig::GetOptions() { vector options; @@ -102048,8 +104156,10 @@ ConfigurationOption *DBConfig::GetOptionByIndex(idx_t target_index) { } ConfigurationOption *DBConfig::GetOptionByName(const string &name) { + auto lname = StringUtil::Lower(name); for (idx_t index = 0; internal_options[index].name; index++) { - if (internal_options[index].name == name) { + D_ASSERT(StringUtil::Lower(internal_options[index].name) == string(internal_options[index].name)); + if (internal_options[index].name == lname) { return internal_options + index; } } @@ -102057,69 +104167,21 @@ ConfigurationOption *DBConfig::GetOptionByName(const string &name) { } void DBConfig::SetOption(const ConfigurationOption &option, const Value &value) { - switch (option.type) { - case ConfigurationOptionType::ACCESS_MODE: { - auto parameter = StringUtil::Lower(value.ToString()); - if (parameter == "automatic") { - access_mode = AccessMode::AUTOMATIC; - } else if (parameter == "read_only") { - access_mode = AccessMode::READ_ONLY; - } else if (parameter == "read_write") { - access_mode = AccessMode::READ_WRITE; - } else { - throw InvalidInputException( - "Unrecognized parameter for option ACCESS_MODE \"%s\". Expected READ_ONLY or READ_WRITE.", parameter); - } - break; - } - case ConfigurationOptionType::DEFAULT_ORDER_TYPE: { - auto parameter = StringUtil::Lower(value.ToString()); - if (parameter == "asc") { - default_order_type = OrderType::ASCENDING; - } else if (parameter == "desc") { - default_order_type = OrderType::DESCENDING; - } else { - throw InvalidInputException("Unrecognized parameter for option DEFAULT_ORDER \"%s\". Expected ASC or DESC.", - parameter); - } - break; - } - case ConfigurationOptionType::DEFAULT_NULL_ORDER: { - auto parameter = StringUtil::Lower(value.ToString()); - if (parameter == "nulls_first") { - default_null_order = OrderByNullType::NULLS_FIRST; - } else if (parameter == "nulls_last") { - default_null_order = OrderByNullType::NULLS_LAST; - } else { - throw InvalidInputException( - "Unrecognized parameter for option NULL_ORDER \"%s\". Expected NULLS_FIRST or NULLS_LAST.", parameter); - } - break; - } - case ConfigurationOptionType::ENABLE_EXTERNAL_ACCESS: { - enable_external_access = value.CastAs(LogicalType::BOOLEAN).GetValueUnsafe(); - break; - } - case ConfigurationOptionType::ENABLE_OBJECT_CACHE: { - object_cache_enable = value.CastAs(LogicalType::BOOLEAN).GetValueUnsafe(); - break; - } - case ConfigurationOptionType::MAXIMUM_MEMORY: { - maximum_memory = ParseMemoryLimit(value.ToString()); - break; - } - case ConfigurationOptionType::THREADS: { - maximum_threads = value.GetValue(); - break; + if (!option.set_global) { + throw InternalException("Could not set option \"%s\" as a global option", option.name); } - default: // LCOV_EXCL_START - break; - } // LCOV_EXCL_STOP + Value input = value.CastAs(option.parameter_type); + option.set_global(nullptr, *this, input); +} + +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))); } idx_t DBConfig::ParseMemoryLimit(const string &arg) { if (arg[0] == '-' || arg == "null" || arg == "none") { - return INVALID_INDEX; + return DConstants::INVALID_INDEX; } // split based on the number/non-number idx_t idx = 0; @@ -102132,7 +104194,7 @@ idx_t DBConfig::ParseMemoryLimit(const string &arg) { idx++; } if (idx == num_start) { - throw ParserException("Memory limit must have a number (e.g. PRAGMA memory_limit=1GB"); + throw ParserException("Memory limit must have a number (e.g. SET memory_limit=1GB"); } string number = arg.substr(num_start, idx - num_start); @@ -102193,13 +104255,15 @@ class SelectStatement; class QueryRelation : public Relation { public: - QueryRelation(ClientContext &context, string query, string alias = "query_relation"); + QueryRelation(ClientContext &context, unique_ptr select_stmt, string alias); + ~QueryRelation(); - string query; + unique_ptr select_stmt; string alias; vector columns; public: + static unique_ptr ParseStatement(ClientContext &context, const string &query, const string &error); unique_ptr GetQueryNode() override; unique_ptr GetTableRef() override; @@ -102300,15 +104364,14 @@ namespace duckdb { class TableFunctionRelation : public Relation { public: TableFunctionRelation(ClientContext &context, string name, vector parameters, - unordered_map named_parameters, - shared_ptr input_relation_p = nullptr); + named_parameter_map_t named_parameters, shared_ptr input_relation_p = nullptr); TableFunctionRelation(ClientContext &context, string name, vector parameters, shared_ptr input_relation_p = nullptr); string name; vector parameters; - unordered_map named_parameters; + named_parameter_map_t named_parameters; vector columns; shared_ptr input_relation; @@ -102465,10 +104528,11 @@ Connection::Connection(DuckDB &database) : Connection(*database.instance) { } string Connection::GetProfilingInformation(ProfilerPrintFormat format) { + auto &profiler = QueryProfiler::Get(*context); if (format == ProfilerPrintFormat::JSON) { - return context->profiler->ToJSON(); + return profiler.ToJSON(); } else { - return context->profiler->ToString(); + return profiler.ToString(); } } @@ -102485,15 +104549,15 @@ void Connection::DisableProfiling() { } void Connection::EnableQueryVerification() { - context->query_verification_enabled = true; + ClientConfig::GetConfig(*context).query_verification_enabled = true; } void Connection::DisableQueryVerification() { - context->query_verification_enabled = false; + ClientConfig::GetConfig(*context).query_verification_enabled = false; } void Connection::ForceParallelism() { - context->verify_parallelism = true; + ClientConfig::GetConfig(*context).verify_parallelism = true; } unique_ptr Connection::SendQuery(const string &query) { @@ -102512,6 +104576,14 @@ unique_ptr Connection::Query(unique_ptr s return unique_ptr_cast(move(result)); } +unique_ptr Connection::PendingQuery(const string &query) { + return context->PendingQuery(query); +} + +unique_ptr Connection::PendingQuery(unique_ptr statement) { + return context->PendingQuery(move(statement)); +} + unique_ptr Connection::Prepare(const string &query) { return context->Prepare(query); } @@ -102576,12 +104648,12 @@ shared_ptr Connection::View(const string &schema_name, const string &t shared_ptr Connection::TableFunction(const string &fname) { vector values; - unordered_map named_parameters; + named_parameter_map_t named_parameters; return TableFunction(fname, values, named_parameters); } shared_ptr Connection::TableFunction(const string &fname, const vector &values, - const unordered_map &named_parameters) { + const named_parameter_map_t &named_parameters) { return make_shared(*context, fname, values, named_parameters); } @@ -102624,7 +104696,7 @@ shared_ptr Connection::ReadCSV(const string &csv_file, const vector column_list; for (auto &column : columns) { - auto col_list = Parser::ParseColumnList(column); + auto col_list = Parser::ParseColumnList(column, context->GetParserOptions()); if (col_list.size() != 1) { throw ParserException("Expected a single column definition"); } @@ -102633,8 +104705,16 @@ shared_ptr Connection::ReadCSV(const string &csv_file, const vector(*context, csv_file, move(column_list)); } -shared_ptr Connection::RelationFromQuery(const string &query, const string &alias) { - return make_shared(*context, query, alias); +unordered_set Connection::GetTableNames(const string &query) { + return context->GetTableNames(query); +} + +shared_ptr Connection::RelationFromQuery(const string &query, string alias, const string &error) { + return RelationFromQuery(QueryRelation::ParseStatement(*context, query, error), move(alias)); +} + +shared_ptr Connection::RelationFromQuery(unique_ptr select_stmt, string alias) { + return make_shared(*context, move(select_stmt), move(alias)); } void Connection::BeginTransaction() { @@ -102699,11 +104779,13 @@ class ObjectCacheEntry { public: virtual ~ObjectCacheEntry() { } + + virtual string GetObjectType() = 0; }; class ObjectCache { public: - shared_ptr Get(string key) { + shared_ptr GetObject(const string &key) { lock_guard glock(lock); auto entry = cache.find(key); if (entry == cache.end()) { @@ -102712,6 +104794,15 @@ class ObjectCache { return entry->second; } + template + shared_ptr Get(const string &key) { + shared_ptr object = GetObject(key); + if (!object || object->GetObjectType() != T::ObjectType()) { + return nullptr; + } + return std::static_pointer_cast(object); + } + void Put(string key, shared_ptr value) { lock_guard glock(lock); cache[key] = move(value); @@ -102731,32 +104822,6 @@ class ObjectCache { -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/extension_helper.hpp -// -// -//===----------------------------------------------------------------------===// - - - -#include - - -namespace duckdb { -class DuckDB; - -enum class ExtensionLoadResult : uint8_t { LOADED_EXTENSION = 0, EXTENSION_UNKNOWN = 1, NOT_LOADED = 2 }; - -class ExtensionHelper { -public: - static void LoadAllExtensions(DuckDB &db); - - static ExtensionLoadResult LoadExtension(DuckDB &db, const std::string &extension); -}; - -} // namespace duckdb #ifndef DUCKDB_NO_THREADS @@ -102776,7 +104841,7 @@ DatabaseInstance::DatabaseInstance() { } DatabaseInstance::~DatabaseInstance() { - if (std::uncaught_exception()) { + if (Exception::UncaughtException()) { return; } @@ -102827,6 +104892,10 @@ DBConfig &DBConfig::GetConfig(DatabaseInstance &db) { return db.config; } +ClientConfig &ClientConfig::GetConfig(ClientContext &context) { + return context.config; +} + TransactionManager &TransactionManager::Get(ClientContext &context) { return TransactionManager::Get(DatabaseInstance::GetDatabase(context)); } @@ -102891,6 +104960,9 @@ DuckDB::DuckDB(const char *path, DBConfig *new_config) : instance(make_sharedNumberOfThreads(); } +bool DuckDB::ExtensionIsLoaded(const std::string &name) { + return instance->loaded_extensions.find(name) != instance->loaded_extensions.end(); +} +void DuckDB::SetExtensionLoaded(const std::string &name) { + instance->loaded_extensions.insert(name); +} + } // namespace duckdb + + + + + #ifdef BUILD_ICU_EXTENSION #include "icu-extension.hpp" #endif @@ -103020,11 +105104,35 @@ namespace duckdb { void ExtensionHelper::LoadAllExtensions(DuckDB &db) { unordered_set extensions {"parquet", "icu", "tpch", "tpcds", "fts", "httpfs", "visualizer"}; for (auto &ext : extensions) { - LoadExtension(db, ext); + LoadExtensionInternal(db, ext, true); } } +//===--------------------------------------------------------------------===// +// Load Statically Compiled Extension +//===--------------------------------------------------------------------===// ExtensionLoadResult ExtensionHelper::LoadExtension(DuckDB &db, const std::string &extension) { + return LoadExtensionInternal(db, extension, false); +} + +ExtensionLoadResult ExtensionHelper::LoadExtensionInternal(DuckDB &db, const std::string &extension, + bool initial_load) { +#ifdef DUCKDB_TEST_REMOTE_INSTALL + if (!initial_load && StringUtil::Contains(DUCKDB_TEST_REMOTE_INSTALL, extension)) { + Connection con(db); + auto result = con.Query("INSTALL " + extension); + if (!result->success) { + result->Print(); + return ExtensionLoadResult::EXTENSION_UNKNOWN; + } + result = con.Query("LOAD " + extension); + if (!result->success) { + result->Print(); + return ExtensionLoadResult::EXTENSION_UNKNOWN; + } + return ExtensionLoadResult::LOADED_EXTENSION; + } +#endif if (extension == "parquet") { #ifdef BUILD_PARQUET_EXTENSION db.LoadExtension(); @@ -103084,4413 +105192,7557 @@ ExtensionLoadResult ExtensionHelper::LoadExtension(DuckDB &db, const std::string -namespace duckdb { +#ifndef DISABLE_DUCKDB_REMOTE_INSTALL -MaterializedQueryResult::MaterializedQueryResult(StatementType statement_type) - : QueryResult(QueryResultType::MATERIALIZED_RESULT, statement_type) { -} -MaterializedQueryResult::MaterializedQueryResult(StatementType statement_type, vector types, - vector names) - : QueryResult(QueryResultType::MATERIALIZED_RESULT, statement_type, move(types), move(names)) { -} +// LICENSE_CHANGE_BEGIN +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #7 +// See the end of this file for a list -MaterializedQueryResult::MaterializedQueryResult(string error) - : QueryResult(QueryResultType::MATERIALIZED_RESULT, move(error)) { -} +// +// httplib.hpp +// +// Copyright (c) 2020 Yuji Hirose. All rights reserved. +// MIT License +// -Value MaterializedQueryResult::GetValue(idx_t column, idx_t index) { - auto &data = collection.GetChunkForRow(index).data[column]; - auto offset_in_chunk = index % STANDARD_VECTOR_SIZE; - return data.GetValue(offset_in_chunk); -} +#ifndef CPPHTTPLIB_HTTPLIB_H +#define CPPHTTPLIB_HTTPLIB_H -string MaterializedQueryResult::ToString() { - string result; - if (success) { - result = HeaderToString(); - result += "[ Rows: " + to_string(collection.Count()) + "]\n"; - for (idx_t j = 0; j < collection.Count(); j++) { - for (idx_t i = 0; i < collection.ColumnCount(); i++) { - auto val = collection.GetValue(i, j); - result += val.is_null ? "NULL" : val.ToString(); - result += "\t"; - } - result += "\n"; - } - result += "\n"; - } else { - result = error + "\n"; - } - return result; -} +/* + * Configuration + */ +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +#define CPPHTTPLIB_NAMESPACE duckdb_httplib_openssl +#else +#define CPPHTTPLIB_NAMESPACE duckdb_httplib +#endif -unique_ptr MaterializedQueryResult::Fetch() { - return FetchRaw(); -} +#ifndef CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND +#define CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND 5 +#endif -unique_ptr MaterializedQueryResult::FetchRaw() { - if (!success) { - throw InvalidInputException("Attempting to fetch from an unsuccessful query result\nError: %s", error); - } - return collection.Fetch(); -} +#ifndef CPPHTTPLIB_KEEPALIVE_MAX_COUNT +#define CPPHTTPLIB_KEEPALIVE_MAX_COUNT 5 +#endif -} // namespace duckdb +#ifndef CPPHTTPLIB_CONNECTION_TIMEOUT_SECOND +#define CPPHTTPLIB_CONNECTION_TIMEOUT_SECOND 300 +#endif +#ifndef CPPHTTPLIB_CONNECTION_TIMEOUT_USECOND +#define CPPHTTPLIB_CONNECTION_TIMEOUT_USECOND 0 +#endif +#ifndef CPPHTTPLIB_READ_TIMEOUT_SECOND +#define CPPHTTPLIB_READ_TIMEOUT_SECOND 5 +#endif +#ifndef CPPHTTPLIB_READ_TIMEOUT_USECOND +#define CPPHTTPLIB_READ_TIMEOUT_USECOND 0 +#endif +#ifndef CPPHTTPLIB_WRITE_TIMEOUT_SECOND +#define CPPHTTPLIB_WRITE_TIMEOUT_SECOND 5 +#endif -namespace duckdb { +#ifndef CPPHTTPLIB_WRITE_TIMEOUT_USECOND +#define CPPHTTPLIB_WRITE_TIMEOUT_USECOND 0 +#endif -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) { - D_ASSERT(data || !success); -} +#ifndef CPPHTTPLIB_IDLE_INTERVAL_SECOND +#define CPPHTTPLIB_IDLE_INTERVAL_SECOND 0 +#endif -PreparedStatement::PreparedStatement(string error) : context(nullptr), success(false), error(move(error)) { -} +#ifndef CPPHTTPLIB_IDLE_INTERVAL_USECOND +#ifdef _WIN32 +#define CPPHTTPLIB_IDLE_INTERVAL_USECOND 10000 +#else +#define CPPHTTPLIB_IDLE_INTERVAL_USECOND 0 +#endif +#endif -PreparedStatement::~PreparedStatement() { -} +#ifndef CPPHTTPLIB_REQUEST_URI_MAX_LENGTH +#define CPPHTTPLIB_REQUEST_URI_MAX_LENGTH 8192 +#endif -idx_t PreparedStatement::ColumnCount() { - D_ASSERT(data); - return data->types.size(); -} +#ifndef CPPHTTPLIB_REDIRECT_MAX_COUNT +#define CPPHTTPLIB_REDIRECT_MAX_COUNT 20 +#endif -StatementType PreparedStatement::GetStatementType() { - D_ASSERT(data); - return data->statement_type; -} +#ifndef CPPHTTPLIB_PAYLOAD_MAX_LENGTH +#define CPPHTTPLIB_PAYLOAD_MAX_LENGTH ((std::numeric_limits::max)()) +#endif -const vector &PreparedStatement::GetTypes() { - D_ASSERT(data); - return data->types; -} +#ifndef CPPHTTPLIB_TCP_NODELAY +#define CPPHTTPLIB_TCP_NODELAY false +#endif -const vector &PreparedStatement::GetNames() { - D_ASSERT(data); - return data->names; -} +#ifndef CPPHTTPLIB_RECV_BUFSIZ +#define CPPHTTPLIB_RECV_BUFSIZ size_t(4096u) +#endif -unique_ptr PreparedStatement::Execute(vector &values, bool allow_stream_result) { - if (!success) { - throw InvalidInputException("Attempting to execute an unsuccessfully prepared statement!"); - } - D_ASSERT(data); - auto result = context->Execute(query, data, values, allow_stream_result && data->allow_stream_result); - return result; -} +#ifndef CPPHTTPLIB_COMPRESSION_BUFSIZ +#define CPPHTTPLIB_COMPRESSION_BUFSIZ size_t(16384u) +#endif -} // namespace duckdb +#ifndef CPPHTTPLIB_THREAD_POOL_COUNT +#define CPPHTTPLIB_THREAD_POOL_COUNT \ + ((std::max)(8u, std::thread::hardware_concurrency() > 0 \ + ? std::thread::hardware_concurrency() - 1 \ + : 0)) +#endif +#ifndef CPPHTTPLIB_RECV_FLAGS +#define CPPHTTPLIB_RECV_FLAGS 0 +#endif +#ifndef CPPHTTPLIB_SEND_FLAGS +#define CPPHTTPLIB_SEND_FLAGS 0 +#endif +/* + * Headers + */ -namespace duckdb { +#ifdef _WIN32 +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif //_CRT_SECURE_NO_WARNINGS -PreparedStatementData::PreparedStatementData(StatementType type) - : statement_type(type), read_only(true), requires_valid_transaction(true), allow_stream_result(false) { -} +#ifndef _CRT_NONSTDC_NO_DEPRECATE +#define _CRT_NONSTDC_NO_DEPRECATE +#endif //_CRT_NONSTDC_NO_DEPRECATE -PreparedStatementData::~PreparedStatementData() { -} +#if defined(_MSC_VER) +#ifdef _WIN64 +using ssize_t = __int64; +#else +using ssize_t = int; +#endif -void PreparedStatementData::Bind(vector values) { - // set parameters - if (values.size() != value_map.size()) { - throw BinderException("Parameter/argument count mismatch for prepared statement. Expected %llu, got %llu", - value_map.size(), values.size()); - } - // bind the values - for (idx_t i = 0; i < values.size(); i++) { - auto it = value_map.find(i + 1); - if (it == value_map.end()) { - throw BinderException("Could not find parameter with index %llu", i + 1); - } - D_ASSERT(!it->second.empty()); - if (!values[i].TryCastAs(it->second[0]->type())) { - throw BinderException( - "Type mismatch for binding parameter with index %llu, expected type %s but got type %s", i + 1, - it->second[0]->type().ToString().c_str(), values[i].type().ToString().c_str()); - } - for (auto &target : it->second) { - *target = values[i]; - } - } -} +#if _MSC_VER < 1900 +#define snprintf _snprintf_s +#endif +#endif // _MSC_VER -LogicalType PreparedStatementData::GetType(idx_t param_idx) { - auto it = value_map.find(param_idx); - if (it == value_map.end()) { - throw BinderException("Could not find parameter with index %llu", param_idx); - } - D_ASSERT(!it->second.empty()); - return it->second[0]->type(); -} +#ifndef S_ISREG +#define S_ISREG(m) (((m)&S_IFREG) == S_IFREG) +#endif // S_ISREG -} // namespace duckdb +#ifndef S_ISDIR +#define S_ISDIR(m) (((m)&S_IFDIR) == S_IFDIR) +#endif // S_ISDIR +#ifndef NOMINMAX +#define NOMINMAX +#endif // NOMINMAX -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/fstream.hpp -// -// -//===----------------------------------------------------------------------===// +#include +#ifdef _WINSOCKAPI_ +#undef _WINSOCKAPI_ +#endif +#include +#include +#include +#ifndef WSA_FLAG_NO_HANDLE_INHERIT +#define WSA_FLAG_NO_HANDLE_INHERIT 0x80 +#endif -#include -#include +#ifdef _MSC_VER +#pragma comment(lib, "ws2_32.lib") +#pragma comment(lib, "crypt32.lib") +#pragma comment(lib, "cryptui.lib") +#endif -namespace duckdb { -using std::endl; -using std::fstream; -using std::ifstream; -using std::ios; -using std::ios_base; -using std::ofstream; -} // namespace duckdb +#ifndef strcasecmp +#define strcasecmp _stricmp +#endif // strcasecmp +using socket_t = SOCKET; +#ifdef CPPHTTPLIB_USE_POLL +#define poll(fds, nfds, timeout) WSAPoll(fds, nfds, timeout) +#endif +#else // not _WIN32 +#include +#include +#include +#include +#include +#ifdef __linux__ +#include +#endif +#include +#ifdef CPPHTTPLIB_USE_POLL +#include +#endif +#include +#include +#include +#include +#include +using socket_t = int; +#define INVALID_SOCKET (-1) +#endif //_WIN32 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +#include +#include +#include +#include +#if defined(_WIN32) && defined(OPENSSL_USE_APPLINK) +#include +#endif +#include +#include +#if OPENSSL_VERSION_NUMBER < 0x10100000L +#include +inline const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *asn1) { + return M_ASN1_STRING_data(asn1); +} +#endif +#endif -#include -#include +#ifdef CPPHTTPLIB_ZLIB_SUPPORT +#include +#endif -namespace duckdb { +#ifdef CPPHTTPLIB_BROTLI_SUPPORT +#include +#include +#endif -void QueryProfiler::StartQuery(string query) { - if (!enabled) { - return; - } - this->running = true; - this->query = move(query); - tree_map.clear(); - root = nullptr; - phase_timings.clear(); - phase_stack.clear(); +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wexit-time-destructors" +#endif - main_query.Start(); -} +/* + * Declaration + */ +namespace CPPHTTPLIB_NAMESPACE { -bool QueryProfiler::OperatorRequiresProfiling(PhysicalOperatorType op_type) { - switch (op_type) { - case PhysicalOperatorType::ORDER_BY: - case PhysicalOperatorType::RESERVOIR_SAMPLE: - case PhysicalOperatorType::STREAMING_SAMPLE: - case PhysicalOperatorType::LIMIT: - case PhysicalOperatorType::TOP_N: - case PhysicalOperatorType::WINDOW: - case PhysicalOperatorType::UNNEST: - case PhysicalOperatorType::SIMPLE_AGGREGATE: - case PhysicalOperatorType::HASH_GROUP_BY: - case PhysicalOperatorType::FILTER: - case PhysicalOperatorType::PROJECTION: - case PhysicalOperatorType::COPY_TO_FILE: - case PhysicalOperatorType::TABLE_SCAN: - case PhysicalOperatorType::CHUNK_SCAN: - case PhysicalOperatorType::DELIM_SCAN: - case PhysicalOperatorType::EXPRESSION_SCAN: - case PhysicalOperatorType::BLOCKWISE_NL_JOIN: - case PhysicalOperatorType::NESTED_LOOP_JOIN: - case PhysicalOperatorType::HASH_JOIN: - case PhysicalOperatorType::CROSS_PRODUCT: - case PhysicalOperatorType::PIECEWISE_MERGE_JOIN: - case PhysicalOperatorType::DELIM_JOIN: - case PhysicalOperatorType::UNION: - case PhysicalOperatorType::RECURSIVE_CTE: - case PhysicalOperatorType::EMPTY_RESULT: - return true; - default: - return false; - } -} +namespace detail { -void QueryProfiler::Finalize(TreeNode &node) { - for (auto &child : node.children) { - Finalize(*child); - if (node.type == PhysicalOperatorType::UNION) { - node.info.elements += child->info.elements; - } - } -} +/* + * Backport std::make_unique from C++14. + * + * NOTE: This code came up with the following stackoverflow post: + * https://stackoverflow.com/questions/10149840/c-arrays-and-make-unique + * + */ -void QueryProfiler::EndQuery() { - if (!enabled || !running) { - return; - } +template +typename std::enable_if::value, std::unique_ptr>::type +make_unique(Args &&... args) { + return std::unique_ptr(new T(std::forward(args)...)); +} - main_query.End(); - if (root) { - Finalize(*root); - } - this->running = false; - // print or output the query profiling after termination, if this is enabled - if (automatic_print_format != ProfilerPrintFormat::NONE) { - // check if this query should be output based on the operator types - string query_info; - if (automatic_print_format == ProfilerPrintFormat::JSON) { - query_info = ToJSON(); - } else if (automatic_print_format == ProfilerPrintFormat::QUERY_TREE) { - query_info = ToString(); - } else if (automatic_print_format == ProfilerPrintFormat::QUERY_TREE_OPTIMIZER) { - query_info = ToString(true); - } +template +typename std::enable_if::value, std::unique_ptr>::type +make_unique(std::size_t n) { + typedef typename std::remove_extent::type RT; + return std::unique_ptr(new RT[n]); +} + +struct ci { + bool operator()(const std::string &s1, const std::string &s2) const { + return std::lexicographical_compare(s1.begin(), s1.end(), s2.begin(), + s2.end(), + [](unsigned char c1, unsigned char c2) { + return ::tolower(c1) < ::tolower(c2); + }); + } +}; - if (save_location.empty()) { - Printer::Print(query_info); - Printer::Print("\n"); - } else { - WriteToFile(save_location.c_str(), query_info); - } - } -} +} // namespace detail -void QueryProfiler::StartPhase(string new_phase) { - if (!enabled || !running) { - return; - } +using Headers = std::multimap; - if (!phase_stack.empty()) { - // there are active phases - phase_profiler.End(); - // add the timing to all phases prior to this one - string prefix = ""; - for (auto &phase : phase_stack) { - phase_timings[phase] += phase_profiler.Elapsed(); - prefix += phase + " > "; - } - // when there are previous phases, we prefix the current phase with those phases - new_phase = prefix + new_phase; - } +using Params = std::multimap; +using Match = std::smatch; - // start a new phase - phase_stack.push_back(new_phase); - // restart the timer - phase_profiler.Start(); -} +using Progress = std::function; -void QueryProfiler::EndPhase() { - if (!enabled || !running) { - return; - } - D_ASSERT(phase_stack.size() > 0); +struct Response; +using ResponseHandler = std::function; - // end the timer - phase_profiler.End(); - // add the timing to all currently active phases - for (auto &phase : phase_stack) { - phase_timings[phase] += phase_profiler.Elapsed(); - } - // now remove the last added phase - phase_stack.pop_back(); +struct MultipartFormData { + std::string name; + std::string content; + std::string filename; + std::string content_type; +}; +using MultipartFormDataItems = std::vector; +using MultipartFormDataMap = std::multimap; - if (!phase_stack.empty()) { - phase_profiler.Start(); - } -} +class DataSink { +public: + DataSink() : os(&sb_), sb_(*this) {} -void QueryProfiler::Initialize(PhysicalOperator *root_op) { - if (!enabled || !running) { - return; - } - this->query_requires_profiling = false; - this->root = CreateTree(root_op); - if (!query_requires_profiling) { - // query does not require profiling: disable profiling for this query - this->running = false; - tree_map.clear(); - root = nullptr; - phase_timings.clear(); - phase_stack.clear(); - } -} + DataSink(const DataSink &) = delete; + DataSink &operator=(const DataSink &) = delete; + DataSink(DataSink &&) = delete; + DataSink &operator=(DataSink &&) = delete; -OperatorProfiler::OperatorProfiler(bool enabled_p) : enabled(enabled_p), active_operator(nullptr) { -} + std::function write; + std::function done; + std::function is_writable; + std::ostream os; -void OperatorProfiler::StartOperator(const PhysicalOperator *phys_op) { - if (!enabled) { - return; - } +private: + class data_sink_streambuf : public std::streambuf { + public: + explicit data_sink_streambuf(DataSink &sink) : sink_(sink) {} - if (active_operator) { - throw InternalException("OperatorProfiler: Attempting to call StartOperator while another operator is active"); - } + protected: + std::streamsize xsputn(const char *s, std::streamsize n) { + sink_.write(s, static_cast(n)); + return n; + } - active_operator = phys_op; + private: + DataSink &sink_; + }; - // start timing for current element - op.Start(); -} + data_sink_streambuf sb_; +}; -void OperatorProfiler::EndOperator(DataChunk *chunk) { - if (!enabled) { - return; - } +using ContentProvider = + std::function; - if (!active_operator) { - throw InternalException("OperatorProfiler: Attempting to call EndOperator while another operator is active"); - } +using ContentProviderWithoutLength = + std::function; - // finish timing for the current element - op.End(); +using ContentReceiverWithProgress = + std::function; - AddTiming(active_operator, op.Elapsed(), chunk ? chunk->size() : 0); - active_operator = nullptr; -} +using ContentReceiver = + std::function; -void OperatorProfiler::AddTiming(const PhysicalOperator *op, double time, idx_t elements) { - if (!enabled) { - return; - } - if (!Value::DoubleIsValid(time)) { - return; - } - auto entry = timings.find(op); - if (entry == timings.end()) { - // add new entry - timings[op] = OperatorInformation(time, elements); - } else { - // add to existing entry - entry->second.time += time; - entry->second.elements += elements; - } -} -void OperatorProfiler::Flush(const PhysicalOperator *phys_op, ExpressionExecutor *expression_executor, - const string &name, int id) { - auto entry = timings.find(phys_op); - if (entry == timings.end()) { - return; - } - auto &operator_timing = timings.find(phys_op)->second; - if (int(operator_timing.executors_info.size()) <= id) { - operator_timing.executors_info.resize(id + 1); - } - operator_timing.executors_info[id] = make_unique(*expression_executor, name, id); - operator_timing.name = phys_op->GetName(); -} +using MultipartContentHeader = + std::function; -void QueryProfiler::Flush(OperatorProfiler &profiler) { - if (!enabled || !running) { - return; - } - lock_guard guard(flush_lock); - for (auto &node : profiler.timings) { - auto entry = tree_map.find(node.first); - D_ASSERT(entry != tree_map.end()); +class ContentReader { +public: + using Reader = std::function; + using MultipartReader = std::function; - entry->second->info.time += node.second.time; - entry->second->info.elements += node.second.elements; - if (!detailed_enabled) { - continue; - } - for (auto &info : node.second.executors_info) { - if (!info) { - continue; - } - auto info_id = info->id; - 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); - } - } - profiler.timings.clear(); -} + ContentReader(Reader reader, MultipartReader multipart_reader) + : reader_(std::move(reader)), + multipart_reader_(std::move(multipart_reader)) {} -static string DrawPadded(const string &str, idx_t width) { - if (str.size() > width) { - return str.substr(0, width); - } else { - width -= str.size(); - int half_spaces = width / 2; - int extra_left_space = width % 2 != 0 ? 1 : 0; - return string(half_spaces + extra_left_space, ' ') + str + string(half_spaces, ' '); - } -} + bool operator()(MultipartContentHeader header, + ContentReceiver receiver) const { + return multipart_reader_(std::move(header), std::move(receiver)); + } -static string RenderTitleCase(string str) { - str = StringUtil::Lower(str); - str[0] = toupper(str[0]); - for (idx_t i = 0; i < str.size(); i++) { - if (str[i] == '_') { - str[i] = ' '; - if (i + 1 < str.size()) { - str[i + 1] = toupper(str[i + 1]); - } - } - } - return str; -} + bool operator()(ContentReceiver receiver) const { + return reader_(std::move(receiver)); + } -static string RenderTiming(double timing) { - string timing_s; - if (timing >= 1) { - timing_s = StringUtil::Format("%.2f", timing); - } else if (timing >= 0.1) { - timing_s = StringUtil::Format("%.3f", timing); - } else { - timing_s = StringUtil::Format("%.4f", timing); - } - return timing_s + "s"; -} + Reader reader_; + MultipartReader multipart_reader_; +}; -string QueryProfiler::ToString(bool print_optimizer_output) const { - std::stringstream str; - ToStream(str, print_optimizer_output); - return str.str(); -} +using Range = std::pair; +using Ranges = std::vector; -void QueryProfiler::ToStream(std::ostream &ss, bool print_optimizer_output) const { - if (!enabled) { - ss << "Query profiling is disabled. Call " - "Connection::EnableProfiling() to enable profiling!"; - return; - } - ss << "┌─────────────────────────────────────┐\n"; - ss << "│┌───────────────────────────────────┐│\n"; - ss << "││ Query Profiling Information ││\n"; - ss << "│└───────────────────────────────────┘│\n"; - ss << "└─────────────────────────────────────┘\n"; - ss << StringUtil::Replace(query, "\n", " ") + "\n"; - if (query.empty()) { - return; - } +struct Request { + std::string method; + std::string path; + Headers headers; + std::string body; - constexpr idx_t TOTAL_BOX_WIDTH = 39; - ss << "┌─────────────────────────────────────┐\n"; - ss << "│┌───────────────────────────────────┐│\n"; - string total_time = "Total Time: " + RenderTiming(main_query.Elapsed()); - ss << "││" + DrawPadded(total_time, TOTAL_BOX_WIDTH - 4) + "││\n"; - ss << "│└───────────────────────────────────┘│\n"; - ss << "└─────────────────────────────────────┘\n"; - // print phase timings - if (print_optimizer_output) { - bool has_previous_phase = false; - for (const auto &entry : GetOrderedPhaseTimings()) { - if (!StringUtil::Contains(entry.first, " > ")) { - // primary phase! - if (has_previous_phase) { - ss << "│└───────────────────────────────────┘│\n"; - ss << "└─────────────────────────────────────┘\n"; - } - ss << "┌─────────────────────────────────────┐\n"; - ss << "│" + - DrawPadded(RenderTitleCase(entry.first) + ": " + RenderTiming(entry.second), - TOTAL_BOX_WIDTH - 2) + - "│\n"; - ss << "│┌───────────────────────────────────┐│\n"; - has_previous_phase = true; - } else { - string entry_name = StringUtil::Split(entry.first, " > ")[1]; - ss << "││" + - DrawPadded(RenderTitleCase(entry_name) + ": " + RenderTiming(entry.second), - TOTAL_BOX_WIDTH - 4) + - "││\n"; - } - } - if (has_previous_phase) { - ss << "│└───────────────────────────────────┘│\n"; - ss << "└─────────────────────────────────────┘\n"; - } - } - // render the main operator tree - if (root) { - Render(*root, ss); - } -} + std::string remote_addr; + int remote_port = -1; -static string JSONSanitize(const string &text) { - string result; - result.reserve(text.size()); - for (idx_t i = 0; i < text.size(); i++) { - switch (text[i]) { - case '\b': - result += "\\b"; - break; - case '\f': - result += "\\f"; - break; - case '\n': - result += "\\n"; - break; - case '\r': - result += "\\r"; - break; - case '\t': - result += "\\t"; - break; - case '"': - result += "\\\""; - break; - case '\\': - result += "\\\\"; - break; - default: - result += text[i]; - break; - } - } - return result; -} + // for server + std::string version; + std::string target; + Params params; + MultipartFormDataMap files; + Ranges ranges; + Match matches; -// Print a row -static void PrintRow(std::ostream &ss, const string &annotation, int id, const string &name, double time, - int sample_counter, int tuple_counter, const string &extra_info, int depth) { - ss << string(depth * 3, ' ') << " {\n"; - ss << string(depth * 3, ' ') << " \"annotation\": \"" + JSONSanitize(annotation) + "\",\n"; - ss << string(depth * 3, ' ') << " \"id\": " + to_string(id) + ",\n"; - ss << string(depth * 3, ' ') << " \"name\": \"" + JSONSanitize(name) + "\",\n"; -#if defined(RDTSC) - ss << string(depth * 3, ' ') << " \"timing\": \"NULL\" ,\n"; - ss << string(depth * 3, ' ') << " \"cycles_per_tuple\": " + StringUtil::Format("%.4f", time) + ",\n"; -#else - ss << string(depth * 3, ' ') << " \"timing\":" + to_string(time) + ",\n"; - ss << string(depth * 3, ' ') << " \"cycles_per_tuple\": \"NULL\" ,\n"; + // for client +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + const SSL *ssl; #endif - ss << string(depth * 3, ' ') << " \"sample_size\": " << to_string(sample_counter) + ",\n"; - ss << string(depth * 3, ' ') << " \"input_size\": " << to_string(tuple_counter) + ",\n"; - ss << string(depth * 3, ' ') << " \"extra_info\": \"" << JSONSanitize(extra_info) + "\"\n"; - ss << string(depth * 3, ' ') << " },\n"; -} -static void ExtractFunctions(std::ostream &ss, ExpressionInfo &info, int &fun_id, int depth) { - if (info.hasfunction) { - D_ASSERT(info.sample_tuples_count != 0); - PrintRow(ss, "Function", fun_id++, info.function_name, - int(info.function_time) / double(info.sample_tuples_count), info.sample_tuples_count, - info.tuples_count, "", depth); - } - if (info.children.empty()) { - return; - } - // extract the children of this node - for (auto &child : info.children) { - ExtractFunctions(ss, *child, fun_id, depth); - } -} + bool has_header(const char *key) const; + std::string get_header_value(const char *key, size_t id = 0) const; + template + T get_header_value(const char *key, size_t id = 0) const; + size_t get_header_value_count(const char *key) const; + void set_header(const char *key, const char *val); + void set_header(const char *key, const std::string &val); + + bool has_param(const char *key) const; + std::string get_param_value(const char *key, size_t id = 0) const; + size_t get_param_value_count(const char *key) const; + + bool is_multipart_form_data() const; + + bool has_file(const char *key) const; + MultipartFormData get_file_value(const char *key) const; + + // private members... + size_t redirect_count_ = CPPHTTPLIB_REDIRECT_MAX_COUNT; + ResponseHandler response_handler_; + ContentReceiverWithProgress content_receiver_; + size_t content_length_ = 0; + ContentProvider content_provider_; + bool is_chunked_content_provider_ = false; + Progress progress_; + size_t authorization_count_ = 0; +}; + +struct Response { + std::string version; + int status = -1; + std::string reason; + Headers headers; + std::string body; + std::string location; // Redirect location + + bool has_header(const char *key) const; + std::string get_header_value(const char *key, size_t id = 0) const; + template + T get_header_value(const char *key, size_t id = 0) const; + size_t get_header_value_count(const char *key) const; + void set_header(const char *key, const char *val); + void set_header(const char *key, const std::string &val); + + void set_redirect(const char *url, int status = 302); + void set_redirect(const std::string &url, int status = 302); + void set_content(const char *s, size_t n, const char *content_type); + void set_content(const std::string &s, const char *content_type); + + void set_content_provider( + size_t length, const char *content_type, ContentProvider provider, + const std::function &resource_releaser = nullptr); + + void set_content_provider( + const char *content_type, ContentProviderWithoutLength provider, + const std::function &resource_releaser = nullptr); + + void set_chunked_content_provider( + const char *content_type, ContentProviderWithoutLength provider, + const std::function &resource_releaser = nullptr); + + Response() = default; + Response(const Response &) = default; + Response &operator=(const Response &) = default; + Response(Response &&) = default; + Response &operator=(Response &&) = default; + ~Response() { + if (content_provider_resource_releaser_) { + content_provider_resource_releaser_(); + } + } -static void ToJSONRecursive(QueryProfiler::TreeNode &node, std::ostream &ss, int depth = 1) { - ss << string(depth * 3, ' ') << " {\n"; - ss << string(depth * 3, ' ') << " \"name\": \"" + JSONSanitize(node.name) + "\",\n"; - ss << string(depth * 3, ' ') << " \"timing\":" + to_string(node.info.time) + ",\n"; - ss << string(depth * 3, ' ') << " \"cardinality\":" + to_string(node.info.elements) + ",\n"; - ss << string(depth * 3, ' ') << " \"extra_info\": \"" + JSONSanitize(node.extra_info) + "\",\n"; - ss << string(depth * 3, ' ') << " \"timings\": ["; - int32_t function_counter = 1; - int32_t expression_counter = 1; - ss << "\n "; - for (auto &expr_executor : node.info.executors_info) { - // For each Expression tree - if (!expr_executor) { - continue; - } - for (auto &expr_timer : expr_executor->roots) { - D_ASSERT(expr_timer->sample_tuples_count != 0); - PrintRow(ss, "ExpressionRoot", expression_counter++, expr_timer->name, - int(expr_timer->time) / double(expr_timer->sample_tuples_count), expr_timer->sample_tuples_count, - expr_timer->tuples_count, expr_timer->extra_info, depth + 1); - // Extract all functions inside the tree - ExtractFunctions(ss, *expr_timer->root, function_counter, depth + 1); - } - } - ss.seekp(-2, ss.cur); - ss << "\n"; - ss << string(depth * 3, ' ') << " ],\n"; - ss << string(depth * 3, ' ') << " \"children\": [\n"; - if (node.children.empty()) { - ss << string(depth * 3, ' ') << " ]\n"; - } else { - for (idx_t i = 0; i < node.children.size(); i++) { - if (i > 0) { - ss << ",\n"; - } - ToJSONRecursive(*node.children[i], ss, depth + 1); - } - ss << string(depth * 3, ' ') << " ]\n"; - } - ss << string(depth * 3, ' ') << " }\n"; -} + // private members... + size_t content_length_ = 0; + ContentProvider content_provider_; + std::function content_provider_resource_releaser_; + bool is_chunked_content_provider_ = false; +}; -string QueryProfiler::ToJSON() const { - if (!enabled) { - return "{ \"result\": \"disabled\" }\n"; - } - if (query.empty()) { - return "{ \"result\": \"empty\" }\n"; - } - if (!root) { - return "{ \"result\": \"error\" }\n"; - } - std::stringstream ss; - ss << "{\n"; - ss << " \"name\": \"Query\", \n"; - ss << " \"result\": " + to_string(main_query.Elapsed()) + ",\n"; - ss << " \"timing\": " + to_string(main_query.Elapsed()) + ",\n"; - ss << " \"cardinality\": " + to_string(root->info.elements) + ",\n"; - // JSON cannot have literal control characters in string literals - string extra_info = JSONSanitize(query); - ss << " \"extra-info\": \"" + extra_info + "\", \n"; - // print the phase timings - ss << " \"timings\": [\n"; - const auto &ordered_phase_timings = GetOrderedPhaseTimings(); - for (idx_t i = 0; i < ordered_phase_timings.size(); i++) { - if (i > 0) { - ss << ",\n"; - } - ss << " {\n"; - ss << " \"annotation\": \"" + ordered_phase_timings[i].first + "\", \n"; - ss << " \"timing\": " + to_string(ordered_phase_timings[i].second) + "\n"; - ss << " }"; - } - ss << "\n"; - ss << " ],\n"; - // recursively print the physical operator tree - ss << " \"children\": [\n"; - ToJSONRecursive(*root, ss); - ss << " ]\n"; - ss << "}"; - return ss.str(); -} +class Stream { +public: + virtual ~Stream() = default; -void QueryProfiler::WriteToFile(const char *path, string &info) const { - ofstream out(path); - out << info; - out.close(); - // throw an IO exception if it fails to write the file - if (out.fail()) { - throw IOException(strerror(errno)); - } -} + virtual bool is_readable() const = 0; + virtual bool is_writable() const = 0; -unique_ptr QueryProfiler::CreateTree(PhysicalOperator *root, idx_t depth) { - if (OperatorRequiresProfiling(root->type)) { - this->query_requires_profiling = true; - } - auto node = make_unique(); - node->type = root->type; - node->name = root->GetName(); - node->extra_info = root->ParamsToString(); - node->depth = depth; - tree_map[root] = node.get(); - for (auto &child : root->children) { - auto child_node = CreateTree(child.get(), depth + 1); - node->children.push_back(move(child_node)); - } - switch (root->type) { - case PhysicalOperatorType::DELIM_JOIN: { - auto &delim_join = (PhysicalDelimJoin &)*root; - auto child_node = CreateTree((PhysicalOperator *)delim_join.join.get(), depth + 1); - node->children.push_back(move(child_node)); - child_node = CreateTree((PhysicalOperator *)delim_join.distinct.get(), depth + 1); - node->children.push_back(move(child_node)); - break; - } - case PhysicalOperatorType::EXECUTE: { - auto &execute = (PhysicalExecute &)*root; - auto child_node = CreateTree((PhysicalOperator *)execute.plan, depth + 1); - node->children.push_back(move(child_node)); - break; - } - default: - break; - } - return node; -} + virtual ssize_t read(char *ptr, size_t size) = 0; + virtual ssize_t write(const char *ptr, size_t size) = 0; + virtual void get_remote_ip_and_port(std::string &ip, int &port) const = 0; + virtual socket_t socket() const = 0; -void QueryProfiler::Render(const QueryProfiler::TreeNode &node, std::ostream &ss) const { - TreeRenderer renderer; - if (IsDetailedEnabled()) { - renderer.EnableDetailed(); - } else { - renderer.EnableStandard(); - } - renderer.Render(node, ss); -} + template + ssize_t write_format(const char *fmt, const Args &... args); + ssize_t write(const char *ptr); + ssize_t write(const std::string &s); +}; -void QueryProfiler::Print() { - Printer::Print(ToString()); -} +class TaskQueue { +public: + TaskQueue() = default; + virtual ~TaskQueue() = default; -vector QueryProfiler::GetOrderedPhaseTimings() const { - vector result; - // first sort the phases alphabetically - vector phases; - for (auto &entry : phase_timings) { - phases.push_back(entry.first); - } - std::sort(phases.begin(), phases.end()); - for (const auto &phase : phases) { - auto entry = phase_timings.find(phase); - D_ASSERT(entry != phase_timings.end()); - result.emplace_back(entry->first, entry->second); - } - return result; -} -void QueryProfiler::Propagate(QueryProfiler &qp) { - this->automatic_print_format = qp.automatic_print_format; - this->save_location = qp.save_location; - this->enabled = qp.enabled; - this->detailed_enabled = qp.detailed_enabled; -} + virtual void enqueue(std::function fn) = 0; + virtual void shutdown() = 0; -void ExpressionInfo::ExtractExpressionsRecursive(unique_ptr &state) { - if (state->child_states.empty()) { - return; - } - // extract the children of this node - for (auto &child : state->child_states) { - auto expr_info = make_unique(); - if (child->expr.expression_class == ExpressionClass::BOUND_FUNCTION) { - expr_info->hasfunction = true; - expr_info->function_name = ((BoundFunctionExpression &)child->expr).function.ToString(); - expr_info->function_time = child->profiler.time; - expr_info->sample_tuples_count = child->profiler.sample_tuples_count; - expr_info->tuples_count = child->profiler.tuples_count; - } - expr_info->ExtractExpressionsRecursive(child); - children.push_back(move(expr_info)); - } - return; -} + virtual void on_idle(){}; +}; -ExpressionExecutorInfo::ExpressionExecutorInfo(ExpressionExecutor &executor, const string &name, int id) : id(id) { - // Extract Expression Root Information from ExpressionExecutorStats - for (auto &state : executor.GetStates()) { - roots.push_back(make_unique(*state, name)); - } -} +class ThreadPool : public TaskQueue { +public: + explicit ThreadPool(size_t n) : shutdown_(false) { + while (n) { + threads_.emplace_back(worker(*this)); + n--; + } + } -ExpressionRootInfo::ExpressionRootInfo(ExpressionExecutorState &state, string name) - : current_count(state.profiler.current_count), sample_count(state.profiler.sample_count), - 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); - auto expression_info_p = make_unique(); - // Maybe root has a function - if (state.root_state->expr.expression_class == ExpressionClass::BOUND_FUNCTION) { - expression_info_p->hasfunction = true; - expression_info_p->function_name = ((BoundFunctionExpression &)state.root_state->expr).function.name; - expression_info_p->function_time = state.root_state->profiler.time; - expression_info_p->sample_tuples_count = state.root_state->profiler.sample_tuples_count; - expression_info_p->tuples_count = state.root_state->profiler.tuples_count; - } - expression_info_p->ExtractExpressionsRecursive(state.root_state); - root = move(expression_info_p); -} -} // namespace duckdb -#include + ThreadPool(const ThreadPool &) = delete; + ~ThreadPool() override = default; + void enqueue(std::function fn) override { + std::unique_lock lock(mutex_); + jobs_.push_back(std::move(fn)); + cond_.notify_one(); + } + void shutdown() override { + // Stop all worker threads... + { + std::unique_lock lock(mutex_); + shutdown_ = true; + } + cond_.notify_all(); + // Join... + for (auto &t : threads_) { + t.join(); + } + } -namespace duckdb { +private: + struct worker { + explicit worker(ThreadPool &pool) : pool_(pool) {} -QueryResult::QueryResult(QueryResultType type, StatementType statement_type) - : type(type), statement_type(statement_type), success(true) { -} + void operator()() { + for (;;) { + std::function fn; + { + std::unique_lock lock(pool_.mutex_); -QueryResult::QueryResult(QueryResultType type, StatementType statement_type, vector types_p, - vector names_p) - : type(type), statement_type(statement_type), types(move(types_p)), names(move(names_p)), success(true) { - D_ASSERT(types.size() == names.size()); -} + pool_.cond_.wait( + lock, [&] { return !pool_.jobs_.empty() || pool_.shutdown_; }); -QueryResult::QueryResult(QueryResultType type, string error) : type(type), success(false), error(move(error)) { -} + if (pool_.shutdown_ && pool_.jobs_.empty()) { break; } -unique_ptr QueryResult::Fetch() { - auto chunk = FetchRaw(); - if (!chunk) { - return nullptr; - } - chunk->Normalify(); - return chunk; -} + fn = pool_.jobs_.front(); + pool_.jobs_.pop_front(); + } -bool QueryResult::Equals(QueryResult &other) { // LCOV_EXCL_START - // first compare the success state of the results - if (success != other.success) { - return false; - } - if (!success) { - return error == other.error; - } - // compare names - if (names != other.names) { - return false; - } - // compare types - if (types != other.types) { - return false; - } - // now compare the actual values - // fetch chunks - while (true) { - auto lchunk = Fetch(); - auto rchunk = other.Fetch(); - if (!lchunk && !rchunk) { - return true; - } - if (!lchunk || !rchunk) { - return false; - } - if (lchunk->size() == 0 && rchunk->size() == 0) { - return true; - } - if (lchunk->size() != rchunk->size()) { - return false; - } - D_ASSERT(lchunk->ColumnCount() == rchunk->ColumnCount()); - for (idx_t col = 0; col < rchunk->ColumnCount(); col++) { - for (idx_t row = 0; row < rchunk->size(); row++) { - auto lvalue = lchunk->GetValue(col, row); - auto rvalue = rchunk->GetValue(col, row); - if (lvalue != rvalue) { - return false; - } - } - } - } -} // LCOV_EXCL_STOP + assert(true == static_cast(fn)); + fn(); + } + } -void QueryResult::Print() { - Printer::Print(ToString()); -} + ThreadPool &pool_; + }; + friend struct worker; -string QueryResult::HeaderToString() { - string result; - for (auto &name : names) { - result += name + "\t"; - } - result += "\n"; - for (auto &type : types) { - result += type.ToString() + "\t"; - } - result += "\n"; - return result; -} + std::vector threads_; + std::list> jobs_; -struct DuckDBArrowSchemaHolder { - // unused in children - vector children; - // unused in children - vector children_ptrs; - //! used for nested structures - std::list> nested_children; - std::list> nested_children_ptr; - //! This holds strings created to represent decimal types - vector> owned_type_names; + bool shutdown_; + + std::condition_variable cond_; + std::mutex mutex_; }; -static void ReleaseDuckDBArrowSchema(ArrowSchema *schema) { - if (!schema || !schema->release) { - return; - } - schema->release = nullptr; - auto holder = static_cast(schema->private_data); - delete holder; -} +using Logger = std::function; -void InitializeChild(ArrowSchema &child, const string &name = "") { - //! Child is cleaned up by parent - child.private_data = nullptr; - child.release = ReleaseDuckDBArrowSchema; +using SocketOptions = std::function; - //! Store the child schema - child.flags = ARROW_FLAG_NULLABLE; - child.name = name.c_str(); - child.n_children = 0; - child.children = nullptr; - child.metadata = nullptr; - child.dictionary = nullptr; +inline void default_socket_options(socket_t sock) { + int yes = 1; +#ifdef _WIN32 + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast(&yes), + sizeof(yes)); + setsockopt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, + reinterpret_cast(&yes), sizeof(yes)); +#else +#ifdef SO_REUSEPORT + setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, reinterpret_cast(&yes), + sizeof(yes)); +#else + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast(&yes), + sizeof(yes)); +#endif +#endif } -void SetArrowFormat(DuckDBArrowSchemaHolder &root_holder, ArrowSchema &child, const LogicalType &type); -void SetArrowMapFormat(DuckDBArrowSchemaHolder &root_holder, ArrowSchema &child, const LogicalType &type) { - child.format = "+m"; - //! Map has one child which is a struct - child.n_children = 1; - root_holder.nested_children.emplace_back(); - root_holder.nested_children.back().resize(1); - root_holder.nested_children_ptr.emplace_back(); - root_holder.nested_children_ptr.back().push_back(&root_holder.nested_children.back()[0]); - 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); -} - -void SetArrowFormat(DuckDBArrowSchemaHolder &root_holder, ArrowSchema &child, const LogicalType &type) { - switch (type.id()) { - case LogicalTypeId::BOOLEAN: - child.format = "b"; - break; - case LogicalTypeId::TINYINT: - child.format = "c"; - break; - case LogicalTypeId::SMALLINT: - child.format = "s"; - break; - case LogicalTypeId::INTEGER: - child.format = "i"; - break; - case LogicalTypeId::BIGINT: - child.format = "l"; - break; - case LogicalTypeId::UTINYINT: - child.format = "C"; - break; - case LogicalTypeId::USMALLINT: - child.format = "S"; - break; - case LogicalTypeId::UINTEGER: - child.format = "I"; - break; - case LogicalTypeId::UBIGINT: - child.format = "L"; - break; - case LogicalTypeId::FLOAT: - child.format = "f"; - break; - case LogicalTypeId::HUGEINT: - child.format = "d:38,0"; - break; - case LogicalTypeId::DOUBLE: - child.format = "g"; - break; - case LogicalTypeId::VARCHAR: - child.format = "u"; - break; - case LogicalTypeId::DATE: - child.format = "tdD"; - break; - case LogicalTypeId::TIME: - child.format = "ttu"; - break; - case LogicalTypeId::TIMESTAMP: - child.format = "tsu:"; - break; - case LogicalTypeId::TIMESTAMP_SEC: - child.format = "tss:"; - break; - case LogicalTypeId::TIMESTAMP_NS: - child.format = "tsn:"; - break; - case LogicalTypeId::TIMESTAMP_MS: - child.format = "tsm:"; - break; - case LogicalTypeId::INTERVAL: - child.format = "tDm"; - break; - case LogicalTypeId::DECIMAL: { - uint8_t width, scale; - type.GetDecimalProperties(width, scale); - string format = "d:" + to_string(width) + "," + to_string(scale); - unique_ptr format_ptr = unique_ptr(new char[format.size() + 1]); - for (size_t i = 0; i < format.size(); i++) { - format_ptr[i] = format[i]; - } - format_ptr[format.size()] = '\0'; - root_holder.owned_type_names.push_back(move(format_ptr)); - child.format = root_holder.owned_type_names.back().get(); - break; - } - case LogicalTypeId::SQLNULL: { - child.format = "n"; - break; - } - case LogicalTypeId::BLOB: { - child.format = "z"; - break; - } - case LogicalTypeId::LIST: { - child.format = "+l"; - child.n_children = 1; - root_holder.nested_children.emplace_back(); - root_holder.nested_children.back().resize(1); - root_holder.nested_children_ptr.emplace_back(); - root_holder.nested_children_ptr.back().push_back(&root_holder.nested_children.back()[0]); - InitializeChild(root_holder.nested_children.back()[0]); - child.children = &root_holder.nested_children_ptr.back()[0]; - child.children[0]->name = "l"; - SetArrowFormat(root_holder, **child.children, ListType::GetChildType(type)); - break; - } - case LogicalTypeId::STRUCT: { - child.format = "+s"; - auto &child_types = StructType::GetChildTypes(type); - child.n_children = child_types.size(); - root_holder.nested_children.emplace_back(); - root_holder.nested_children.back().resize(child_types.size()); - root_holder.nested_children_ptr.emplace_back(); - root_holder.nested_children_ptr.back().resize(child_types.size()); - for (idx_t type_idx = 0; type_idx < child_types.size(); type_idx++) { - root_holder.nested_children_ptr.back()[type_idx] = &root_holder.nested_children.back()[type_idx]; - } - child.children = &root_holder.nested_children_ptr.back()[0]; - for (size_t type_idx = 0; type_idx < child_types.size(); type_idx++) { +class Server { +public: + using Handler = std::function; - InitializeChild(*child.children[type_idx]); + using ExceptionHandler = + std::function; - auto &struct_col_name = child_types[type_idx].first; - unique_ptr name_ptr = unique_ptr(new char[struct_col_name.size() + 1]); - for (size_t i = 0; i < struct_col_name.size(); i++) { - name_ptr[i] = struct_col_name[i]; - } - name_ptr[struct_col_name.size()] = '\0'; - root_holder.owned_type_names.push_back(move(name_ptr)); + enum class HandlerResponse { + Handled, + Unhandled, + }; + using HandlerWithResponse = + std::function; + + using HandlerWithContentReader = std::function; + + using Expect100ContinueHandler = + std::function; + + Server(); + + virtual ~Server(); + + virtual bool is_valid() const; + + Server &Get(const char *pattern, Handler handler); + Server &Get(const char *pattern, size_t pattern_len, Handler handler); + Server &Post(const char *pattern, Handler handler); + Server &Post(const char *pattern, size_t pattern_len, Handler handler); + Server &Post(const char *pattern, HandlerWithContentReader handler); + Server &Post(const char *pattern, size_t pattern_len, + HandlerWithContentReader handler); + Server &Put(const char *pattern, Handler handler); + Server &Put(const char *pattern, size_t pattern_len, Handler handler); + Server &Put(const char *pattern, HandlerWithContentReader handler); + Server &Put(const char *pattern, size_t pattern_len, + HandlerWithContentReader handler); + Server &Patch(const char *pattern, Handler handler); + Server &Patch(const char *pattern, size_t pattern_len, Handler handler); + Server &Patch(const char *pattern, HandlerWithContentReader handler); + Server &Patch(const char *pattern, size_t pattern_len, + HandlerWithContentReader handler); + Server &Delete(const char *pattern, Handler handler); + Server &Delete(const char *pattern, size_t pattern_len, Handler handler); + Server &Delete(const char *pattern, HandlerWithContentReader handler); + Server &Delete(const char *pattern, size_t pattern_len, + HandlerWithContentReader handler); + Server &Options(const char *pattern, Handler handler); + Server &Options(const char *pattern, size_t pattern_len, Handler handler); + + bool set_base_dir(const char *dir, const char *mount_point = nullptr); + bool set_mount_point(const char *mount_point, const char *dir, + Headers headers = Headers()); + bool remove_mount_point(const char *mount_point); + Server &set_file_extension_and_mimetype_mapping(const char *ext, + const char *mime); + Server &set_file_request_handler(Handler handler); + + Server &set_error_handler(HandlerWithResponse handler); + Server &set_error_handler(Handler handler); + Server &set_exception_handler(ExceptionHandler handler); + Server &set_pre_routing_handler(HandlerWithResponse handler); + Server &set_post_routing_handler(Handler handler); + + Server &set_expect_100_continue_handler(Expect100ContinueHandler handler); + Server &set_logger(Logger logger); + + Server &set_tcp_nodelay(bool on); + Server &set_socket_options(SocketOptions socket_options); + + Server &set_keep_alive_max_count(size_t count); + Server &set_keep_alive_timeout(time_t sec); + Server &set_read_timeout(time_t sec, time_t usec = 0); + Server &set_write_timeout(time_t sec, time_t usec = 0); + Server &set_idle_interval(time_t sec, time_t usec = 0); + + Server &set_payload_max_length(size_t length); + + bool bind_to_port(const char *host, int port, int socket_flags = 0); + int bind_to_any_port(const char *host, int socket_flags = 0); + bool listen_after_bind(); + + bool listen(const char *host, int port, int socket_flags = 0); + + bool is_running() const; + void stop(); + + std::function new_task_queue; - child.children[type_idx]->name = root_holder.owned_type_names.back().get(); - SetArrowFormat(root_holder, *child.children[type_idx], child_types[type_idx].second); - } - break; - } - case LogicalTypeId::MAP: { - SetArrowMapFormat(root_holder, child, type); - break; - } - default: - throw InternalException("Unsupported Arrow type " + type.ToString()); - } -} +protected: + bool process_request(Stream &strm, bool close_connection, + bool &connection_closed, + const std::function &setup_request); + + std::atomic svr_sock_; + size_t keep_alive_max_count_ = CPPHTTPLIB_KEEPALIVE_MAX_COUNT; + time_t keep_alive_timeout_sec_ = CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND; + time_t read_timeout_sec_ = CPPHTTPLIB_READ_TIMEOUT_SECOND; + time_t read_timeout_usec_ = CPPHTTPLIB_READ_TIMEOUT_USECOND; + time_t write_timeout_sec_ = CPPHTTPLIB_WRITE_TIMEOUT_SECOND; + time_t write_timeout_usec_ = CPPHTTPLIB_WRITE_TIMEOUT_USECOND; + time_t idle_interval_sec_ = CPPHTTPLIB_IDLE_INTERVAL_SECOND; + time_t idle_interval_usec_ = CPPHTTPLIB_IDLE_INTERVAL_USECOND; + size_t payload_max_length_ = CPPHTTPLIB_PAYLOAD_MAX_LENGTH; -void QueryResult::ToArrowSchema(ArrowSchema *out_schema) { - D_ASSERT(out_schema); +private: + using Handlers = std::vector>; + using HandlersForContentReader = + std::vector>; + + socket_t create_server_socket(const char *host, int port, int socket_flags, + SocketOptions socket_options) const; + int bind_internal(const char *host, int port, int socket_flags); + bool listen_internal(); + + bool routing(Request &req, Response &res, Stream &strm); + bool handle_file_request(const Request &req, Response &res, + bool head = false); + bool dispatch_request(Request &req, Response &res, const Handlers &handlers); + bool + dispatch_request_for_content_reader(Request &req, Response &res, + ContentReader content_reader, + const HandlersForContentReader &handlers); + + bool parse_request_line(const char *s, Request &req); + void apply_ranges(const Request &req, Response &res, + std::string &content_type, std::string &boundary); + bool write_response(Stream &strm, bool close_connection, const Request &req, + Response &res); + bool write_response_with_content(Stream &strm, bool close_connection, + const Request &req, Response &res); + bool write_response_core(Stream &strm, bool close_connection, + const Request &req, Response &res, + bool need_apply_ranges); + bool write_content_with_provider(Stream &strm, const Request &req, + Response &res, const std::string &boundary, + const std::string &content_type); + bool read_content(Stream &strm, Request &req, Response &res); + bool + read_content_with_content_receiver(Stream &strm, Request &req, Response &res, + ContentReceiver receiver, + MultipartContentHeader multipart_header, + ContentReceiver multipart_receiver); + bool read_content_core(Stream &strm, Request &req, Response &res, + ContentReceiver receiver, + MultipartContentHeader mulitpart_header, + ContentReceiver multipart_receiver); + + virtual bool process_and_close_socket(socket_t sock); + + struct MountPointEntry { + std::string mount_point; + std::string base_dir; + Headers headers; + }; + std::vector base_dirs_; + + std::atomic is_running_; + std::map file_extension_and_mimetype_map_; + Handler file_request_handler_; + Handlers get_handlers_; + Handlers post_handlers_; + HandlersForContentReader post_handlers_for_content_reader_; + Handlers put_handlers_; + HandlersForContentReader put_handlers_for_content_reader_; + Handlers patch_handlers_; + HandlersForContentReader patch_handlers_for_content_reader_; + Handlers delete_handlers_; + HandlersForContentReader delete_handlers_for_content_reader_; + Handlers options_handlers_; + HandlerWithResponse error_handler_; + ExceptionHandler exception_handler_; + HandlerWithResponse pre_routing_handler_; + Handler post_routing_handler_; + Logger logger_; + Expect100ContinueHandler expect_100_continue_handler_; + + bool tcp_nodelay_ = CPPHTTPLIB_TCP_NODELAY; + SocketOptions socket_options_ = default_socket_options; +}; + +enum Error { + Success = 0, + Unknown, + Connection, + BindIPAddress, + Read, + Write, + ExceedRedirectCount, + Canceled, + SSLConnection, + SSLLoadingCerts, + SSLServerVerification, + UnsupportedMultipartBoundaryChars, + Compression, +}; + +class Result { +public: + Result(std::unique_ptr res, Error err) + : res_(std::move(res)), err_(err) {} + operator bool() const { return res_ != nullptr; } + bool operator==(std::nullptr_t) const { return res_ == nullptr; } + bool operator!=(std::nullptr_t) const { return res_ != nullptr; } + const Response &value() const { return *res_; } + Response &value() { return *res_; } + const Response &operator*() const { return *res_; } + Response &operator*() { return *res_; } + const Response *operator->() const { return res_.get(); } + Response *operator->() { return res_.get(); } + Error error() const { return err_; } - // Allocate as unique_ptr first to cleanup properly on error - auto root_holder = make_unique(); +private: + std::unique_ptr res_; + Error err_; +}; - // Allocate the children - root_holder->children.resize(ColumnCount()); - root_holder->children_ptrs.resize(ColumnCount(), nullptr); - for (size_t i = 0; i < ColumnCount(); ++i) { - root_holder->children_ptrs[i] = &root_holder->children[i]; - } - out_schema->children = root_holder->children_ptrs.data(); - out_schema->n_children = ColumnCount(); +class ClientImpl { +public: + explicit ClientImpl(const std::string &host); + + explicit ClientImpl(const std::string &host, int port); + + explicit ClientImpl(const std::string &host, int port, + const std::string &client_cert_path, + const std::string &client_key_path); + + virtual ~ClientImpl(); + + virtual bool is_valid() const; + + Result Get(const char *path); + Result Get(const char *path, const Headers &headers); + Result Get(const char *path, Progress progress); + Result Get(const char *path, const Headers &headers, Progress progress); + Result Get(const char *path, ContentReceiver content_receiver); + Result Get(const char *path, const Headers &headers, + ContentReceiver content_receiver); + Result Get(const char *path, ContentReceiver content_receiver, + Progress progress); + Result Get(const char *path, const Headers &headers, + ContentReceiver content_receiver, Progress progress); + Result Get(const char *path, ResponseHandler response_handler, + ContentReceiver content_receiver); + Result Get(const char *path, const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver); + Result Get(const char *path, ResponseHandler response_handler, + ContentReceiver content_receiver, Progress progress); + Result Get(const char *path, const Headers &headers, + ResponseHandler response_handler, ContentReceiver content_receiver, + Progress progress); + + Result Get(const char *path, const Params ¶ms, const Headers &headers, + Progress progress = nullptr); + Result Get(const char *path, const Params ¶ms, const Headers &headers, + ContentReceiver content_receiver, Progress progress = nullptr); + Result Get(const char *path, const Params ¶ms, const Headers &headers, + ResponseHandler response_handler, ContentReceiver content_receiver, + Progress progress = nullptr); + + Result Head(const char *path); + Result Head(const char *path, const Headers &headers); + + Result Post(const char *path); + Result Post(const char *path, const char *body, size_t content_length, + const char *content_type); + Result Post(const char *path, const Headers &headers, const char *body, + size_t content_length, const char *content_type); + Result Post(const char *path, const std::string &body, + const char *content_type); + Result Post(const char *path, const Headers &headers, const std::string &body, + const char *content_type); + Result Post(const char *path, size_t content_length, + ContentProvider content_provider, const char *content_type); + Result Post(const char *path, ContentProviderWithoutLength content_provider, + const char *content_type); + Result Post(const char *path, const Headers &headers, size_t content_length, + ContentProvider content_provider, const char *content_type); + Result Post(const char *path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const char *content_type); + Result Post(const char *path, const Params ¶ms); + Result Post(const char *path, const Headers &headers, const Params ¶ms); + Result Post(const char *path, const MultipartFormDataItems &items); + Result Post(const char *path, const Headers &headers, + const MultipartFormDataItems &items); + Result Post(const char *path, const Headers &headers, + const MultipartFormDataItems &items, const std::string &boundary); + + Result Put(const char *path); + Result Put(const char *path, const char *body, size_t content_length, + const char *content_type); + Result Put(const char *path, const Headers &headers, const char *body, + size_t content_length, const char *content_type); + Result Put(const char *path, const std::string &body, + const char *content_type); + Result Put(const char *path, const Headers &headers, const std::string &body, + const char *content_type); + Result Put(const char *path, size_t content_length, + ContentProvider content_provider, const char *content_type); + Result Put(const char *path, ContentProviderWithoutLength content_provider, + const char *content_type); + Result Put(const char *path, const Headers &headers, size_t content_length, + ContentProvider content_provider, const char *content_type); + Result Put(const char *path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const char *content_type); + Result Put(const char *path, const Params ¶ms); + Result Put(const char *path, const Headers &headers, const Params ¶ms); + + Result Patch(const char *path); + Result Patch(const char *path, const char *body, size_t content_length, + const char *content_type); + Result Patch(const char *path, const Headers &headers, const char *body, + size_t content_length, const char *content_type); + Result Patch(const char *path, const std::string &body, + const char *content_type); + Result Patch(const char *path, const Headers &headers, + const std::string &body, const char *content_type); + Result Patch(const char *path, size_t content_length, + ContentProvider content_provider, const char *content_type); + Result Patch(const char *path, ContentProviderWithoutLength content_provider, + const char *content_type); + Result Patch(const char *path, const Headers &headers, size_t content_length, + ContentProvider content_provider, const char *content_type); + Result Patch(const char *path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const char *content_type); + + Result Delete(const char *path); + Result Delete(const char *path, const Headers &headers); + Result Delete(const char *path, const char *body, size_t content_length, + const char *content_type); + Result Delete(const char *path, const Headers &headers, const char *body, + size_t content_length, const char *content_type); + Result Delete(const char *path, const std::string &body, + const char *content_type); + Result Delete(const char *path, const Headers &headers, + const std::string &body, const char *content_type); + + Result Options(const char *path); + Result Options(const char *path, const Headers &headers); + + bool send(const Request &req, Response &res, Error &error); + Result send(const Request &req); + + size_t is_socket_open() const; + + void stop(); + + void set_default_headers(Headers headers); + + void set_tcp_nodelay(bool on); + void set_socket_options(SocketOptions socket_options); + + void set_connection_timeout(time_t sec, time_t usec = 0); + void set_read_timeout(time_t sec, time_t usec = 0); + void set_write_timeout(time_t sec, time_t usec = 0); + + void set_basic_auth(const char *username, const char *password); + void set_bearer_token_auth(const char *token); +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + void set_digest_auth(const char *username, const char *password); +#endif - // Store the schema - out_schema->format = "+s"; // struct apparently - out_schema->flags = 0; - out_schema->metadata = nullptr; - out_schema->name = "duckdb_query_result"; - out_schema->dictionary = nullptr; + void set_keep_alive(bool on); + void set_follow_location(bool on); - // Configure all child schemas - for (idx_t col_idx = 0; col_idx < ColumnCount(); col_idx++) { + void set_compress(bool on); - auto &child = root_holder->children[col_idx]; - InitializeChild(child, names[col_idx]); - SetArrowFormat(*root_holder, child, types[col_idx]); - } + void set_decompress(bool on); - // Release ownership to caller - out_schema->private_data = root_holder.release(); - out_schema->release = ReleaseDuckDBArrowSchema; -} + void set_interface(const char *intf); -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/relation/aggregate_relation.hpp -// -// -//===----------------------------------------------------------------------===// + void set_proxy(const char *host, int port); + void set_proxy_basic_auth(const char *username, const char *password); + void set_proxy_bearer_token_auth(const char *token); +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + void set_proxy_digest_auth(const char *username, const char *password); +#endif +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + void enable_server_certificate_verification(bool enabled); +#endif + void set_logger(Logger logger); +protected: + struct Socket { + socket_t sock = INVALID_SOCKET; +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + SSL *ssl = nullptr; +#endif + bool is_open() const { return sock != INVALID_SOCKET; } + }; + virtual bool create_and_connect_socket(Socket &socket, Error &error); + + // All of: + // shutdown_ssl + // shutdown_socket + // close_socket + // should ONLY be called when socket_mutex_ is locked. + // Also, shutdown_ssl and close_socket should also NOT be called concurrently + // with a DIFFERENT thread sending requests using that socket. + virtual void shutdown_ssl(Socket &socket, bool shutdown_gracefully); + void shutdown_socket(Socket &socket); + void close_socket(Socket &socket); + + // Similar to shutdown_ssl and close_socket, this should NOT be called + // concurrently with a DIFFERENT thread sending requests from the socket + void lock_socket_and_shutdown_and_close(); + + bool process_request(Stream &strm, const Request &req, Response &res, + bool close_connection, Error &error); + + bool write_content_with_provider(Stream &strm, const Request &req, + Error &error); + + void copy_settings(const ClientImpl &rhs); + + // Socket endoint information + const std::string host_; + const int port_; + const std::string host_and_port_; + + // Current open socket + Socket socket_; + mutable std::mutex socket_mutex_; + std::recursive_mutex request_mutex_; + + // These are all protected under socket_mutex + size_t socket_requests_in_flight_ = 0; + std::thread::id socket_requests_are_from_thread_ = std::thread::id(); + bool socket_should_be_closed_when_request_is_done_ = false; + + // Default headers + Headers default_headers_; + + // Settings + std::string client_cert_path_; + std::string client_key_path_; + + time_t connection_timeout_sec_ = CPPHTTPLIB_CONNECTION_TIMEOUT_SECOND; + time_t connection_timeout_usec_ = CPPHTTPLIB_CONNECTION_TIMEOUT_USECOND; + time_t read_timeout_sec_ = CPPHTTPLIB_READ_TIMEOUT_SECOND; + time_t read_timeout_usec_ = CPPHTTPLIB_READ_TIMEOUT_USECOND; + time_t write_timeout_sec_ = CPPHTTPLIB_WRITE_TIMEOUT_SECOND; + time_t write_timeout_usec_ = CPPHTTPLIB_WRITE_TIMEOUT_USECOND; + + std::string basic_auth_username_; + std::string basic_auth_password_; + std::string bearer_token_auth_token_; +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + std::string digest_auth_username_; + std::string digest_auth_password_; +#endif -namespace duckdb { + bool keep_alive_ = false; + bool follow_location_ = false; -class AggregateRelation : public Relation { -public: - AggregateRelation(shared_ptr child, vector> expressions); - AggregateRelation(shared_ptr child, vector> expressions, - vector> groups); + bool tcp_nodelay_ = CPPHTTPLIB_TCP_NODELAY; + SocketOptions socket_options_ = nullptr; - vector> expressions; - vector> groups; - vector columns; - shared_ptr child; + bool compress_ = false; + bool decompress_ = true; -public: - unique_ptr GetQueryNode() override; + std::string interface_; - const vector &Columns() override; - string ToString(idx_t depth) override; - string GetAlias() override; -}; + std::string proxy_host_; + int proxy_port_ = -1; -} // namespace duckdb + std::string proxy_basic_auth_username_; + std::string proxy_basic_auth_password_; + std::string proxy_bearer_token_auth_token_; +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + std::string proxy_digest_auth_username_; + std::string proxy_digest_auth_password_; +#endif +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + bool server_certificate_verification_ = true; +#endif + Logger logger_; -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/tableref/subqueryref.hpp -// -// -//===----------------------------------------------------------------------===// +private: + socket_t create_client_socket(Error &error) const; + bool read_response_line(Stream &strm, const Request &req, Response &res); + bool write_request(Stream &strm, const Request &req, bool close_connection, + Error &error); + bool redirect(const Request &req, Response &res, Error &error); + bool handle_request(Stream &strm, const Request &req, Response &res, + bool close_connection, Error &error); + std::unique_ptr send_with_content_provider( + const char *method, const char *path, const Headers &headers, + const char *body, size_t content_length, ContentProvider content_provider, + ContentProviderWithoutLength content_provider_without_length, + const char *content_type, Error &error); + Result send_with_content_provider( + const char *method, const char *path, const Headers &headers, + const char *body, size_t content_length, ContentProvider content_provider, + ContentProviderWithoutLength content_provider_without_length, + const char *content_type); + + virtual bool process_socket(const Socket &socket, + std::function callback); + virtual bool is_ssl() const; +}; + +class Client { +public: + // Universal interface + explicit Client(const char *scheme_host_port); + + explicit Client(const char *scheme_host_port, + const std::string &client_cert_path, + const std::string &client_key_path); + + // HTTP only interface + explicit Client(const std::string &host, int port); + + explicit Client(const std::string &host, int port, + const std::string &client_cert_path, + const std::string &client_key_path); + + ~Client(); + + bool is_valid() const; + + Result Get(const char *path); + Result Get(const char *path, const Headers &headers); + Result Get(const char *path, Progress progress); + Result Get(const char *path, const Headers &headers, Progress progress); + Result Get(const char *path, ContentReceiver content_receiver); + Result Get(const char *path, const Headers &headers, + ContentReceiver content_receiver); + Result Get(const char *path, ContentReceiver content_receiver, + Progress progress); + Result Get(const char *path, const Headers &headers, + ContentReceiver content_receiver, Progress progress); + Result Get(const char *path, ResponseHandler response_handler, + ContentReceiver content_receiver); + Result Get(const char *path, const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver); + Result Get(const char *path, const Headers &headers, + ResponseHandler response_handler, ContentReceiver content_receiver, + Progress progress); + Result Get(const char *path, ResponseHandler response_handler, + ContentReceiver content_receiver, Progress progress); + + Result Get(const char *path, const Params ¶ms, const Headers &headers, + Progress progress = nullptr); + Result Get(const char *path, const Params ¶ms, const Headers &headers, + ContentReceiver content_receiver, Progress progress = nullptr); + Result Get(const char *path, const Params ¶ms, const Headers &headers, + ResponseHandler response_handler, ContentReceiver content_receiver, + Progress progress = nullptr); + + Result Head(const char *path); + Result Head(const char *path, const Headers &headers); + + Result Post(const char *path); + Result Post(const char *path, const char *body, size_t content_length, + const char *content_type); + Result Post(const char *path, const Headers &headers, const char *body, + size_t content_length, const char *content_type); + Result Post(const char *path, const std::string &body, + const char *content_type); + Result Post(const char *path, const Headers &headers, const std::string &body, + const char *content_type); + Result Post(const char *path, size_t content_length, + ContentProvider content_provider, const char *content_type); + Result Post(const char *path, ContentProviderWithoutLength content_provider, + const char *content_type); + Result Post(const char *path, const Headers &headers, size_t content_length, + ContentProvider content_provider, const char *content_type); + Result Post(const char *path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const char *content_type); + Result Post(const char *path, const Params ¶ms); + Result Post(const char *path, const Headers &headers, const Params ¶ms); + Result Post(const char *path, const MultipartFormDataItems &items); + Result Post(const char *path, const Headers &headers, + const MultipartFormDataItems &items); + Result Post(const char *path, const Headers &headers, + const MultipartFormDataItems &items, const std::string &boundary); + Result Put(const char *path); + Result Put(const char *path, const char *body, size_t content_length, + const char *content_type); + Result Put(const char *path, const Headers &headers, const char *body, + size_t content_length, const char *content_type); + Result Put(const char *path, const std::string &body, + const char *content_type); + Result Put(const char *path, const Headers &headers, const std::string &body, + const char *content_type); + Result Put(const char *path, size_t content_length, + ContentProvider content_provider, const char *content_type); + Result Put(const char *path, ContentProviderWithoutLength content_provider, + const char *content_type); + Result Put(const char *path, const Headers &headers, size_t content_length, + ContentProvider content_provider, const char *content_type); + Result Put(const char *path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const char *content_type); + Result Put(const char *path, const Params ¶ms); + Result Put(const char *path, const Headers &headers, const Params ¶ms); + Result Patch(const char *path); + Result Patch(const char *path, const char *body, size_t content_length, + const char *content_type); + Result Patch(const char *path, const Headers &headers, const char *body, + size_t content_length, const char *content_type); + Result Patch(const char *path, const std::string &body, + const char *content_type); + Result Patch(const char *path, const Headers &headers, + const std::string &body, const char *content_type); + Result Patch(const char *path, size_t content_length, + ContentProvider content_provider, const char *content_type); + Result Patch(const char *path, ContentProviderWithoutLength content_provider, + const char *content_type); + Result Patch(const char *path, const Headers &headers, size_t content_length, + ContentProvider content_provider, const char *content_type); + Result Patch(const char *path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const char *content_type); + + Result Delete(const char *path); + Result Delete(const char *path, const Headers &headers); + Result Delete(const char *path, const char *body, size_t content_length, + const char *content_type); + Result Delete(const char *path, const Headers &headers, const char *body, + size_t content_length, const char *content_type); + Result Delete(const char *path, const std::string &body, + const char *content_type); + Result Delete(const char *path, const Headers &headers, + const std::string &body, const char *content_type); + + Result Options(const char *path); + Result Options(const char *path, const Headers &headers); + + bool send(const Request &req, Response &res, Error &error); + Result send(const Request &req); + + size_t is_socket_open() const; + + void stop(); + + void set_default_headers(Headers headers); + + void set_tcp_nodelay(bool on); + void set_socket_options(SocketOptions socket_options); + + void set_connection_timeout(time_t sec, time_t usec = 0); + void set_read_timeout(time_t sec, time_t usec = 0); + void set_write_timeout(time_t sec, time_t usec = 0); + + void set_basic_auth(const char *username, const char *password); + void set_bearer_token_auth(const char *token); +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + void set_digest_auth(const char *username, const char *password); +#endif + void set_keep_alive(bool on); + void set_follow_location(bool on); + void set_compress(bool on); + void set_decompress(bool on); + void set_interface(const char *intf); + void set_proxy(const char *host, int port); + void set_proxy_basic_auth(const char *username, const char *password); + void set_proxy_bearer_token_auth(const char *token); +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + void set_proxy_digest_auth(const char *username, const char *password); +#endif -namespace duckdb { -//! Represents a subquery -class SubqueryRef : public TableRef { -public: - explicit SubqueryRef(unique_ptr subquery, string alias = string()); +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + void enable_server_certificate_verification(bool enabled); +#endif - //! The subquery - unique_ptr subquery; - //! Alises for the column names - vector column_name_alias; + void set_logger(Logger logger); -public: - bool Equals(const TableRef *other_p) const override; + // SSL +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + void set_ca_cert_path(const char *ca_cert_file_path, + const char *ca_cert_dir_path = nullptr); - unique_ptr Copy() override; + void set_ca_cert_store(X509_STORE *ca_cert_store); - //! Serializes a blob into a SubqueryRef - void Serialize(Serializer &serializer) override; - //! Deserializes a blob back into a SubqueryRef - static unique_ptr Deserialize(Deserializer &source); -}; -} // namespace duckdb + long get_openssl_verify_result() const; + SSL_CTX *ssl_context() const; +#endif -namespace duckdb { +private: + std::unique_ptr cli_; -AggregateRelation::AggregateRelation(shared_ptr child_p, - vector> parsed_expressions) - : Relation(child_p->context, RelationType::AGGREGATE_RELATION), expressions(move(parsed_expressions)), - child(move(child_p)) { - // bind the expressions - context.TryBindRelation(*this, this->columns); -} +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + bool is_ssl_ = false; +#endif +}; -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)) { - // bind the expressions - context.TryBindRelation(*this, this->columns); -} +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +class SSLServer : public Server { +public: + SSLServer(const char *cert_path, const char *private_key_path, + const char *client_ca_cert_file_path = nullptr, + const char *client_ca_cert_dir_path = nullptr); -unique_ptr AggregateRelation::GetQueryNode() { - auto child_ptr = child.get(); - while (child_ptr->InheritsColumnBindings()) { - child_ptr = child_ptr->ChildRelation(); - } - unique_ptr result; - if (child_ptr->type == RelationType::JOIN_RELATION) { - // child node is a join: push projection into the child query node - result = child->GetQueryNode(); - } else { - // 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); - } - D_ASSERT(result->type == QueryNodeType::SELECT_NODE); - auto &select_node = (SelectNode &)*result; - if (!groups.empty()) { - // explicit groups provided: use standard handling - select_node.aggregate_handling = AggregateHandling::STANDARD_HANDLING; - select_node.groups.group_expressions.clear(); - GroupingSet grouping_set; - for (idx_t i = 0; i < groups.size(); i++) { - select_node.groups.group_expressions.push_back(groups[i]->Copy()); - grouping_set.insert(i); - } - select_node.groups.grouping_sets.push_back(move(grouping_set)); - } else { - // no groups provided: automatically figure out groups (if any) - select_node.aggregate_handling = AggregateHandling::FORCE_AGGREGATES; - } - select_node.select_list.clear(); - for (auto &expr : expressions) { - select_node.select_list.push_back(expr->Copy()); - } - return result; -} + SSLServer(X509 *cert, EVP_PKEY *private_key, + X509_STORE *client_ca_cert_store = nullptr); -string AggregateRelation::GetAlias() { - return child->GetAlias(); -} + ~SSLServer() override; -const vector &AggregateRelation::Columns() { - return columns; -} + bool is_valid() const override; -string AggregateRelation::ToString(idx_t depth) { - string str = RenderWhitespace(depth) + "Aggregate ["; - for (idx_t i = 0; i < expressions.size(); i++) { - if (i != 0) { - str += ", "; - } - str += expressions[i]->ToString(); - } - str += "]\n"; - return str + child->ToString(depth + 1); -} +private: + bool process_and_close_socket(socket_t sock) override; -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/relation/create_table_relation.hpp -// -// -//===----------------------------------------------------------------------===// + SSL_CTX *ctx_; + std::mutex ctx_mutex_; +}; +class SSLClient : public ClientImpl { +public: + explicit SSLClient(const std::string &host); + explicit SSLClient(const std::string &host, int port); + explicit SSLClient(const std::string &host, int port, + const std::string &client_cert_path, + const std::string &client_key_path); + explicit SSLClient(const std::string &host, int port, X509 *client_cert, + EVP_PKEY *client_key); -namespace duckdb { + ~SSLClient() override; -class CreateTableRelation : public Relation { -public: - CreateTableRelation(shared_ptr child, string schema_name, string table_name); + bool is_valid() const override; - shared_ptr child; - string schema_name; - string table_name; - vector columns; + void set_ca_cert_path(const char *ca_cert_file_path, + const char *ca_cert_dir_path = nullptr); -public: - BoundStatement Bind(Binder &binder) override; - const vector &Columns() override; - string ToString(idx_t depth) override; - bool IsReadOnly() override { - return false; - } -}; + void set_ca_cert_store(X509_STORE *ca_cert_store); -} // namespace duckdb + long get_openssl_verify_result() const; -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/statement/create_statement.hpp -// -// -//===----------------------------------------------------------------------===// + SSL_CTX *ssl_context() const; +private: + bool create_and_connect_socket(Socket &socket, Error &error) override; + void shutdown_ssl(Socket &socket, bool shutdown_gracefully) override; + bool process_socket(const Socket &socket, + std::function callback) override; + bool is_ssl() const override; + bool connect_with_proxy(Socket &sock, Response &res, bool &success, + Error &error); + bool initialize_ssl(Socket &socket, Error &error); + bool load_certs(); + bool verify_host(X509 *server_cert) const; + bool verify_host_with_subject_alt_name(X509 *server_cert) const; + bool verify_host_with_common_name(X509 *server_cert) const; + bool check_host_name(const char *pattern, size_t pattern_len) const; -namespace duckdb { + SSL_CTX *ctx_; + std::mutex ctx_mutex_; + std::once_flag initialize_cert_; -class CreateStatement : public SQLStatement { -public: - CreateStatement(); + std::vector host_components_; - unique_ptr info; + std::string ca_cert_file_path_; + std::string ca_cert_dir_path_; + long verify_result_ = 0; -public: - unique_ptr Copy() const override; + friend class ClientImpl; }; +#endif -} // namespace duckdb - +// ---------------------------------------------------------------------------- +/* + * Implementation + */ +namespace detail { +inline bool is_hex(char c, int &v) { + if (0x20 <= c && isdigit(c)) { + v = c - '0'; + return true; + } else if ('A' <= c && c <= 'F') { + v = c - 'A' + 10; + return true; + } else if ('a' <= c && c <= 'f') { + v = c - 'a' + 10; + return true; + } + return false; +} +inline bool from_hex_to_i(const std::string &s, size_t i, size_t cnt, + int &val) { + if (i >= s.size()) { return false; } -namespace duckdb { + val = 0; + for (; cnt; i++, cnt--) { + if (!s[i]) { return false; } + int v = 0; + if (is_hex(s[i], v)) { + val = val * 16 + v; + } else { + return false; + } + } + return true; +} -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)) { - context.TryBindRelation(*this, this->columns); +inline std::string from_i_to_hex(size_t n) { + const char *charset = "0123456789abcdef"; + std::string ret; + do { + ret = charset[n & 15] + ret; + n >>= 4; + } while (n > 0); + return ret; } -BoundStatement CreateTableRelation::Bind(Binder &binder) { - auto select = make_unique(); - select->node = child->GetQueryNode(); +inline size_t to_utf8(int code, char *buff) { + if (code < 0x0080) { + buff[0] = (code & 0x7F); + return 1; + } else if (code < 0x0800) { + buff[0] = static_cast(0xC0 | ((code >> 6) & 0x1F)); + buff[1] = static_cast(0x80 | (code & 0x3F)); + return 2; + } else if (code < 0xD800) { + buff[0] = static_cast(0xE0 | ((code >> 12) & 0xF)); + buff[1] = static_cast(0x80 | ((code >> 6) & 0x3F)); + buff[2] = static_cast(0x80 | (code & 0x3F)); + return 3; + } else if (code < 0xE000) { // D800 - DFFF is invalid... + return 0; + } else if (code < 0x10000) { + buff[0] = static_cast(0xE0 | ((code >> 12) & 0xF)); + buff[1] = static_cast(0x80 | ((code >> 6) & 0x3F)); + buff[2] = static_cast(0x80 | (code & 0x3F)); + return 3; + } else if (code < 0x110000) { + buff[0] = static_cast(0xF0 | ((code >> 18) & 0x7)); + buff[1] = static_cast(0x80 | ((code >> 12) & 0x3F)); + buff[2] = static_cast(0x80 | ((code >> 6) & 0x3F)); + buff[3] = static_cast(0x80 | (code & 0x3F)); + return 4; + } - CreateStatement stmt; - auto info = make_unique(); - info->schema = schema_name; - info->table = table_name; - info->query = move(select); - info->on_conflict = OnCreateConflict::ERROR_ON_CONFLICT; - stmt.info = move(info); - return binder.Bind((SQLStatement &)stmt); + // NOTREACHED + return 0; } -const vector &CreateTableRelation::Columns() { - return columns; -} +// NOTE: This code came up with the following stackoverflow post: +// https://stackoverflow.com/questions/180947/base64-decode-snippet-in-c +inline std::string base64_encode(const std::string &in) { + static const auto lookup = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -string CreateTableRelation::ToString(idx_t depth) { - string str = RenderWhitespace(depth) + "Create Table\n"; - return str + child->ToString(depth + 1); -} + std::string out; + out.reserve(in.size()); -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/relation/create_view_relation.hpp -// -// -//===----------------------------------------------------------------------===// + int val = 0; + int valb = -6; + for (auto c : in) { + val = (val << 8) + static_cast(c); + valb += 8; + while (valb >= 0) { + out.push_back(lookup[(val >> valb) & 0x3F]); + valb -= 6; + } + } + if (valb > -6) { out.push_back(lookup[((val << 8) >> (valb + 8)) & 0x3F]); } + while (out.size() % 4) { + out.push_back('='); + } + return out; +} -namespace duckdb { +inline bool is_file(const std::string &path) { + struct stat st; + return stat(path.c_str(), &st) >= 0 && S_ISREG(st.st_mode); +} -class CreateViewRelation : public Relation { -public: - CreateViewRelation(shared_ptr child, string view_name, bool replace, bool temporary); +inline bool is_dir(const std::string &path) { + struct stat st; + return stat(path.c_str(), &st) >= 0 && S_ISDIR(st.st_mode); +} - shared_ptr child; - string view_name; - bool replace; - bool temporary; - vector columns; +inline bool is_valid_path(const std::string &path) { + size_t level = 0; + size_t i = 0; -public: - BoundStatement Bind(Binder &binder) override; - const vector &Columns() override; - string ToString(idx_t depth) override; - bool IsReadOnly() override { - return false; - } -}; + // Skip slash + while (i < path.size() && path[i] == '/') { + i++; + } -} // namespace duckdb + while (i < path.size()) { + // Read component + auto beg = i; + while (i < path.size() && path[i] != '/') { + i++; + } + auto len = i - beg; + assert(len > 0); + if (!path.compare(beg, len, ".")) { + ; + } else if (!path.compare(beg, len, "..")) { + if (level == 0) { return false; } + level--; + } else { + level++; + } + // Skip slash + while (i < path.size() && path[i] == '/') { + i++; + } + } + return true; +} +inline std::string encode_query_param(const std::string &value) { + std::ostringstream escaped; + escaped.fill('0'); + escaped << std::hex; -namespace duckdb { + for (auto c : value) { + if (std::isalnum(static_cast(c)) || c == '-' || c == '_' || + c == '.' || c == '!' || c == '~' || c == '*' || c == '\'' || c == '(' || + c == ')') { + escaped << c; + } else { + escaped << std::uppercase; + escaped << '%' << std::setw(2) + << static_cast(static_cast(c)); + escaped << std::nouppercase; + } + } -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) { - context.TryBindRelation(*this, this->columns); + return escaped.str(); } -BoundStatement CreateViewRelation::Bind(Binder &binder) { - auto select = make_unique(); - select->node = child->GetQueryNode(); +inline std::string encode_url(const std::string &s) { + std::string result; - CreateStatement stmt; - auto info = make_unique(); - info->query = move(select); - info->view_name = view_name; - info->temporary = temporary; - info->schema = ""; - info->on_conflict = replace ? OnCreateConflict::REPLACE_ON_CONFLICT : OnCreateConflict::ERROR_ON_CONFLICT; - stmt.info = move(info); - return binder.Bind((SQLStatement &)stmt); + for (size_t i = 0; s[i]; i++) { + switch (s[i]) { + case ' ': result += "%20"; break; + case '+': result += "%2B"; break; + case '\r': result += "%0D"; break; + case '\n': result += "%0A"; break; + case '\'': result += "%27"; break; + case ',': result += "%2C"; break; + // case ':': result += "%3A"; break; // ok? probably... + case ';': result += "%3B"; break; + default: + auto c = static_cast(s[i]); + if (c >= 0x80) { + result += '%'; + char hex[4]; + auto len = snprintf(hex, sizeof(hex) - 1, "%02X", c); + assert(len == 2); + result.append(hex, static_cast(len)); + } else { + result += s[i]; + } + break; + } + } + + return result; } -const vector &CreateViewRelation::Columns() { - return columns; +inline std::string decode_url(const std::string &s, + bool convert_plus_to_space) { + std::string result; + + for (size_t i = 0; i < s.size(); i++) { + if (s[i] == '%' && i + 1 < s.size()) { + if (s[i + 1] == 'u') { + int val = 0; + if (from_hex_to_i(s, i + 2, 4, val)) { + // 4 digits Unicode codes + char buff[4]; + size_t len = to_utf8(val, buff); + if (len > 0) { result.append(buff, len); } + i += 5; // 'u0000' + } else { + result += s[i]; + } + } else { + int val = 0; + if (from_hex_to_i(s, i + 1, 2, val)) { + // 2 digits hex codes + result += static_cast(val); + i += 2; // '00' + } else { + result += s[i]; + } + } + } else if (convert_plus_to_space && s[i] == '+') { + result += ' '; + } else { + result += s[i]; + } + } + + return result; } -string CreateViewRelation::ToString(idx_t depth) { - string str = RenderWhitespace(depth) + "Create View\n"; - return str + child->ToString(depth + 1); +inline void read_file(const std::string &path, std::string &out) { + std::ifstream fs(path, std::ios_base::binary); + fs.seekg(0, std::ios_base::end); + auto size = fs.tellg(); + fs.seekg(0); + out.resize(static_cast(size)); + fs.read(&out[0], static_cast(size)); } -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/relation/delete_relation.hpp -// -// -//===----------------------------------------------------------------------===// +inline std::string file_extension(const std::string &path) { + std::smatch m; + static auto re = std::regex("\\.([a-zA-Z0-9]+)$"); + if (std::regex_search(path, m, re)) { return m[1].str(); } + return std::string(); +} +inline bool is_space_or_tab(char c) { return c == ' ' || c == '\t'; } +inline std::pair trim(const char *b, const char *e, size_t left, + size_t right) { + while (b + left < e && is_space_or_tab(b[left])) { + left++; + } + while (right > 0 && is_space_or_tab(b[right - 1])) { + right--; + } + return std::make_pair(left, right); +} +inline std::string trim_copy(const std::string &s) { + auto r = trim(s.data(), s.data() + s.size(), 0, s.size()); + return s.substr(r.first, r.second - r.first); +} +template void split(const char *b, const char *e, char d, Fn fn) { + size_t i = 0; + size_t beg = 0; + while (e ? (b + i < e) : (b[i] != '\0')) { + if (b[i] == d) { + auto r = trim(b, e, beg, i); + if (r.first < r.second) { fn(&b[r.first], &b[r.second]); } + beg = i + 1; + } + i++; + } -namespace duckdb { + if (i) { + auto r = trim(b, e, beg, i); + if (r.first < r.second) { fn(&b[r.first], &b[r.second]); } + } +} -class DeleteRelation : public Relation { +// NOTE: until the read size reaches `fixed_buffer_size`, use `fixed_buffer` +// to store data. The call can set memory on stack for performance. +class stream_line_reader { public: - DeleteRelation(ClientContext &context, unique_ptr condition, string schema_name, - string table_name); + stream_line_reader(Stream &strm, char *fixed_buffer, size_t fixed_buffer_size) + : strm_(strm), fixed_buffer_(fixed_buffer), + fixed_buffer_size_(fixed_buffer_size) {} - vector columns; - unique_ptr condition; - string schema_name; - string table_name; + const char *ptr() const { + if (glowable_buffer_.empty()) { + return fixed_buffer_; + } else { + return glowable_buffer_.data(); + } + } -public: - BoundStatement Bind(Binder &binder) override; - const vector &Columns() override; - string ToString(idx_t depth) override; - bool IsReadOnly() override { - return false; - } -}; + size_t size() const { + if (glowable_buffer_.empty()) { + return fixed_buffer_used_size_; + } else { + return glowable_buffer_.size(); + } + } -} // namespace duckdb + bool end_with_crlf() const { + auto end = ptr() + size(); + return size() >= 2 && end[-2] == '\r' && end[-1] == '\n'; + } -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/statement/delete_statement.hpp -// -// -//===----------------------------------------------------------------------===// + bool getline() { + fixed_buffer_used_size_ = 0; + glowable_buffer_.clear(); + for (size_t i = 0;; i++) { + char byte; + auto n = strm_.read(&byte, 1); + if (n < 0) { + return false; + } else if (n == 0) { + if (i == 0) { + return false; + } else { + break; + } + } + append(byte); + if (byte == '\n') { break; } + } + return true; + } +private: + void append(char c) { + if (fixed_buffer_used_size_ < fixed_buffer_size_ - 1) { + fixed_buffer_[fixed_buffer_used_size_++] = c; + fixed_buffer_[fixed_buffer_used_size_] = '\0'; + } else { + if (glowable_buffer_.empty()) { + assert(fixed_buffer_[fixed_buffer_used_size_] == '\0'); + glowable_buffer_.assign(fixed_buffer_, fixed_buffer_used_size_); + } + glowable_buffer_ += c; + } + } -namespace duckdb { + Stream &strm_; + char *fixed_buffer_; + const size_t fixed_buffer_size_; + size_t fixed_buffer_used_size_ = 0; + std::string glowable_buffer_; +}; -class DeleteStatement : public SQLStatement { -public: - DeleteStatement(); +inline int close_socket(socket_t sock) { +#ifdef _WIN32 + return closesocket(sock); +#else + return close(sock); +#endif +} - unique_ptr condition; - unique_ptr table; - vector> using_clauses; +template inline ssize_t handle_EINTR(T fn) { + ssize_t res = false; + while (true) { + res = fn(); + if (res < 0 && errno == EINTR) { continue; } + break; + } + return res; +} -public: - unique_ptr Copy() const override; -}; +inline ssize_t select_read(socket_t sock, time_t sec, time_t usec) { +#ifdef CPPHTTPLIB_USE_POLL + struct pollfd pfd_read; + pfd_read.fd = sock; + pfd_read.events = POLLIN; -} // namespace duckdb + auto timeout = static_cast(sec * 1000 + usec / 1000); + return handle_EINTR([&]() { return poll(&pfd_read, 1, timeout); }); +#else +#ifndef _WIN32 + if (sock >= FD_SETSIZE) { return 1; } +#endif + fd_set fds; + FD_ZERO(&fds); + FD_SET(sock, &fds); + timeval tv; + tv.tv_sec = static_cast(sec); + tv.tv_usec = static_cast(usec); + return handle_EINTR([&]() { + return select(static_cast(sock + 1), &fds, nullptr, nullptr, &tv); + }); +#endif +} -namespace duckdb { +inline ssize_t select_write(socket_t sock, time_t sec, time_t usec) { +#ifdef CPPHTTPLIB_USE_POLL + struct pollfd pfd_read; + pfd_read.fd = sock; + pfd_read.events = POLLOUT; -DeleteRelation::DeleteRelation(ClientContext &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)) { - context.TryBindRelation(*this, this->columns); -} + auto timeout = static_cast(sec * 1000 + usec / 1000); -BoundStatement DeleteRelation::Bind(Binder &binder) { - auto basetable = make_unique(); - basetable->schema_name = schema_name; - basetable->table_name = table_name; + return handle_EINTR([&]() { return poll(&pfd_read, 1, timeout); }); +#else +#ifndef _WIN32 + if (sock >= FD_SETSIZE) { return 1; } +#endif - DeleteStatement stmt; - stmt.condition = condition ? condition->Copy() : nullptr; - stmt.table = move(basetable); - return binder.Bind((SQLStatement &)stmt); -} + fd_set fds; + FD_ZERO(&fds); + FD_SET(sock, &fds); -const vector &DeleteRelation::Columns() { - return columns; -} + timeval tv; + tv.tv_sec = static_cast(sec); + tv.tv_usec = static_cast(usec); -string DeleteRelation::ToString(idx_t depth) { - string str = RenderWhitespace(depth) + "DELETE FROM " + table_name; - if (condition) { - str += " WHERE " + condition->ToString(); - } - return str; + return handle_EINTR([&]() { + return select(static_cast(sock + 1), nullptr, &fds, nullptr, &tv); + }); +#endif } -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/relation/distinct_relation.hpp -// -// -//===----------------------------------------------------------------------===// +inline bool wait_until_socket_is_ready(socket_t sock, time_t sec, time_t usec) { +#ifdef CPPHTTPLIB_USE_POLL + struct pollfd pfd_read; + pfd_read.fd = sock; + pfd_read.events = POLLIN | POLLOUT; + + auto timeout = static_cast(sec * 1000 + usec / 1000); + auto poll_res = handle_EINTR([&]() { return poll(&pfd_read, 1, timeout); }); + if (poll_res > 0 && pfd_read.revents & (POLLIN | POLLOUT)) { + int error = 0; + socklen_t len = sizeof(error); + auto res = getsockopt(sock, SOL_SOCKET, SO_ERROR, + reinterpret_cast(&error), &len); + return res >= 0 && !error; + } + return false; +#else +#ifndef _WIN32 + if (sock >= FD_SETSIZE) { return false; } +#endif + fd_set fdsr; + FD_ZERO(&fdsr); + FD_SET(sock, &fdsr); + auto fdsw = fdsr; + auto fdse = fdsr; -namespace duckdb { + timeval tv; + tv.tv_sec = static_cast(sec); + tv.tv_usec = static_cast(usec); -class DistinctRelation : public Relation { -public: - explicit DistinctRelation(shared_ptr child); + auto ret = handle_EINTR([&]() { + return select(static_cast(sock + 1), &fdsr, &fdsw, &fdse, &tv); + }); - shared_ptr child; + if (ret > 0 && (FD_ISSET(sock, &fdsr) || FD_ISSET(sock, &fdsw))) { + int error = 0; + socklen_t len = sizeof(error); + return getsockopt(sock, SOL_SOCKET, SO_ERROR, + reinterpret_cast(&error), &len) >= 0 && + !error; + } + return false; +#endif +} +class SocketStream : public Stream { public: - unique_ptr GetQueryNode() override; + SocketStream(socket_t sock, time_t read_timeout_sec, time_t read_timeout_usec, + time_t write_timeout_sec, time_t write_timeout_usec); + ~SocketStream() override; - const vector &Columns() override; - string ToString(idx_t depth) override; - string GetAlias() override; + bool is_readable() const override; + bool is_writable() const override; + ssize_t read(char *ptr, size_t size) override; + ssize_t write(const char *ptr, size_t size) override; + void get_remote_ip_and_port(std::string &ip, int &port) const override; + socket_t socket() const override; + +private: + socket_t sock_; + time_t read_timeout_sec_; + time_t read_timeout_usec_; + time_t write_timeout_sec_; + time_t write_timeout_usec_; +}; +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +class SSLSocketStream : public Stream { public: - bool InheritsColumnBindings() override { - return true; - } - Relation *ChildRelation() override { - return child.get(); - } + SSLSocketStream(socket_t sock, SSL *ssl, time_t read_timeout_sec, + time_t read_timeout_usec, time_t write_timeout_sec, + time_t write_timeout_usec); + ~SSLSocketStream() override; + + bool is_readable() const override; + bool is_writable() const override; + ssize_t read(char *ptr, size_t size) override; + ssize_t write(const char *ptr, size_t size) override; + void get_remote_ip_and_port(std::string &ip, int &port) const override; + socket_t socket() const override; + +private: + socket_t sock_; + SSL *ssl_; + time_t read_timeout_sec_; + time_t read_timeout_usec_; + time_t write_timeout_sec_; + time_t write_timeout_usec_; }; +#endif -} // namespace duckdb +class BufferStream : public Stream { +public: + BufferStream() = default; + ~BufferStream() override = default; + bool is_readable() const override; + bool is_writable() const override; + ssize_t read(char *ptr, size_t size) override; + ssize_t write(const char *ptr, size_t size) override; + void get_remote_ip_and_port(std::string &ip, int &port) const override; + socket_t socket() const override; + const std::string &get_buffer() const; +private: + std::string buffer; + size_t position = 0; +}; -namespace duckdb { +inline bool keep_alive(socket_t sock, time_t keep_alive_timeout_sec) { + using namespace std::chrono; + auto start = steady_clock::now(); + while (true) { + auto val = select_read(sock, 0, 10000); + if (val < 0) { + return false; + } else if (val == 0) { + auto current = steady_clock::now(); + auto duration = duration_cast(current - start); + auto timeout = keep_alive_timeout_sec * 1000; + if (duration.count() > timeout) { return false; } + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } else { + return true; + } + } +} -DistinctRelation::DistinctRelation(shared_ptr child_p) - : Relation(child_p->context, RelationType::DISTINCT_RELATION), child(move(child_p)) { - vector dummy_columns; - context.TryBindRelation(*this, dummy_columns); +template +inline bool +process_server_socket_core(socket_t sock, size_t keep_alive_max_count, + time_t keep_alive_timeout_sec, T callback) { + assert(keep_alive_max_count > 0); + auto ret = false; + auto count = keep_alive_max_count; + while (count > 0 && keep_alive(sock, keep_alive_timeout_sec)) { + auto close_connection = count == 1; + auto connection_closed = false; + ret = callback(close_connection, connection_closed); + if (!ret || connection_closed) { break; } + count--; + } + return ret; } -unique_ptr DistinctRelation::GetQueryNode() { - auto child_node = child->GetQueryNode(); - child_node->modifiers.push_back(make_unique()); - return child_node; +template +inline bool +process_server_socket(socket_t sock, size_t keep_alive_max_count, + time_t keep_alive_timeout_sec, time_t read_timeout_sec, + time_t read_timeout_usec, time_t write_timeout_sec, + time_t write_timeout_usec, T callback) { + return process_server_socket_core( + sock, keep_alive_max_count, keep_alive_timeout_sec, + [&](bool close_connection, bool &connection_closed) { + SocketStream strm(sock, read_timeout_sec, read_timeout_usec, + write_timeout_sec, write_timeout_usec); + return callback(strm, close_connection, connection_closed); + }); } -string DistinctRelation::GetAlias() { - return child->GetAlias(); +template +inline bool process_client_socket(socket_t sock, time_t read_timeout_sec, + time_t read_timeout_usec, + time_t write_timeout_sec, + time_t write_timeout_usec, T callback) { + SocketStream strm(sock, read_timeout_sec, read_timeout_usec, + write_timeout_sec, write_timeout_usec); + return callback(strm); } -const vector &DistinctRelation::Columns() { - return child->Columns(); +inline int shutdown_socket(socket_t sock) { +#ifdef _WIN32 + return shutdown(sock, SD_BOTH); +#else + return shutdown(sock, SHUT_RDWR); +#endif } -string DistinctRelation::ToString(idx_t depth) { - string str = RenderWhitespace(depth) + "Distinct\n"; - return str + child->ToString(depth + 1); - ; +template +socket_t create_socket(const char *host, int port, int socket_flags, + bool tcp_nodelay, SocketOptions socket_options, + BindOrConnect bind_or_connect) { + // Get address info + struct addrinfo hints; + struct addrinfo *result; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = socket_flags; + hints.ai_protocol = 0; + + auto service = std::to_string(port); + + if (getaddrinfo(host, service.c_str(), &hints, &result)) { +#ifdef __linux__ + res_init(); +#endif + return INVALID_SOCKET; + } + + for (auto rp = result; rp; rp = rp->ai_next) { + // Create a socket +#ifdef _WIN32 + auto sock = WSASocketW(rp->ai_family, rp->ai_socktype, rp->ai_protocol, + nullptr, 0, WSA_FLAG_NO_HANDLE_INHERIT); + /** + * Since the WSA_FLAG_NO_HANDLE_INHERIT is only supported on Windows 7 SP1 + * and above the socket creation fails on older Windows Systems. + * + * Let's try to create a socket the old way in this case. + * + * Reference: + * https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasocketa + * + * WSA_FLAG_NO_HANDLE_INHERIT: + * This flag is supported on Windows 7 with SP1, Windows Server 2008 R2 with + * SP1, and later + * + */ + if (sock == INVALID_SOCKET) { + sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + } +#else + auto sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); +#endif + if (sock == INVALID_SOCKET) { continue; } + +#ifndef _WIN32 + if (fcntl(sock, F_SETFD, FD_CLOEXEC) == -1) { continue; } +#endif + + if (tcp_nodelay) { + int yes = 1; + setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast(&yes), + sizeof(yes)); + } + + if (socket_options) { socket_options(sock); } + + if (rp->ai_family == AF_INET6) { + int no = 0; + setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast(&no), + sizeof(no)); + } + + // bind or connect + if (bind_or_connect(sock, *rp)) { + freeaddrinfo(result); + return sock; + } + + close_socket(sock); + } + + freeaddrinfo(result); + return INVALID_SOCKET; } -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/relation/explain_relation.hpp -// -// -//===----------------------------------------------------------------------===// +inline void set_nonblocking(socket_t sock, bool nonblocking) { +#ifdef _WIN32 + auto flags = nonblocking ? 1UL : 0UL; + ioctlsocket(sock, FIONBIO, &flags); +#else + auto flags = fcntl(sock, F_GETFL, 0); + fcntl(sock, F_SETFL, + nonblocking ? (flags | O_NONBLOCK) : (flags & (~O_NONBLOCK))); +#endif +} +inline bool is_connection_error() { +#ifdef _WIN32 + return WSAGetLastError() != WSAEWOULDBLOCK; +#else + return errno != EINPROGRESS; +#endif +} +inline bool bind_ip_address(socket_t sock, const char *host) { + struct addrinfo hints; + struct addrinfo *result; + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = 0; + if (getaddrinfo(host, "0", &hints, &result)) { return false; } -namespace duckdb { + auto ret = false; + for (auto rp = result; rp; rp = rp->ai_next) { + const auto &ai = *rp; + if (!::bind(sock, ai.ai_addr, static_cast(ai.ai_addrlen))) { + ret = true; + break; + } + } -class ExplainRelation : public Relation { -public: - explicit ExplainRelation(shared_ptr child); + freeaddrinfo(result); + return ret; +} - shared_ptr child; - vector columns; +#if !defined _WIN32 && !defined ANDROID +#define USE_IF2IP +#endif -public: - BoundStatement Bind(Binder &binder) override; - const vector &Columns() override; - string ToString(idx_t depth) override; - bool IsReadOnly() override { - return false; - } -}; +#ifdef USE_IF2IP +inline std::string if2ip(const std::string &ifn) { + struct ifaddrs *ifap; + getifaddrs(&ifap); + for (auto ifa = ifap; ifa; ifa = ifa->ifa_next) { + if (ifa->ifa_addr && ifn == ifa->ifa_name) { + if (ifa->ifa_addr->sa_family == AF_INET) { + auto sa = reinterpret_cast(ifa->ifa_addr); + char buf[INET_ADDRSTRLEN]; + if (inet_ntop(AF_INET, &sa->sin_addr, buf, INET_ADDRSTRLEN)) { + freeifaddrs(ifap); + return std::string(buf, INET_ADDRSTRLEN); + } + } + } + } + freeifaddrs(ifap); + return std::string(); +} +#endif -} // namespace duckdb +inline socket_t create_client_socket(const char *host, int port, + bool tcp_nodelay, + SocketOptions socket_options, + time_t timeout_sec, time_t timeout_usec, + const std::string &intf, Error &error) { + auto sock = create_socket( + host, port, 0, tcp_nodelay, std::move(socket_options), + [&](socket_t sock, struct addrinfo &ai) -> bool { + if (!intf.empty()) { +#ifdef USE_IF2IP + auto ip = if2ip(intf); + if (ip.empty()) { ip = intf; } + if (!bind_ip_address(sock, ip.c_str())) { + error = Error::BindIPAddress; + return false; + } +#endif + } + set_nonblocking(sock, true); + auto ret = + ::connect(sock, ai.ai_addr, static_cast(ai.ai_addrlen)); + if (ret < 0) { + if (is_connection_error() || + !wait_until_socket_is_ready(sock, timeout_sec, timeout_usec)) { + close_socket(sock); + error = Error::Connection; + return false; + } + } + set_nonblocking(sock, false); + error = Error::Success; + return true; + }); + if (sock != INVALID_SOCKET) { + error = Error::Success; + } else { + if (error == Error::Success) { error = Error::Connection; } + } + return sock; +} -namespace duckdb { +inline void get_remote_ip_and_port(const struct sockaddr_storage &addr, + socklen_t addr_len, std::string &ip, + int &port) { + if (addr.ss_family == AF_INET) { + port = ntohs(reinterpret_cast(&addr)->sin_port); + } else if (addr.ss_family == AF_INET6) { + port = + ntohs(reinterpret_cast(&addr)->sin6_port); + } -ExplainRelation::ExplainRelation(shared_ptr child_p) - : Relation(child_p->context, RelationType::EXPLAIN_RELATION), child(move(child_p)) { - context.TryBindRelation(*this, this->columns); + std::array ipstr{}; + if (!getnameinfo(reinterpret_cast(&addr), addr_len, + ipstr.data(), static_cast(ipstr.size()), nullptr, + 0, NI_NUMERICHOST)) { + ip = ipstr.data(); + } } -BoundStatement ExplainRelation::Bind(Binder &binder) { - auto select = make_unique(); - select->node = child->GetQueryNode(); - ExplainStatement explain(move(select)); - return binder.Bind((SQLStatement &)explain); +inline void get_remote_ip_and_port(socket_t sock, std::string &ip, int &port) { + struct sockaddr_storage addr; + socklen_t addr_len = sizeof(addr); + + if (!getpeername(sock, reinterpret_cast(&addr), + &addr_len)) { + get_remote_ip_and_port(addr, addr_len, ip, port); + } } -const vector &ExplainRelation::Columns() { - return columns; +inline constexpr unsigned int str2tag_core(const char *s, size_t l, + unsigned int h) { + return (l == 0) ? h + : str2tag_core(s + 1, l - 1, + (h * 33) ^ static_cast(*s)); +} + +inline unsigned int str2tag(const std::string &s) { + return str2tag_core(s.data(), s.size(), 0); +} + +namespace udl { + +inline constexpr unsigned int operator"" _(const char *s, size_t l) { + return str2tag_core(s, l, 0); +} + +} // namespace udl + +inline const char * +find_content_type(const std::string &path, + const std::map &user_data) { + auto ext = file_extension(path); + + auto it = user_data.find(ext); + if (it != user_data.end()) { return it->second.c_str(); } + + using udl::operator"" _; + + switch (str2tag(ext)) { + default: return nullptr; + case "css"_: return "text/css"; + case "csv"_: return "text/csv"; + case "txt"_: return "text/plain"; + case "vtt"_: return "text/vtt"; + case "htm"_: + case "html"_: return "text/html"; + + case "apng"_: return "image/apng"; + case "avif"_: return "image/avif"; + case "bmp"_: return "image/bmp"; + case "gif"_: return "image/gif"; + case "png"_: return "image/png"; + case "svg"_: return "image/svg+xml"; + case "webp"_: return "image/webp"; + case "ico"_: return "image/x-icon"; + case "tif"_: return "image/tiff"; + case "tiff"_: return "image/tiff"; + case "jpg"_: + case "jpeg"_: return "image/jpeg"; + + case "mp4"_: return "video/mp4"; + case "mpeg"_: return "video/mpeg"; + case "webm"_: return "video/webm"; + + case "mp3"_: return "audio/mp3"; + case "mpga"_: return "audio/mpeg"; + case "weba"_: return "audio/webm"; + case "wav"_: return "audio/wave"; + + case "otf"_: return "font/otf"; + case "ttf"_: return "font/ttf"; + case "woff"_: return "font/woff"; + case "woff2"_: return "font/woff2"; + + case "7z"_: return "application/x-7z-compressed"; + case "atom"_: return "application/atom+xml"; + case "pdf"_: return "application/pdf"; + case "js"_: + case "mjs"_: return "application/javascript"; + case "json"_: return "application/json"; + case "rss"_: return "application/rss+xml"; + case "tar"_: return "application/x-tar"; + case "xht"_: + case "xhtml"_: return "application/xhtml+xml"; + case "xslt"_: return "application/xslt+xml"; + case "xml"_: return "application/xml"; + case "gz"_: return "application/gzip"; + case "zip"_: return "application/zip"; + case "wasm"_: return "application/wasm"; + } } -string ExplainRelation::ToString(idx_t depth) { - string str = RenderWhitespace(depth) + "Explain\n"; - return str + child->ToString(depth + 1); +inline const char *status_message(int status) { + switch (status) { + case 100: return "Continue"; + case 101: return "Switching Protocol"; + case 102: return "Processing"; + case 103: return "Early Hints"; + case 200: return "OK"; + case 201: return "Created"; + case 202: return "Accepted"; + case 203: return "Non-Authoritative Information"; + case 204: return "No Content"; + case 205: return "Reset Content"; + case 206: return "Partial Content"; + case 207: return "Multi-Status"; + case 208: return "Already Reported"; + case 226: return "IM Used"; + case 300: return "Multiple Choice"; + case 301: return "Moved Permanently"; + case 302: return "Found"; + case 303: return "See Other"; + case 304: return "Not Modified"; + case 305: return "Use Proxy"; + case 306: return "unused"; + case 307: return "Temporary Redirect"; + case 308: return "Permanent Redirect"; + case 400: return "Bad Request"; + case 401: return "Unauthorized"; + case 402: return "Payment Required"; + case 403: return "Forbidden"; + case 404: return "Not Found"; + case 405: return "Method Not Allowed"; + case 406: return "Not Acceptable"; + case 407: return "Proxy Authentication Required"; + case 408: return "Request Timeout"; + case 409: return "Conflict"; + case 410: return "Gone"; + case 411: return "Length Required"; + case 412: return "Precondition Failed"; + case 413: return "Payload Too Large"; + case 414: return "URI Too Long"; + case 415: return "Unsupported Media Type"; + case 416: return "Range Not Satisfiable"; + case 417: return "Expectation Failed"; + case 418: return "I'm a teapot"; + case 421: return "Misdirected Request"; + case 422: return "Unprocessable Entity"; + case 423: return "Locked"; + case 424: return "Failed Dependency"; + case 425: return "Too Early"; + case 426: return "Upgrade Required"; + case 428: return "Precondition Required"; + case 429: return "Too Many Requests"; + case 431: return "Request Header Fields Too Large"; + case 451: return "Unavailable For Legal Reasons"; + case 501: return "Not Implemented"; + case 502: return "Bad Gateway"; + case 503: return "Service Unavailable"; + case 504: return "Gateway Timeout"; + case 505: return "HTTP Version Not Supported"; + case 506: return "Variant Also Negotiates"; + case 507: return "Insufficient Storage"; + case 508: return "Loop Detected"; + case 510: return "Not Extended"; + case 511: return "Network Authentication Required"; + + default: + case 500: return "Internal Server Error"; + } } -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/relation/filter_relation.hpp -// -// -//===----------------------------------------------------------------------===// +inline bool can_compress_content_type(const std::string &content_type) { + return (!content_type.find("text/") && content_type != "text/event-stream") || + content_type == "image/svg+xml" || + content_type == "application/javascript" || + content_type == "application/json" || + content_type == "application/xml" || + content_type == "application/xhtml+xml"; +} +enum class EncodingType { None = 0, Gzip, Brotli }; +inline EncodingType encoding_type(const Request &req, const Response &res) { + auto ret = + detail::can_compress_content_type(res.get_header_value("Content-Type")); + if (!ret) { return EncodingType::None; } + const auto &s = req.get_header_value("Accept-Encoding"); + (void)(s); +#ifdef CPPHTTPLIB_BROTLI_SUPPORT + // TODO: 'Accept-Encoding' has br, not br;q=0 + ret = s.find("br") != std::string::npos; + if (ret) { return EncodingType::Brotli; } +#endif +#ifdef CPPHTTPLIB_ZLIB_SUPPORT + // TODO: 'Accept-Encoding' has gzip, not gzip;q=0 + ret = s.find("gzip") != std::string::npos; + if (ret) { return EncodingType::Gzip; } +#endif -namespace duckdb { + return EncodingType::None; +} -class FilterRelation : public Relation { +class compressor { public: - FilterRelation(shared_ptr child, unique_ptr condition); + virtual ~compressor(){}; - unique_ptr condition; - shared_ptr child; + typedef std::function Callback; + virtual bool compress(const char *data, size_t data_length, bool last, + Callback callback) = 0; +}; +class decompressor { public: - unique_ptr GetQueryNode() override; + virtual ~decompressor() {} - const vector &Columns() override; - string ToString(idx_t depth) override; - string GetAlias() override; + virtual bool is_valid() const = 0; + + typedef std::function Callback; + virtual bool decompress(const char *data, size_t data_length, + Callback callback) = 0; +}; +class nocompressor : public compressor { public: - bool InheritsColumnBindings() override { - return true; - } - Relation *ChildRelation() override { - return child.get(); - } + ~nocompressor(){}; + + bool compress(const char *data, size_t data_length, bool /*last*/, + Callback callback) override { + if (!data_length) { return true; } + return callback(data, data_length); + } }; -} // namespace duckdb +#ifdef CPPHTTPLIB_ZLIB_SUPPORT +class gzip_compressor : public compressor { +public: + gzip_compressor() { + std::memset(&strm_, 0, sizeof(strm_)); + strm_.zalloc = Z_NULL; + strm_.zfree = Z_NULL; + strm_.opaque = Z_NULL; + + is_valid_ = deflateInit2(&strm_, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 31, 8, + Z_DEFAULT_STRATEGY) == Z_OK; + } + ~gzip_compressor() { deflateEnd(&strm_); } + bool compress(const char *data, size_t data_length, bool last, + Callback callback) override { + assert(is_valid_); -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/query_node/set_operation_node.hpp -// -// -//===----------------------------------------------------------------------===// + auto flush = last ? Z_FINISH : Z_NO_FLUSH; + strm_.avail_in = static_cast(data_length); + strm_.next_in = const_cast(reinterpret_cast(data)); + int ret = Z_OK; -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/enums/set_operation_type.hpp -// -// -//===----------------------------------------------------------------------===// + std::array buff{}; + do { + strm_.avail_out = buff.size(); + strm_.next_out = reinterpret_cast(buff.data()); + ret = deflate(&strm_, flush); + if (ret == Z_STREAM_ERROR) { return false; } + if (!callback(buff.data(), buff.size() - strm_.avail_out)) { + return false; + } + } while (strm_.avail_out == 0); + assert((last && ret == Z_STREAM_END) || (!last && ret == Z_OK)); + assert(strm_.avail_in == 0); + return true; + } +private: + bool is_valid_ = false; + z_stream strm_; +}; -namespace duckdb { +class gzip_decompressor : public decompressor { +public: + gzip_decompressor() { + std::memset(&strm_, 0, sizeof(strm_)); + strm_.zalloc = Z_NULL; + strm_.zfree = Z_NULL; + strm_.opaque = Z_NULL; + + // 15 is the value of wbits, which should be at the maximum possible value + // to ensure that any gzip stream can be decoded. The offset of 32 specifies + // that the stream type should be automatically detected either gzip or + // deflate. + is_valid_ = inflateInit2(&strm_, 32 + 15) == Z_OK; + } -enum class SetOperationType : uint8_t { NONE = 0, UNION = 1, EXCEPT = 2, INTERSECT = 3 }; -} + ~gzip_decompressor() { inflateEnd(&strm_); } + bool is_valid() const override { return is_valid_; } + bool decompress(const char *data, size_t data_length, + Callback callback) override { + assert(is_valid_); + int ret = Z_OK; + strm_.avail_in = static_cast(data_length); + strm_.next_in = const_cast(reinterpret_cast(data)); -namespace duckdb { + std::array buff{}; + while (strm_.avail_in > 0) { + strm_.avail_out = buff.size(); + strm_.next_out = reinterpret_cast(buff.data()); -class SetOperationNode : public QueryNode { -public: - SetOperationNode() : QueryNode(QueryNodeType::SET_OPERATION_NODE) { - } + ret = inflate(&strm_, Z_NO_FLUSH); + assert(ret != Z_STREAM_ERROR); + switch (ret) { + case Z_NEED_DICT: + case Z_DATA_ERROR: + case Z_MEM_ERROR: inflateEnd(&strm_); return false; + } - //! The type of set operation - SetOperationType setop_type = SetOperationType::NONE; - //! The left side of the set operation - unique_ptr left; - //! The right side of the set operation - unique_ptr right; + if (!callback(buff.data(), buff.size() - strm_.avail_out)) { + return false; + } + } - const vector> &GetSelectList() const override { - return left->GetSelectList(); - } + return ret == Z_OK || ret == Z_STREAM_END; + } + +private: + bool is_valid_ = false; + z_stream strm_; +}; +#endif +#ifdef CPPHTTPLIB_BROTLI_SUPPORT +class brotli_compressor : public compressor { public: - bool Equals(const QueryNode *other) const override; - //! Create a copy of this SelectNode - unique_ptr Copy() override; + brotli_compressor() { + state_ = BrotliEncoderCreateInstance(nullptr, nullptr, nullptr); + } - //! Serializes a SelectNode to a stand-alone binary blob - void Serialize(Serializer &serializer) override; - //! Deserializes a blob back into a SelectNode - static unique_ptr Deserialize(Deserializer &source); -}; + ~brotli_compressor() { BrotliEncoderDestroyInstance(state_); } -} // namespace duckdb + bool compress(const char *data, size_t data_length, bool last, + Callback callback) override { + std::array buff{}; -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/expression/conjunction_expression.hpp -// -// -//===----------------------------------------------------------------------===// + auto operation = last ? BROTLI_OPERATION_FINISH : BROTLI_OPERATION_PROCESS; + auto available_in = data_length; + auto next_in = reinterpret_cast(data); + for (;;) { + if (last) { + if (BrotliEncoderIsFinished(state_)) { break; } + } else { + if (!available_in) { break; } + } + auto available_out = buff.size(); + auto next_out = buff.data(); + if (!BrotliEncoderCompressStream(state_, operation, &available_in, + &next_in, &available_out, &next_out, + nullptr)) { + return false; + } + auto output_bytes = buff.size() - available_out; + if (output_bytes) { + callback(reinterpret_cast(buff.data()), output_bytes); + } + } + return true; + } -namespace duckdb { +private: + BrotliEncoderState *state_ = nullptr; +}; -//! Represents a conjunction (AND/OR) -class ConjunctionExpression : public ParsedExpression { +class brotli_decompressor : public decompressor { public: - explicit ConjunctionExpression(ExpressionType type); - ConjunctionExpression(ExpressionType type, vector> children); - ConjunctionExpression(ExpressionType type, unique_ptr left, unique_ptr right); + brotli_decompressor() { + decoder_s = BrotliDecoderCreateInstance(0, 0, 0); + decoder_r = decoder_s ? BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT + : BROTLI_DECODER_RESULT_ERROR; + } - vector> children; + ~brotli_decompressor() { + if (decoder_s) { BrotliDecoderDestroyInstance(decoder_s); } + } -public: - void AddExpression(unique_ptr expr); + bool is_valid() const override { return decoder_s; } - string ToString() const override; + bool decompress(const char *data, size_t data_length, + Callback callback) override { + if (decoder_r == BROTLI_DECODER_RESULT_SUCCESS || + decoder_r == BROTLI_DECODER_RESULT_ERROR) { + return 0; + } - static bool Equals(const ConjunctionExpression *a, const ConjunctionExpression *b); + const uint8_t *next_in = (const uint8_t *)data; + size_t avail_in = data_length; + size_t total_out; - unique_ptr Copy() const override; + decoder_r = BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT; - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(ExpressionType type, Deserializer &source); -}; -} // namespace duckdb + std::array buff{}; + while (decoder_r == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) { + char *next_out = buff.data(); + size_t avail_out = buff.size(); + decoder_r = BrotliDecoderDecompressStream( + decoder_s, &avail_in, &next_in, &avail_out, + reinterpret_cast(&next_out), &total_out); + if (decoder_r == BROTLI_DECODER_RESULT_ERROR) { return false; } -namespace duckdb { + if (!callback(buff.data(), buff.size() - avail_out)) { return false; } + } -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)) { - vector dummy_columns; - context.TryBindRelation(*this, dummy_columns); -} + return decoder_r == BROTLI_DECODER_RESULT_SUCCESS || + decoder_r == BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT; + } -unique_ptr FilterRelation::GetQueryNode() { - auto child_ptr = child.get(); - while (child_ptr->InheritsColumnBindings()) { - child_ptr = child_ptr->ChildRelation(); - } - if (child_ptr->type == RelationType::JOIN_RELATION) { - // child node is a join: push filter into WHERE clause of select node - auto child_node = child->GetQueryNode(); - D_ASSERT(child_node->type == QueryNodeType::SELECT_NODE); - auto &select_node = (SelectNode &)*child_node; - if (!select_node.where_clause) { - select_node.where_clause = condition->Copy(); - } else { - select_node.where_clause = make_unique( - ExpressionType::CONJUNCTION_AND, move(select_node.where_clause), condition->Copy()); - } - return child_node; - } else { - auto result = make_unique(); - result->select_list.push_back(make_unique()); - result->from_table = child->GetTableRef(); - result->where_clause = condition->Copy(); - return move(result); - } -} +private: + BrotliDecoderResult decoder_r; + BrotliDecoderState *decoder_s = nullptr; +}; +#endif -string FilterRelation::GetAlias() { - return child->GetAlias(); +inline bool has_header(const Headers &headers, const char *key) { + return headers.find(key) != headers.end(); } -const vector &FilterRelation::Columns() { - return child->Columns(); +inline const char *get_header_value(const Headers &headers, const char *key, + size_t id = 0, const char *def = nullptr) { + auto rng = headers.equal_range(key); + auto it = rng.first; + std::advance(it, static_cast(id)); + if (it != rng.second) { return it->second.c_str(); } + return def; } -string FilterRelation::ToString(idx_t depth) { - string str = RenderWhitespace(depth) + "Filter [" + condition->ToString() + "]\n"; - return str + child->ToString(depth + 1); +template +inline T get_header_value(const Headers & /*headers*/, const char * /*key*/, + size_t /*id*/ = 0, uint64_t /*def*/ = 0) {} + +template <> +inline uint64_t get_header_value(const Headers &headers, + const char *key, size_t id, + uint64_t def) { + auto rng = headers.equal_range(key); + auto it = rng.first; + std::advance(it, static_cast(id)); + if (it != rng.second) { + return std::strtoull(it->second.data(), nullptr, 10); + } + return def; } -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/relation/insert_relation.hpp -// -// -//===----------------------------------------------------------------------===// +template +inline bool parse_header(const char *beg, const char *end, T fn) { + // Skip trailing spaces and tabs. + while (beg < end && is_space_or_tab(end[-1])) { + end--; + } + auto p = beg; + while (p < end && *p != ':') { + p++; + } + if (p == end) { return false; } + auto key_end = p; + if (*p++ != ':') { return false; } -namespace duckdb { + while (p < end && is_space_or_tab(*p)) { + p++; + } -class InsertRelation : public Relation { -public: - InsertRelation(shared_ptr child, string schema_name, string table_name); + if (p < end) { + fn(std::string(beg, key_end), decode_url(std::string(p, end), false)); + return true; + } - shared_ptr child; - string schema_name; - string table_name; - vector columns; + return false; +} -public: - BoundStatement Bind(Binder &binder) override; - const vector &Columns() override; - string ToString(idx_t depth) override; - bool IsReadOnly() override { - return false; - } -}; +inline bool read_headers(Stream &strm, Headers &headers) { + const auto bufsiz = 2048; + char buf[bufsiz]; + stream_line_reader line_reader(strm, buf, bufsiz); -} // namespace duckdb + for (;;) { + if (!line_reader.getline()) { return false; } -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/statement/insert_statement.hpp -// -// -//===----------------------------------------------------------------------===// + // Check if the line ends with CRLF. + if (line_reader.end_with_crlf()) { + // Blank line indicates end of headers. + if (line_reader.size() == 2) { break; } + } else { + continue; // Skip invalid line. + } + // Exclude CRLF + auto end = line_reader.ptr() + line_reader.size() - 2; + parse_header(line_reader.ptr(), end, + [&](std::string &&key, std::string &&val) { + headers.emplace(std::move(key), std::move(val)); + }); + } + return true; +} +inline bool read_content_with_length(Stream &strm, uint64_t len, + Progress progress, + ContentReceiverWithProgress out) { + char buf[CPPHTTPLIB_RECV_BUFSIZ]; + uint64_t r = 0; + while (r < len) { + auto read_len = static_cast(len - r); + auto n = strm.read(buf, (std::min)(read_len, CPPHTTPLIB_RECV_BUFSIZ)); + if (n <= 0) { return false; } -namespace duckdb { + if (!out(buf, static_cast(n), r, len)) { return false; } + r += static_cast(n); -class InsertStatement : public SQLStatement { -public: - InsertStatement(); + if (progress) { + if (!progress(r, len)) { return false; } + } + } - //! 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; - -public: - unique_ptr Copy() const override; -}; + return true; +} -} // namespace duckdb +inline void skip_content_with_length(Stream &strm, uint64_t len) { + char buf[CPPHTTPLIB_RECV_BUFSIZ]; + uint64_t r = 0; + while (r < len) { + auto read_len = static_cast(len - r); + auto n = strm.read(buf, (std::min)(read_len, CPPHTTPLIB_RECV_BUFSIZ)); + if (n <= 0) { return; } + r += static_cast(n); + } +} +inline bool read_content_without_length(Stream &strm, + ContentReceiverWithProgress out) { + char buf[CPPHTTPLIB_RECV_BUFSIZ]; + uint64_t r = 0; + for (;;) { + auto n = strm.read(buf, CPPHTTPLIB_RECV_BUFSIZ); + if (n < 0) { + return false; + } else if (n == 0) { + return true; + } + if (!out(buf, static_cast(n), r, 0)) { return false; } + r += static_cast(n); + } + return true; +} +inline bool read_content_chunked(Stream &strm, + ContentReceiverWithProgress out) { + const auto bufsiz = 16; + char buf[bufsiz]; + stream_line_reader line_reader(strm, buf, bufsiz); -namespace duckdb { + if (!line_reader.getline()) { return false; } -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)) { - context.TryBindRelation(*this, this->columns); -} + unsigned long chunk_len; + while (true) { + char *end_ptr; -BoundStatement InsertRelation::Bind(Binder &binder) { - InsertStatement stmt; - auto select = make_unique(); - select->node = child->GetQueryNode(); + chunk_len = std::strtoul(line_reader.ptr(), &end_ptr, 16); - stmt.schema = schema_name; - stmt.table = table_name; - stmt.select_statement = move(select); - return binder.Bind((SQLStatement &)stmt); -} + if (end_ptr == line_reader.ptr()) { return false; } + if (chunk_len == ULONG_MAX) { return false; } -const vector &InsertRelation::Columns() { - return columns; -} + if (chunk_len == 0) { break; } -string InsertRelation::ToString(idx_t depth) { - string str = RenderWhitespace(depth) + "Insert\n"; - return str + child->ToString(depth + 1); -} + if (!read_content_with_length(strm, chunk_len, nullptr, out)) { + return false; + } -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/relation/join_relation.hpp -// -// -//===----------------------------------------------------------------------===// + if (!line_reader.getline()) { return false; } + if (strcmp(line_reader.ptr(), "\r\n")) { break; } + if (!line_reader.getline()) { return false; } + } + if (chunk_len == 0) { + // Reader terminator after chunks + if (!line_reader.getline() || strcmp(line_reader.ptr(), "\r\n")) + return false; + } + return true; +} -namespace duckdb { +inline bool is_chunked_transfer_encoding(const Headers &headers) { + return !strcasecmp(get_header_value(headers, "Transfer-Encoding", 0, ""), + "chunked"); +} -class JoinRelation : public Relation { -public: - JoinRelation(shared_ptr left, shared_ptr right, unique_ptr condition, - JoinType type); - JoinRelation(shared_ptr left, shared_ptr right, vector using_columns, JoinType type); +template +bool prepare_content_receiver(T &x, int &status, + ContentReceiverWithProgress receiver, + bool decompress, U callback) { + if (decompress) { + std::string encoding = x.get_header_value("Content-Encoding"); + std::unique_ptr decompressor; - shared_ptr left; - shared_ptr right; - unique_ptr condition; - vector using_columns; - JoinType join_type; - vector columns; + if (encoding.find("gzip") != std::string::npos || + encoding.find("deflate") != std::string::npos) { +#ifdef CPPHTTPLIB_ZLIB_SUPPORT + decompressor = detail::make_unique(); +#else + status = 415; + return false; +#endif + } else if (encoding.find("br") != std::string::npos) { +#ifdef CPPHTTPLIB_BROTLI_SUPPORT + decompressor = detail::make_unique(); +#else + status = 415; + return false; +#endif + } -public: - unique_ptr GetQueryNode() override; + if (decompressor) { + if (decompressor->is_valid()) { + ContentReceiverWithProgress out = [&](const char *buf, size_t n, + uint64_t off, uint64_t len) { + return decompressor->decompress(buf, n, + [&](const char *buf, size_t n) { + return receiver(buf, n, off, len); + }); + }; + return callback(std::move(out)); + } else { + status = 500; + return false; + } + } + } - const vector &Columns() override; - string ToString(idx_t depth) override; + ContentReceiverWithProgress out = [&](const char *buf, size_t n, uint64_t off, + uint64_t len) { + return receiver(buf, n, off, len); + }; + return callback(std::move(out)); +} - unique_ptr GetTableRef() override; -}; +template +bool read_content(Stream &strm, T &x, size_t payload_max_length, int &status, + Progress progress, ContentReceiverWithProgress receiver, + bool decompress) { + return prepare_content_receiver( + x, status, std::move(receiver), decompress, + [&](const ContentReceiverWithProgress &out) { + auto ret = true; + auto exceed_payload_max_length = false; + + if (is_chunked_transfer_encoding(x.headers)) { + ret = read_content_chunked(strm, out); + } else if (!has_header(x.headers, "Content-Length")) { + ret = read_content_without_length(strm, out); + } else { + auto len = get_header_value(x.headers, "Content-Length"); + if (len > payload_max_length) { + exceed_payload_max_length = true; + skip_content_with_length(strm, len); + ret = false; + } else if (len > 0) { + ret = read_content_with_length(strm, len, std::move(progress), out); + } + } -} // namespace duckdb + if (!ret) { status = exceed_payload_max_length ? 413 : 400; } + return ret; + }); +} +template +inline ssize_t write_headers(Stream &strm, const T &info, + const Headers &headers) { + ssize_t write_len = 0; + for (const auto &x : info.headers) { + if (x.first == "EXCEPTION_WHAT") { continue; } + auto len = + strm.write_format("%s: %s\r\n", x.first.c_str(), x.second.c_str()); + if (len < 0) { return len; } + write_len += len; + } + for (const auto &x : headers) { + auto len = + strm.write_format("%s: %s\r\n", x.first.c_str(), x.second.c_str()); + if (len < 0) { return len; } + write_len += len; + } + auto len = strm.write("\r\n"); + if (len < 0) { return len; } + write_len += len; + return write_len; +} + +inline bool write_data(Stream &strm, const char *d, size_t l) { + size_t offset = 0; + while (offset < l) { + auto length = strm.write(d + offset, l - offset); + if (length < 0) { return false; } + offset += static_cast(length); + } + return true; +} +template +inline bool write_content(Stream &strm, const ContentProvider &content_provider, + size_t offset, size_t length, T is_shutting_down, + Error &error) { + size_t end_offset = offset + length; + auto ok = true; + DataSink data_sink; + + data_sink.write = [&](const char *d, size_t l) { + if (ok) { + if (write_data(strm, d, l)) { + offset += l; + } else { + ok = false; + } + } + }; + data_sink.is_writable = [&](void) { return ok && strm.is_writable(); }; -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/tableref/joinref.hpp -// -// -//===----------------------------------------------------------------------===// + while (offset < end_offset && !is_shutting_down()) { + if (!content_provider(offset, end_offset - offset, data_sink)) { + error = Error::Canceled; + return false; + } + if (!ok) { + error = Error::Write; + return false; + } + } + error = Error::Success; + return true; +} +template +inline bool write_content(Stream &strm, const ContentProvider &content_provider, + size_t offset, size_t length, + const T &is_shutting_down) { + auto error = Error::Success; + return write_content(strm, content_provider, offset, length, is_shutting_down, + error); +} +template +inline bool +write_content_without_length(Stream &strm, + const ContentProvider &content_provider, + const T &is_shutting_down) { + size_t offset = 0; + auto data_available = true; + auto ok = true; + DataSink data_sink; + + data_sink.write = [&](const char *d, size_t l) { + if (ok) { + offset += l; + if (!write_data(strm, d, l)) { ok = false; } + } + }; + data_sink.done = [&](void) { data_available = false; }; + data_sink.is_writable = [&](void) { return ok && strm.is_writable(); }; + while (data_available && !is_shutting_down()) { + if (!content_provider(offset, 0, data_sink)) { return false; } + if (!ok) { return false; } + } + return true; +} +template +inline bool +write_content_chunked(Stream &strm, const ContentProvider &content_provider, + const T &is_shutting_down, U &compressor, Error &error) { + size_t offset = 0; + auto data_available = true; + auto ok = true; + DataSink data_sink; + + data_sink.write = [&](const char *d, size_t l) { + if (!ok) { return; } + + data_available = l > 0; + offset += l; + + std::string payload; + if (!compressor.compress(d, l, false, + [&](const char *data, size_t data_len) { + payload.append(data, data_len); + return true; + })) { + ok = false; + return; + } + if (!payload.empty()) { + // Emit chunked response header and footer for each chunk + auto chunk = from_i_to_hex(payload.size()) + "\r\n" + payload + "\r\n"; + if (!write_data(strm, chunk.data(), chunk.size())) { + ok = false; + return; + } + } + }; -namespace duckdb { -//! Represents a JOIN between two expressions -class JoinRef : public TableRef { -public: - JoinRef() : TableRef(TableReferenceType::JOIN), is_natural(false) { - } + data_sink.done = [&](void) { + if (!ok) { return; } - //! 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; + data_available = false; -public: - bool Equals(const TableRef *other_p) const override; + std::string payload; + if (!compressor.compress(nullptr, 0, true, + [&](const char *data, size_t data_len) { + payload.append(data, data_len); + return true; + })) { + ok = false; + return; + } - unique_ptr Copy() override; + if (!payload.empty()) { + // Emit chunked response header and footer for each chunk + auto chunk = from_i_to_hex(payload.size()) + "\r\n" + payload + "\r\n"; + if (!write_data(strm, chunk.data(), chunk.size())) { + ok = false; + return; + } + } - //! Serializes a blob into a JoinRef - void Serialize(Serializer &serializer) override; - //! Deserializes a blob back into a JoinRef - static unique_ptr Deserialize(Deserializer &source); -}; -} // namespace duckdb + static const std::string done_marker("0\r\n\r\n"); + if (!write_data(strm, done_marker.data(), done_marker.size())) { + ok = false; + } + }; + data_sink.is_writable = [&](void) { return ok && strm.is_writable(); }; -namespace duckdb { + while (data_available && !is_shutting_down()) { + if (!content_provider(offset, 0, data_sink)) { + error = Error::Canceled; + return false; + } + if (!ok) { + error = Error::Write; + return false; + } + } -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) { - if (&left->context != &right->context) { - throw Exception("Cannot combine LEFT and RIGHT relations of different connections!"); - } - context.TryBindRelation(*this, this->columns); + error = Error::Success; + return true; } -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) { - if (&left->context != &right->context) { - throw Exception("Cannot combine LEFT and RIGHT relations of different connections!"); - } - context.TryBindRelation(*this, this->columns); +template +inline bool write_content_chunked(Stream &strm, + const ContentProvider &content_provider, + const T &is_shutting_down, U &compressor) { + auto error = Error::Success; + return write_content_chunked(strm, content_provider, is_shutting_down, + compressor, error); } -unique_ptr JoinRelation::GetQueryNode() { - auto result = make_unique(); - result->select_list.push_back(make_unique()); - result->from_table = GetTableRef(); - return move(result); +template +inline bool redirect(T &cli, const Request &req, Response &res, + const std::string &path, const std::string &location, + Error &error) { + Request new_req = req; + new_req.path = path; + new_req.redirect_count_ -= 1; + + if (res.status == 303 && (req.method != "GET" && req.method != "HEAD")) { + new_req.method = "GET"; + new_req.body.clear(); + new_req.headers.clear(); + } + + Response new_res; + + auto ret = cli.send(new_req, new_res, error); + if (ret) { + new_res.location = location; + res = new_res; + } + return ret; } -unique_ptr JoinRelation::GetTableRef() { - auto join_ref = make_unique(); - join_ref->left = left->GetTableRef(); - join_ref->right = right->GetTableRef(); - if (condition) { - join_ref->condition = condition->Copy(); - } - join_ref->using_columns = using_columns; - join_ref->type = join_type; - return move(join_ref); +inline std::string params_to_query_str(const Params ¶ms) { + std::string query; + + for (auto it = params.begin(); it != params.end(); ++it) { + if (it != params.begin()) { query += "&"; } + query += it->first; + query += "="; + query += encode_query_param(it->second); + } + return query; } -const vector &JoinRelation::Columns() { - return this->columns; +inline std::string append_query_params(const char *path, const Params ¶ms) { + std::string path_with_query = path; + const static std::regex re("[^?]+\\?.*"); + auto delm = std::regex_match(path, re) ? '&' : '?'; + path_with_query += delm + params_to_query_str(params); + return path_with_query; } -string JoinRelation::ToString(idx_t depth) { - string str = RenderWhitespace(depth); - str = "Join"; - return str + "\n" + left->ToString(depth + 1) + right->ToString(depth + 1); +inline void parse_query_text(const std::string &s, Params ¶ms) { + split(s.data(), s.data() + s.size(), '&', [&](const char *b, const char *e) { + std::string key; + std::string val; + split(b, e, '=', [&](const char *b2, const char *e2) { + if (key.empty()) { + key.assign(b2, e2); + } else { + val.assign(b2, e2); + } + }); + + if (!key.empty()) { + params.emplace(decode_url(key, true), decode_url(val, true)); + } + }); } -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/relation/limit_relation.hpp -// -// -//===----------------------------------------------------------------------===// +inline bool parse_multipart_boundary(const std::string &content_type, + std::string &boundary) { + auto pos = content_type.find("boundary="); + if (pos == std::string::npos) { return false; } + boundary = content_type.substr(pos + 9); + if (boundary.length() >= 2 && boundary.front() == '"' && + boundary.back() == '"') { + boundary = boundary.substr(1, boundary.size() - 2); + } + return !boundary.empty(); +} + +inline bool parse_range_header(const std::string &s, Ranges &ranges) try { + static auto re_first_range = std::regex(R"(bytes=(\d*-\d*(?:,\s*\d*-\d*)*))"); + std::smatch m; + if (std::regex_match(s, m, re_first_range)) { + auto pos = static_cast(m.position(1)); + auto len = static_cast(m.length(1)); + bool all_valid_ranges = true; + split(&s[pos], &s[pos + len], ',', [&](const char *b, const char *e) { + if (!all_valid_ranges) return; + static auto re_another_range = std::regex(R"(\s*(\d*)-(\d*))"); + std::cmatch cm; + if (std::regex_match(b, e, cm, re_another_range)) { + ssize_t first = -1; + if (!cm.str(1).empty()) { + first = static_cast(std::stoll(cm.str(1))); + } + ssize_t last = -1; + if (!cm.str(2).empty()) { + last = static_cast(std::stoll(cm.str(2))); + } + if (first != -1 && last != -1 && first > last) { + all_valid_ranges = false; + return; + } + ranges.emplace_back(std::make_pair(first, last)); + } + }); + return all_valid_ranges; + } + return false; +} catch (...) { return false; } +class MultipartFormDataParser { +public: + MultipartFormDataParser() = default; + + void set_boundary(std::string &&boundary) { boundary_ = boundary; } + + bool is_valid() const { return is_valid_; } + + bool parse(const char *buf, size_t n, const ContentReceiver &content_callback, + const MultipartContentHeader &header_callback) { + + static const std::regex re_content_disposition( + "^Content-Disposition:\\s*form-data;\\s*name=\"(.*?)\"(?:;\\s*filename=" + "\"(.*?)\")?\\s*$", + std::regex_constants::icase); + static const std::string dash_ = "--"; + static const std::string crlf_ = "\r\n"; + + buf_.append(buf, n); // TODO: performance improvement + + while (!buf_.empty()) { + switch (state_) { + case 0: { // Initial boundary + auto pattern = dash_ + boundary_ + crlf_; + if (pattern.size() > buf_.size()) { return true; } + auto pos = buf_.find(pattern); + if (pos != 0) { return false; } + buf_.erase(0, pattern.size()); + off_ += pattern.size(); + state_ = 1; + break; + } + case 1: { // New entry + clear_file_info(); + state_ = 2; + break; + } + case 2: { // Headers + auto pos = buf_.find(crlf_); + while (pos != std::string::npos) { + // Empty line + if (pos == 0) { + if (!header_callback(file_)) { + is_valid_ = false; + return false; + } + buf_.erase(0, crlf_.size()); + off_ += crlf_.size(); + state_ = 3; + break; + } + static const std::string header_name = "content-type:"; + const auto header = buf_.substr(0, pos); + if (start_with_case_ignore(header, header_name)) { + file_.content_type = trim_copy(header.substr(header_name.size())); + } else { + std::smatch m; + if (std::regex_match(header, m, re_content_disposition)) { + file_.name = m[1]; + file_.filename = m[2]; + } + } -namespace duckdb { + buf_.erase(0, pos + crlf_.size()); + off_ += pos + crlf_.size(); + pos = buf_.find(crlf_); + } + if (state_ != 3) { return true; } + break; + } + case 3: { // Body + { + auto pattern = crlf_ + dash_; + if (pattern.size() > buf_.size()) { return true; } -class LimitRelation : public Relation { -public: - LimitRelation(shared_ptr child, int64_t limit, int64_t offset); + auto pos = find_string(buf_, pattern); - int64_t limit; - int64_t offset; - shared_ptr child; + if (!content_callback(buf_.data(), pos)) { + is_valid_ = false; + return false; + } -public: - unique_ptr GetQueryNode() override; + off_ += pos; + buf_.erase(0, pos); + } + { + auto pattern = crlf_ + dash_ + boundary_; + if (pattern.size() > buf_.size()) { return true; } + + auto pos = buf_.find(pattern); + if (pos != std::string::npos) { + if (!content_callback(buf_.data(), pos)) { + is_valid_ = false; + return false; + } - const vector &Columns() override; - string ToString(idx_t depth) override; - string GetAlias() override; + off_ += pos + pattern.size(); + buf_.erase(0, pos + pattern.size()); + state_ = 4; + } else { + if (!content_callback(buf_.data(), pattern.size())) { + is_valid_ = false; + return false; + } -public: - bool InheritsColumnBindings() override { - return true; - } - Relation *ChildRelation() override { - return child.get(); - } -}; + off_ += pattern.size(); + buf_.erase(0, pattern.size()); + } + } + break; + } + case 4: { // Boundary + if (crlf_.size() > buf_.size()) { return true; } + if (buf_.compare(0, crlf_.size(), crlf_) == 0) { + buf_.erase(0, crlf_.size()); + off_ += crlf_.size(); + state_ = 1; + } else { + auto pattern = dash_ + crlf_; + if (pattern.size() > buf_.size()) { return true; } + if (buf_.compare(0, pattern.size(), pattern) == 0) { + buf_.erase(0, pattern.size()); + off_ += pattern.size(); + is_valid_ = true; + state_ = 5; + } else { + return true; + } + } + break; + } + case 5: { // Done + is_valid_ = false; + return false; + } + } + } -} // namespace duckdb + return true; + } +private: + void clear_file_info() { + file_.name.clear(); + file_.filename.clear(); + file_.content_type.clear(); + } + bool start_with_case_ignore(const std::string &a, + const std::string &b) const { + if (a.size() < b.size()) { return false; } + for (size_t i = 0; i < b.size(); i++) { + if (::tolower(a[i]) != ::tolower(b[i])) { return false; } + } + return true; + } + bool start_with(const std::string &a, size_t off, + const std::string &b) const { + if (a.size() - off < b.size()) { return false; } + for (size_t i = 0; i < b.size(); i++) { + if (a[i + off] != b[i]) { return false; } + } + return true; + } + size_t find_string(const std::string &s, const std::string &pattern) const { + auto c = pattern.front(); + size_t off = 0; + while (off < s.size()) { + auto pos = s.find(c, off); + if (pos == std::string::npos) { return s.size(); } -namespace duckdb { + auto rem = s.size() - pos; + if (pattern.size() > rem) { return pos; } -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)) { -} + if (start_with(s, pos, pattern)) { return pos; } -unique_ptr LimitRelation::GetQueryNode() { - auto child_node = child->GetQueryNode(); - auto limit_node = make_unique(); - if (limit >= 0) { - limit_node->limit = make_unique(Value::BIGINT(limit)); - } - if (offset > 0) { - limit_node->offset = make_unique(Value::BIGINT(offset)); - } + off = pos + 1; + } - child_node->modifiers.push_back(move(limit_node)); - return child_node; -} + return s.size(); + } -string LimitRelation::GetAlias() { - return child->GetAlias(); -} + std::string boundary_; -const vector &LimitRelation::Columns() { - return child->Columns(); -} + std::string buf_; + size_t state_ = 0; + bool is_valid_ = false; + size_t off_ = 0; + MultipartFormData file_; +}; -string LimitRelation::ToString(idx_t depth) { - string str = RenderWhitespace(depth) + "Limit " + to_string(limit); - if (offset > 0) { - str += " Offset " + to_string(offset); - } - str += "\n"; - return str + child->ToString(depth + 1); +inline std::string to_lower(const char *beg, const char *end) { + std::string out; + auto it = beg; + while (it != end) { + out += static_cast(::tolower(*it)); + it++; + } + return out; } -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/relation/order_relation.hpp -// -// -//===----------------------------------------------------------------------===// - +inline std::string make_multipart_data_boundary() { + static const char data[] = + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + // std::random_device might actually be deterministic on some + // platforms, but due to lack of support in the c++ standard library, + // doing better requires either some ugly hacks or breaking portability. + std::random_device seed_gen; + // Request 128 bits of entropy for initialization + std::seed_seq seed_sequence{seed_gen(), seed_gen(), seed_gen(), seed_gen()}; + std::mt19937 engine(seed_sequence); + std::string result = "--cpp-httplib-multipart-data-"; + for (auto i = 0; i < 16; i++) { + result += data[engine() % (sizeof(data) - 1)]; + } + return result; +} +inline std::pair +get_range_offset_and_length(const Request &req, size_t content_length, + size_t index) { + auto r = req.ranges[index]; -namespace duckdb { + if (r.first == -1 && r.second == -1) { + return std::make_pair(0, content_length); + } -class OrderRelation : public Relation { -public: - OrderRelation(shared_ptr child, vector orders); + auto slen = static_cast(content_length); - vector orders; - shared_ptr child; + if (r.first == -1) { + r.first = (std::max)(static_cast(0), slen - r.second); + r.second = slen - 1; + } -public: - unique_ptr GetQueryNode() override; + if (r.second == -1) { r.second = slen - 1; } + return std::make_pair(r.first, static_cast(r.second - r.first) + 1); +} + +inline std::string make_content_range_header_field(size_t offset, size_t length, + size_t content_length) { + std::string field = "bytes "; + field += std::to_string(offset); + field += "-"; + field += std::to_string(offset + length - 1); + field += "/"; + field += std::to_string(content_length); + return field; +} + +template +bool process_multipart_ranges_data(const Request &req, Response &res, + const std::string &boundary, + const std::string &content_type, + SToken stoken, CToken ctoken, + Content content) { + for (size_t i = 0; i < req.ranges.size(); i++) { + ctoken("--"); + stoken(boundary); + ctoken("\r\n"); + if (!content_type.empty()) { + ctoken("Content-Type: "); + stoken(content_type); + ctoken("\r\n"); + } - const vector &Columns() override; - string ToString(idx_t depth) override; - string GetAlias() override; + auto offsets = get_range_offset_and_length(req, res.body.size(), i); + auto offset = offsets.first; + auto length = offsets.second; -public: - bool InheritsColumnBindings() override { - return true; - } - Relation *ChildRelation() override { - return child.get(); - } -}; + ctoken("Content-Range: "); + stoken(make_content_range_header_field(offset, length, res.body.size())); + ctoken("\r\n"); + ctoken("\r\n"); + if (!content(offset, length)) { return false; } + ctoken("\r\n"); + } -} // namespace duckdb + ctoken("--"); + stoken(boundary); + ctoken("--\r\n"); + return true; +} +inline bool make_multipart_ranges_data(const Request &req, Response &res, + const std::string &boundary, + const std::string &content_type, + std::string &data) { + return process_multipart_ranges_data( + req, res, boundary, content_type, + [&](const std::string &token) { data += token; }, + [&](const char *token) { data += token; }, + [&](size_t offset, size_t length) { + if (offset < res.body.size()) { + data += res.body.substr(offset, length); + return true; + } + return false; + }); +} +inline size_t +get_multipart_ranges_data_length(const Request &req, Response &res, + const std::string &boundary, + const std::string &content_type) { + size_t data_length = 0; -namespace duckdb { + process_multipart_ranges_data( + req, res, boundary, content_type, + [&](const std::string &token) { data_length += token.size(); }, + [&](const char *token) { data_length += strlen(token); }, + [&](size_t /*offset*/, size_t length) { + data_length += length; + return true; + }); -OrderRelation::OrderRelation(shared_ptr child_p, vector orders) - : Relation(child_p->context, RelationType::ORDER_RELATION), orders(move(orders)), child(move(child_p)) { - // bind the expressions - vector dummy_columns; - context.TryBindRelation(*this, dummy_columns); + return data_length; } -unique_ptr OrderRelation::GetQueryNode() { - auto child_node = child->GetQueryNode(); - auto order_node = make_unique(); - 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()); - } - child_node->modifiers.push_back(move(order_node)); - return child_node; -} +template +inline bool write_multipart_ranges_data(Stream &strm, const Request &req, + Response &res, + const std::string &boundary, + const std::string &content_type, + const T &is_shutting_down) { + return process_multipart_ranges_data( + req, res, boundary, content_type, + [&](const std::string &token) { strm.write(token); }, + [&](const char *token) { strm.write(token); }, + [&](size_t offset, size_t length) { + return write_content(strm, res.content_provider_, offset, length, + is_shutting_down); + }); +} + +inline std::pair +get_range_offset_and_length(const Request &req, const Response &res, + size_t index) { + auto r = req.ranges[index]; + + if (r.second == -1) { + r.second = static_cast(res.content_length_) - 1; + } -string OrderRelation::GetAlias() { - return child->GetAlias(); + return std::make_pair(r.first, r.second - r.first + 1); } -const vector &OrderRelation::Columns() { - return child->Columns(); +inline bool expect_content(const Request &req) { + if (req.method == "POST" || req.method == "PUT" || req.method == "PATCH" || + req.method == "PRI" || req.method == "DELETE") { + return true; + } + // TODO: check if Content-Length is set + return false; } -string OrderRelation::ToString(idx_t depth) { - string str = RenderWhitespace(depth) + "Order ["; - for (idx_t i = 0; i < orders.size(); i++) { - if (i != 0) { - str += ", "; - } - str += orders[i].expression->ToString() + (orders[i].type == OrderType::ASCENDING ? " ASC" : " DESC"); - } - str += "]\n"; - return str + child->ToString(depth + 1); +inline bool has_crlf(const char *s) { + auto p = s; + while (*p) { + if (*p == '\r' || *p == '\n') { return true; } + p++; + } + return false; } -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/relation/projection_relation.hpp -// -// -//===----------------------------------------------------------------------===// +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +template +inline std::string message_digest(const std::string &s, Init init, + Update update, Final final, + size_t digest_length) { + using namespace std; + std::vector md(digest_length, 0); + CTX ctx; + init(&ctx); + update(&ctx, s.data(), s.size()); + final(md.data(), &ctx); + stringstream ss; + for (auto c : md) { + ss << setfill('0') << setw(2) << hex << (unsigned int)c; + } + return ss.str(); +} +inline std::string MD5(const std::string &s) { + return message_digest(s, MD5_Init, MD5_Update, MD5_Final, + MD5_DIGEST_LENGTH); +} +inline std::string SHA_256(const std::string &s) { + return message_digest(s, SHA256_Init, SHA256_Update, SHA256_Final, + SHA256_DIGEST_LENGTH); +} +inline std::string SHA_512(const std::string &s) { + return message_digest(s, SHA512_Init, SHA512_Update, SHA512_Final, + SHA512_DIGEST_LENGTH); +} +#endif -namespace duckdb { +#ifdef _WIN32 +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +// NOTE: This code came up with the following stackoverflow post: +// https://stackoverflow.com/questions/9507184/can-openssl-on-windows-use-the-system-certificate-store +inline bool load_system_certs_on_windows(X509_STORE *store) { + auto hStore = CertOpenSystemStoreW((HCRYPTPROV_LEGACY)NULL, L"ROOT"); + + if (!hStore) { return false; } + + PCCERT_CONTEXT pContext = NULL; + while ((pContext = CertEnumCertificatesInStore(hStore, pContext)) != + nullptr) { + auto encoded_cert = + static_cast(pContext->pbCertEncoded); + + auto x509 = d2i_X509(NULL, &encoded_cert, pContext->cbCertEncoded); + if (x509) { + X509_STORE_add_cert(store, x509); + X509_free(x509); + } + } -class ProjectionRelation : public Relation { -public: - ProjectionRelation(shared_ptr child, vector> expressions, - vector aliases); + CertFreeCertificateContext(pContext); + CertCloseStore(hStore, 0); - vector> expressions; - vector columns; - shared_ptr child; + return true; +} +#endif +class WSInit { public: - unique_ptr GetQueryNode() override; + WSInit() { + WSADATA wsaData; + WSAStartup(0x0002, &wsaData); + } - const vector &Columns() override; - string ToString(idx_t depth) override; - string GetAlias() override; + ~WSInit() { WSACleanup(); } }; -} // namespace duckdb +static WSInit wsinit_; +#endif +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +inline std::pair make_digest_authentication_header( + const Request &req, const std::map &auth, + size_t cnonce_count, const std::string &cnonce, const std::string &username, + const std::string &password, bool is_proxy = false) { + using namespace std; + string nc; + { + stringstream ss; + ss << setfill('0') << setw(8) << hex << cnonce_count; + nc = ss.str(); + } + auto qop = auth.at("qop"); + if (qop.find("auth-int") != std::string::npos) { + qop = "auth-int"; + } else { + qop = "auth"; + } + std::string algo = "MD5"; + if (auth.find("algorithm") != auth.end()) { algo = auth.at("algorithm"); } -namespace duckdb { + string response; + { + auto H = algo == "SHA-256" + ? detail::SHA_256 + : algo == "SHA-512" ? detail::SHA_512 : detail::MD5; -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)) { - if (!aliases.empty()) { - if (aliases.size() != expressions.size()) { - throw ParserException("Aliases list length must match expression list length!"); - } - for (idx_t i = 0; i < aliases.size(); i++) { - expressions[i]->alias = aliases[i]; - } - } - // bind the expressions - context.TryBindRelation(*this, this->columns); -} + auto A1 = username + ":" + auth.at("realm") + ":" + password; -unique_ptr ProjectionRelation::GetQueryNode() { - auto child_ptr = child.get(); - while (child_ptr->InheritsColumnBindings()) { - child_ptr = child_ptr->ChildRelation(); - } - unique_ptr result; - if (child_ptr->type == RelationType::JOIN_RELATION) { - // child node is a join: push projection into the child query node - result = child->GetQueryNode(); - } else { - // 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); - } - D_ASSERT(result->type == QueryNodeType::SELECT_NODE); - auto &select_node = (SelectNode &)*result; - select_node.aggregate_handling = AggregateHandling::NO_AGGREGATES_ALLOWED; - select_node.select_list.clear(); - for (auto &expr : expressions) { - select_node.select_list.push_back(expr->Copy()); - } - return result; -} + auto A2 = req.method + ":" + req.path; + if (qop == "auth-int") { A2 += ":" + H(req.body); } -string ProjectionRelation::GetAlias() { - return child->GetAlias(); -} + response = H(H(A1) + ":" + auth.at("nonce") + ":" + nc + ":" + cnonce + + ":" + qop + ":" + H(A2)); + } -const vector &ProjectionRelation::Columns() { - return columns; + auto field = "Digest username=\"" + username + "\", realm=\"" + + auth.at("realm") + "\", nonce=\"" + auth.at("nonce") + + "\", uri=\"" + req.path + "\", algorithm=" + algo + + ", qop=" + qop + ", nc=\"" + nc + "\", cnonce=\"" + cnonce + + "\", response=\"" + response + "\""; + + auto key = is_proxy ? "Proxy-Authorization" : "Authorization"; + return std::make_pair(key, field); } +#endif -string ProjectionRelation::ToString(idx_t depth) { - string str = RenderWhitespace(depth) + "Projection ["; - for (idx_t i = 0; i < expressions.size(); i++) { - if (i != 0) { - str += ", "; - } - str += expressions[i]->ToString(); - } - str += "]\n"; - return str + child->ToString(depth + 1); +inline bool parse_www_authenticate(const Response &res, + std::map &auth, + bool is_proxy) { + auto auth_key = is_proxy ? "Proxy-Authenticate" : "WWW-Authenticate"; + if (res.has_header(auth_key)) { + static auto re = std::regex(R"~((?:(?:,\s*)?(.+?)=(?:"(.*?)"|([^,]*))))~"); + auto s = res.get_header_value(auth_key); + auto pos = s.find(' '); + if (pos != std::string::npos) { + auto type = s.substr(0, pos); + if (type == "Basic") { + return false; + } else if (type == "Digest") { + s = s.substr(pos + 1); + auto beg = std::sregex_iterator(s.begin(), s.end(), re); + for (auto i = beg; i != std::sregex_iterator(); ++i) { + auto m = *i; + auto key = s.substr(static_cast(m.position(1)), + static_cast(m.length(1))); + auto val = m.length(2) > 0 + ? s.substr(static_cast(m.position(2)), + static_cast(m.length(2))) + : s.substr(static_cast(m.position(3)), + static_cast(m.length(3))); + auth[key] = val; + } + return true; + } + } + } + return false; } -} // namespace duckdb +// https://stackoverflow.com/questions/440133/how-do-i-create-a-random-alpha-numeric-string-in-c/440240#answer-440240 +inline std::string random_string(size_t length) { + auto randchar = []() -> char { + const char charset[] = "0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; + const size_t max_index = (sizeof(charset) - 1); + return charset[static_cast(rand()) % max_index]; + }; + std::string str(length, 0); + std::generate_n(str.begin(), length, randchar); + return str; +} +class ContentProviderAdapter { +public: + explicit ContentProviderAdapter( + ContentProviderWithoutLength &&content_provider) + : content_provider_(content_provider) {} + bool operator()(size_t offset, size_t, DataSink &sink) { + return content_provider_(offset, sink); + } +private: + ContentProviderWithoutLength content_provider_; +}; +} // namespace detail +// Header utilities +inline std::pair make_range_header(Ranges ranges) { + std::string field = "bytes="; + auto i = 0; + for (auto r : ranges) { + if (i != 0) { field += ", "; } + if (r.first != -1) { field += std::to_string(r.first); } + field += '-'; + if (r.second != -1) { field += std::to_string(r.second); } + i++; + } + return std::make_pair("Range", std::move(field)); +} -namespace duckdb { +inline std::pair +make_basic_authentication_header(const std::string &username, + const std::string &password, + bool is_proxy = false) { + auto field = "Basic " + detail::base64_encode(username + ":" + password); + auto key = is_proxy ? "Proxy-Authorization" : "Authorization"; + return std::make_pair(key, std::move(field)); +} -QueryRelation::QueryRelation(ClientContext &context, string query, string alias) - : Relation(context, RelationType::QUERY_RELATION), query(move(query)), alias(move(alias)) { - context.TryBindRelation(*this, this->columns); +inline std::pair +make_bearer_token_authentication_header(const std::string &token, + bool is_proxy = false) { + auto field = "Bearer " + token; + auto key = is_proxy ? "Proxy-Authorization" : "Authorization"; + return std::make_pair(key, std::move(field)); } -unique_ptr QueryRelation::GetSelectStatement() { - Parser parser; - parser.ParseQuery(query); - if (parser.statements.size() != 1) { - throw ParserException("Expected a single SELECT statement"); - } - if (parser.statements[0]->type != StatementType::SELECT_STATEMENT) { - throw ParserException("Expected a single SELECT statement"); - } - return unique_ptr_cast(move(parser.statements[0])); +// Request implementation +inline bool Request::has_header(const char *key) const { + return detail::has_header(headers, key); } -unique_ptr QueryRelation::GetQueryNode() { - auto select = GetSelectStatement(); - return move(select->node); +inline std::string Request::get_header_value(const char *key, size_t id) const { + return detail::get_header_value(headers, key, id, ""); } -unique_ptr QueryRelation::GetTableRef() { - auto subquery_ref = make_unique(GetSelectStatement(), GetAlias()); - return move(subquery_ref); +template +inline T Request::get_header_value(const char *key, size_t id) const { + return detail::get_header_value(headers, key, id, 0); } -string QueryRelation::GetAlias() { - return alias; +inline size_t Request::get_header_value_count(const char *key) const { + auto r = headers.equal_range(key); + return static_cast(std::distance(r.first, r.second)); } -const vector &QueryRelation::Columns() { - return columns; +inline void Request::set_header(const char *key, const char *val) { + if (!detail::has_crlf(key) && !detail::has_crlf(val)) { + headers.emplace(key, val); + } } -string QueryRelation::ToString(idx_t depth) { - return RenderWhitespace(depth) + "Subquery [" + query + "]"; +inline void Request::set_header(const char *key, const std::string &val) { + if (!detail::has_crlf(key) && !detail::has_crlf(val.c_str())) { + headers.emplace(key, val); + } } -} // namespace duckdb +inline bool Request::has_param(const char *key) const { + return params.find(key) != params.end(); +} +inline std::string Request::get_param_value(const char *key, size_t id) const { + auto rng = params.equal_range(key); + auto it = rng.first; + std::advance(it, static_cast(id)); + if (it != rng.second) { return it->second; } + return std::string(); +} +inline size_t Request::get_param_value_count(const char *key) const { + auto r = params.equal_range(key); + return static_cast(std::distance(r.first, r.second)); +} +inline bool Request::is_multipart_form_data() const { + const auto &content_type = get_header_value("Content-Type"); + return !content_type.find("multipart/form-data"); +} +inline bool Request::has_file(const char *key) const { + return files.find(key) != files.end(); +} +inline MultipartFormData Request::get_file_value(const char *key) const { + auto it = files.find(key); + if (it != files.end()) { return it->second; } + return MultipartFormData(); +} +// Response implementation +inline bool Response::has_header(const char *key) const { + return headers.find(key) != headers.end(); +} +inline std::string Response::get_header_value(const char *key, + size_t id) const { + return detail::get_header_value(headers, key, id, ""); +} +template +inline T Response::get_header_value(const char *key, size_t id) const { + return detail::get_header_value(headers, key, id, 0); +} +inline size_t Response::get_header_value_count(const char *key) const { + auto r = headers.equal_range(key); + return static_cast(std::distance(r.first, r.second)); +} +inline void Response::set_header(const char *key, const char *val) { + if (!detail::has_crlf(key) && !detail::has_crlf(val)) { + headers.emplace(key, val); + } +} -namespace duckdb { +inline void Response::set_header(const char *key, const std::string &val) { + if (!detail::has_crlf(key) && !detail::has_crlf(val.c_str())) { + headers.emplace(key, val); + } +} -ReadCSVRelation::ReadCSVRelation(ClientContext &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)) { - if (alias.empty()) { - alias = StringUtil::Split(csv_file, ".")[0]; - } +inline void Response::set_redirect(const char *url, int stat) { + if (!detail::has_crlf(url)) { + set_header("Location", url); + if (300 <= stat && stat < 400) { + this->status = stat; + } else { + this->status = 302; + } + } } -unique_ptr ReadCSVRelation::GetQueryNode() { - auto result = make_unique(); - result->select_list.push_back(make_unique()); - result->from_table = GetTableRef(); - return move(result); +inline void Response::set_redirect(const std::string &url, int stat) { + set_redirect(url.c_str(), stat); } -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)))); - } - table_ref->function = make_unique("read_csv", move(children)); - return move(table_ref); +inline void Response::set_content(const char *s, size_t n, + const char *content_type) { + body.assign(s, n); + + auto rng = headers.equal_range("Content-Type"); + headers.erase(rng.first, rng.second); + set_header("Content-Type", content_type); } -string ReadCSVRelation::GetAlias() { - return alias; +inline void Response::set_content(const std::string &s, + const char *content_type) { + set_content(s.data(), s.size(), content_type); } -const vector &ReadCSVRelation::Columns() { - return columns; +inline void +Response::set_content_provider(size_t in_length, const char *content_type, + ContentProvider provider, + const std::function &resource_releaser) { + assert(in_length > 0); + set_header("Content-Type", content_type); + content_length_ = in_length; + content_provider_ = std::move(provider); + content_provider_resource_releaser_ = resource_releaser; + is_chunked_content_provider_ = false; } -string ReadCSVRelation::ToString(idx_t depth) { - return RenderWhitespace(depth) + "Read CSV [" + csv_file + "]"; +inline void +Response::set_content_provider(const char *content_type, + ContentProviderWithoutLength provider, + const std::function &resource_releaser) { + set_header("Content-Type", content_type); + content_length_ = 0; + content_provider_ = detail::ContentProviderAdapter(std::move(provider)); + content_provider_resource_releaser_ = resource_releaser; + is_chunked_content_provider_ = false; } -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/relation/setop_relation.hpp -// -// -//===----------------------------------------------------------------------===// +inline void Response::set_chunked_content_provider( + const char *content_type, ContentProviderWithoutLength provider, + const std::function &resource_releaser) { + set_header("Content-Type", content_type); + content_length_ = 0; + content_provider_ = detail::ContentProviderAdapter(std::move(provider)); + content_provider_resource_releaser_ = resource_releaser; + is_chunked_content_provider_ = true; +} +// Rstream implementation +inline ssize_t Stream::write(const char *ptr) { + return write(ptr, strlen(ptr)); +} +inline ssize_t Stream::write(const std::string &s) { + return write(s.data(), s.size()); +} +template +inline ssize_t Stream::write_format(const char *fmt, const Args &... args) { + const auto bufsiz = 2048; + std::array buf; +#if defined(_MSC_VER) && _MSC_VER < 1900 + auto sn = _snprintf_s(buf.data(), bufsiz - 1, buf.size() - 1, fmt, args...); +#else + auto sn = snprintf(buf.data(), buf.size() - 1, fmt, args...); +#endif + if (sn <= 0) { return sn; } + auto n = static_cast(sn); -namespace duckdb { + if (n >= buf.size() - 1) { + std::vector glowable_buf(buf.size()); -class SetOpRelation : public Relation { -public: - SetOpRelation(shared_ptr left, shared_ptr right, SetOperationType setop_type); + while (n >= glowable_buf.size() - 1) { + glowable_buf.resize(glowable_buf.size() * 2); +#if defined(_MSC_VER) && _MSC_VER < 1900 + n = static_cast(_snprintf_s(&glowable_buf[0], glowable_buf.size(), + glowable_buf.size() - 1, fmt, + args...)); +#else + n = static_cast( + snprintf(&glowable_buf[0], glowable_buf.size() - 1, fmt, args...)); +#endif + } + return write(&glowable_buf[0], n); + } else { + return write(buf.data(), n); + } +} - shared_ptr left; - shared_ptr right; - SetOperationType setop_type; +namespace detail { -public: - unique_ptr GetQueryNode() override; +// Socket stream implementation +inline SocketStream::SocketStream(socket_t sock, time_t read_timeout_sec, + time_t read_timeout_usec, + time_t write_timeout_sec, + time_t write_timeout_usec) + : sock_(sock), read_timeout_sec_(read_timeout_sec), + read_timeout_usec_(read_timeout_usec), + write_timeout_sec_(write_timeout_sec), + write_timeout_usec_(write_timeout_usec) {} - const vector &Columns() override; - string ToString(idx_t depth) override; - string GetAlias() override; -}; +inline SocketStream::~SocketStream() {} -} // namespace duckdb +inline bool SocketStream::is_readable() const { + return select_read(sock_, read_timeout_sec_, read_timeout_usec_) > 0; +} +inline bool SocketStream::is_writable() const { + return select_write(sock_, write_timeout_sec_, write_timeout_usec_) > 0; +} +inline ssize_t SocketStream::read(char *ptr, size_t size) { + if (!is_readable()) { return -1; } +#ifdef _WIN32 + if (size > static_cast((std::numeric_limits::max)())) { + return -1; + } + return recv(sock_, ptr, static_cast(size), CPPHTTPLIB_RECV_FLAGS); +#else + return handle_EINTR( + [&]() { return recv(sock_, ptr, size, CPPHTTPLIB_RECV_FLAGS); }); +#endif +} -namespace duckdb { +inline ssize_t SocketStream::write(const char *ptr, size_t size) { + if (!is_writable()) { return -1; } -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) { - if (&left->context != &right->context) { - throw Exception("Cannot combine LEFT and RIGHT relations of different connections!"); - } - vector dummy_columns; - context.TryBindRelation(*this, dummy_columns); +#ifdef _WIN32 + if (size > static_cast((std::numeric_limits::max)())) { + return -1; + } + return send(sock_, ptr, static_cast(size), CPPHTTPLIB_SEND_FLAGS); +#else + return handle_EINTR( + [&]() { return send(sock_, ptr, size, CPPHTTPLIB_SEND_FLAGS); }); +#endif } -unique_ptr SetOpRelation::GetQueryNode() { - auto result = make_unique(); - result->left = left->GetQueryNode(); - result->right = right->GetQueryNode(); - result->setop_type = setop_type; - return move(result); +inline void SocketStream::get_remote_ip_and_port(std::string &ip, + int &port) const { + return detail::get_remote_ip_and_port(sock_, ip, port); } -string SetOpRelation::GetAlias() { - return left->GetAlias(); -} +inline socket_t SocketStream::socket() const { return sock_; } -const vector &SetOpRelation::Columns() { - return left->Columns(); +// Buffer stream implementation +inline bool BufferStream::is_readable() const { return true; } + +inline bool BufferStream::is_writable() const { return true; } + +inline ssize_t BufferStream::read(char *ptr, size_t size) { +#if defined(_MSC_VER) && _MSC_VER <= 1900 + auto len_read = buffer._Copy_s(ptr, size, size, position); +#else + auto len_read = buffer.copy(ptr, size, position); +#endif + position += static_cast(len_read); + return static_cast(len_read); } -string SetOpRelation::ToString(idx_t depth) { - string str = RenderWhitespace(depth); - switch (setop_type) { - case SetOperationType::UNION: - str += "Union"; - break; - case SetOperationType::EXCEPT: - str += "Except"; - break; - case SetOperationType::INTERSECT: - str += "Intersect"; - break; - default: - throw InternalException("Unknown setop type"); - } - return str + "\n" + left->ToString(depth + 1) + right->ToString(depth + 1); +inline ssize_t BufferStream::write(const char *ptr, size_t size) { + buffer.append(ptr, size); + return static_cast(size); } -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/relation/subquery_relation.hpp -// -// -//===----------------------------------------------------------------------===// +inline void BufferStream::get_remote_ip_and_port(std::string & /*ip*/, + int & /*port*/) const {} +inline socket_t BufferStream::socket() const { return 0; } +inline const std::string &BufferStream::get_buffer() const { return buffer; } +} // namespace detail +// HTTP server implementation +inline Server::Server() + : new_task_queue( + [] { return new ThreadPool(CPPHTTPLIB_THREAD_POOL_COUNT); }), + svr_sock_(INVALID_SOCKET), is_running_(false) { +#ifndef _WIN32 + signal(SIGPIPE, SIG_IGN); +#endif +} -namespace duckdb { +inline Server::~Server() {} -class SubqueryRelation : public Relation { -public: - SubqueryRelation(shared_ptr child, string alias); +inline Server &Server::Get(const char *pattern, Handler handler) { + return Get(pattern, strlen(pattern), handler); +} - shared_ptr child; - string alias; +inline Server &Server::Get(const char *pattern, size_t pattern_len, + Handler handler) { + get_handlers_.push_back( + std::make_pair(std::regex(pattern, pattern_len), std::move(handler))); + return *this; +} -public: - unique_ptr GetQueryNode() override; +inline Server &Server::Post(const char *pattern, Handler handler) { + return Post(pattern, strlen(pattern), handler); +} - const vector &Columns() override; - string ToString(idx_t depth) override; - string GetAlias() override; +inline Server &Server::Post(const char *pattern, size_t pattern_len, + Handler handler) { + post_handlers_.push_back( + std::make_pair(std::regex(pattern, pattern_len), std::move(handler))); + return *this; +} -public: - bool InheritsColumnBindings() override { - return child->InheritsColumnBindings(); - } - Relation *ChildRelation() override { - return child->ChildRelation(); - } -}; +inline Server &Server::Post(const char *pattern, + HandlerWithContentReader handler) { + return Post(pattern, strlen(pattern), handler); +} -} // namespace duckdb +inline Server &Server::Post(const char *pattern, size_t pattern_len, + HandlerWithContentReader handler) { + post_handlers_for_content_reader_.push_back( + std::make_pair(std::regex(pattern, pattern_len), std::move(handler))); + return *this; +} +inline Server &Server::Put(const char *pattern, Handler handler) { + return Put(pattern, strlen(pattern), handler); +} +inline Server &Server::Put(const char *pattern, size_t pattern_len, + Handler handler) { + put_handlers_.push_back( + std::make_pair(std::regex(pattern, pattern_len), std::move(handler))); + return *this; +} +inline Server &Server::Put(const char *pattern, + HandlerWithContentReader handler) { + return Put(pattern, strlen(pattern), handler); +} -namespace duckdb { +inline Server &Server::Put(const char *pattern, size_t pattern_len, + HandlerWithContentReader handler) { + put_handlers_for_content_reader_.push_back( + std::make_pair(std::regex(pattern, pattern_len), std::move(handler))); + return *this; +} -SubqueryRelation::SubqueryRelation(shared_ptr child_p, string alias_p) - : Relation(child_p->context, RelationType::SUBQUERY_RELATION), child(move(child_p)), alias(move(alias_p)) { - vector dummy_columns; - context.TryBindRelation(*this, dummy_columns); +inline Server &Server::Patch(const char *pattern, Handler handler) { + return Patch(pattern, strlen(pattern), handler); } -unique_ptr SubqueryRelation::GetQueryNode() { - return child->GetQueryNode(); +inline Server &Server::Patch(const char *pattern, size_t pattern_len, + Handler handler) { + patch_handlers_.push_back( + std::make_pair(std::regex(pattern, pattern_len), std::move(handler))); + return *this; } -string SubqueryRelation::GetAlias() { - return alias; +inline Server &Server::Patch(const char *pattern, + HandlerWithContentReader handler) { + return Patch(pattern, strlen(pattern), handler); } -const vector &SubqueryRelation::Columns() { - return child->Columns(); +inline Server &Server::Patch(const char *pattern, size_t pattern_len, + HandlerWithContentReader handler) { + patch_handlers_for_content_reader_.push_back( + std::make_pair(std::regex(pattern, pattern_len), std::move(handler))); + return *this; } -string SubqueryRelation::ToString(idx_t depth) { - return child->ToString(depth); +inline Server &Server::Delete(const char *pattern, Handler handler) { + return Delete(pattern, strlen(pattern), handler); } -} // namespace duckdb +inline Server &Server::Delete(const char *pattern, size_t pattern_len, + Handler handler) { + delete_handlers_.push_back( + std::make_pair(std::regex(pattern, pattern_len), std::move(handler))); + return *this; +} +inline Server &Server::Delete(const char *pattern, + HandlerWithContentReader handler) { + return Delete(pattern, strlen(pattern), handler); +} +inline Server &Server::Delete(const char *pattern, size_t pattern_len, + HandlerWithContentReader handler) { + delete_handlers_for_content_reader_.push_back( + std::make_pair(std::regex(pattern, pattern_len), std::move(handler))); + return *this; +} +inline Server &Server::Options(const char *pattern, Handler handler) { + return Options(pattern, strlen(pattern), handler); +} +inline Server &Server::Options(const char *pattern, size_t pattern_len, + Handler handler) { + options_handlers_.push_back( + std::make_pair(std::regex(pattern, pattern_len), std::move(handler))); + return *this; +} +inline bool Server::set_base_dir(const char *dir, const char *mount_point) { + return set_mount_point(mount_point, dir); +} +inline bool Server::set_mount_point(const char *mount_point, const char *dir, + Headers headers) { + if (detail::is_dir(dir)) { + std::string mnt = mount_point ? mount_point : "/"; + if (!mnt.empty() && mnt[0] == '/') { + base_dirs_.push_back({mnt, dir, std::move(headers)}); + return true; + } + } + return false; +} -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/expression/subquery_expression.hpp -// -// -//===----------------------------------------------------------------------===// +inline bool Server::remove_mount_point(const char *mount_point) { + for (auto it = base_dirs_.begin(); it != base_dirs_.end(); ++it) { + if (it->mount_point == mount_point) { + base_dirs_.erase(it); + return true; + } + } + return false; +} +inline Server & +Server::set_file_extension_and_mimetype_mapping(const char *ext, + const char *mime) { + file_extension_and_mimetype_map_[ext] = mime; + return *this; +} +inline Server &Server::set_file_request_handler(Handler handler) { + file_request_handler_ = std::move(handler); + return *this; +} +inline Server &Server::set_error_handler(HandlerWithResponse handler) { + error_handler_ = std::move(handler); + return *this; +} +inline Server &Server::set_error_handler(Handler handler) { + error_handler_ = [handler](const Request &req, Response &res) { + handler(req, res); + return HandlerResponse::Handled; + }; + return *this; +} -namespace duckdb { +inline Server &Server::set_exception_handler(ExceptionHandler handler) { + exception_handler_ = std::move(handler); + return *this; +} -//! Represents a subquery -class SubqueryExpression : public ParsedExpression { -public: - SubqueryExpression(); +inline Server &Server::set_pre_routing_handler(HandlerWithResponse handler) { + pre_routing_handler_ = std::move(handler); + return *this; +} - //! The actual subquery - unique_ptr subquery; - //! The subquery type - SubqueryType subquery_type; - //! the child expression to compare with (in case of IN, ANY, ALL operators, empty for EXISTS queries and scalar - //! subquery) - unique_ptr child; - //! The comparison type of the child expression with the subquery (in case of ANY, ALL operators), empty otherwise - ExpressionType comparison_type; +inline Server &Server::set_post_routing_handler(Handler handler) { + post_routing_handler_ = std::move(handler); + return *this; +} -public: - bool HasSubquery() const override { - return true; - } - bool IsScalar() const override { - return false; - } +inline Server &Server::set_logger(Logger logger) { + logger_ = std::move(logger); - string ToString() const override; + return *this; +} - static bool Equals(const SubqueryExpression *a, const SubqueryExpression *b); +inline Server & +Server::set_expect_100_continue_handler(Expect100ContinueHandler handler) { + expect_100_continue_handler_ = std::move(handler); - unique_ptr Copy() const override; + return *this; +} - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(ExpressionType type, Deserializer &source); -}; -} // namespace duckdb +inline Server &Server::set_tcp_nodelay(bool on) { + tcp_nodelay_ = on; + + return *this; +} +inline Server &Server::set_socket_options(SocketOptions socket_options) { + socket_options_ = std::move(socket_options); + return *this; +} +inline Server &Server::set_keep_alive_max_count(size_t count) { + keep_alive_max_count_ = count; + return *this; +} -namespace duckdb { +inline Server &Server::set_keep_alive_timeout(time_t sec) { + keep_alive_timeout_sec_ = sec; -TableFunctionRelation::TableFunctionRelation(ClientContext &context, string name_p, vector parameters_p, - unordered_map 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); + return *this; } -TableFunctionRelation::TableFunctionRelation(ClientContext &context, string name_p, vector parameters_p, - 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); +inline Server &Server::set_read_timeout(time_t sec, time_t usec) { + read_timeout_sec_ = sec; + read_timeout_usec_ = usec; + + return *this; } -unique_ptr TableFunctionRelation::GetQueryNode() { - auto result = make_unique(); - result->select_list.push_back(make_unique()); - result->from_table = GetTableRef(); - return move(result); +inline Server &Server::set_write_timeout(time_t sec, time_t usec) { + write_timeout_sec_ = sec; + write_timeout_usec_ = usec; + + return *this; } -unique_ptr TableFunctionRelation::GetTableRef() { - vector> children; - if (input_relation) { // input relation becomes first parameter if present, always - auto subquery = make_unique(); - subquery->subquery = make_unique(); - subquery->subquery->node = input_relation->GetQueryNode(); - subquery->subquery_type = SubqueryType::SCALAR; - children.push_back(move(subquery)); - } - for (auto ¶meter : parameters) { - children.push_back(make_unique(parameter)); - } +inline Server &Server::set_idle_interval(time_t sec, time_t usec) { + idle_interval_sec_ = sec; + idle_interval_usec_ = usec; - for (auto ¶meter : named_parameters) { - // Hackity-hack some comparisons with column refs - // This is all but pretty, basically the named parameter is the column, the table is empty because that's what - // 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)); - } + return *this; +} - auto table_function = make_unique(); - auto function = make_unique(name, move(children)); - table_function->function = move(function); - return move(table_function); +inline Server &Server::set_payload_max_length(size_t length) { + payload_max_length_ = length; + + return *this; } -string TableFunctionRelation::GetAlias() { - return name; +inline bool Server::bind_to_port(const char *host, int port, int socket_flags) { + if (bind_internal(host, port, socket_flags) < 0) return false; + return true; +} +inline int Server::bind_to_any_port(const char *host, int socket_flags) { + return bind_internal(host, 0, socket_flags); } -const vector &TableFunctionRelation::Columns() { - return columns; +inline bool Server::listen_after_bind() { return listen_internal(); } + +inline bool Server::listen(const char *host, int port, int socket_flags) { + return bind_to_port(host, port, socket_flags) && listen_internal(); } -string TableFunctionRelation::ToString(idx_t depth) { - string function_call = name + "("; - for (idx_t i = 0; i < parameters.size(); i++) { - if (i > 0) { - function_call += ", "; - } - function_call += parameters[i].ToString(); - } - function_call += ")"; - return RenderWhitespace(depth) + function_call; +inline bool Server::is_running() const { return is_running_; } + +inline void Server::stop() { + if (is_running_) { + assert(svr_sock_ != INVALID_SOCKET); + std::atomic sock(svr_sock_.exchange(INVALID_SOCKET)); + detail::shutdown_socket(sock); + detail::close_socket(sock); + } } -} // namespace duckdb +inline bool Server::parse_request_line(const char *s, Request &req) { + const static std::regex re( + "(GET|HEAD|POST|PUT|DELETE|CONNECT|OPTIONS|TRACE|PATCH|PRI) " + "(([^? ]+)(?:\\?([^ ]*?))?) (HTTP/1\\.[01])\r\n"); + std::cmatch m; + if (std::regex_match(s, m, re)) { + req.version = std::string(m[5]); + req.method = std::string(m[1]); + req.target = std::string(m[2]); + req.path = detail::decode_url(m[3], false); + // Parse query text + auto len = std::distance(m[4].first, m[4].second); + if (len > 0) { detail::parse_query_text(m[4], req.params); } + return true; + } + return false; +} -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/relation/update_relation.hpp -// -// -//===----------------------------------------------------------------------===// +inline bool Server::write_response(Stream &strm, bool close_connection, + const Request &req, Response &res) { + return write_response_core(strm, close_connection, req, res, false); +} +inline bool Server::write_response_with_content(Stream &strm, + bool close_connection, + const Request &req, + Response &res) { + return write_response_core(strm, close_connection, req, res, true); +} +inline bool Server::write_response_core(Stream &strm, bool close_connection, + const Request &req, Response &res, + bool need_apply_ranges) { + assert(res.status != -1); + if (400 <= res.status && error_handler_ && + error_handler_(req, res) == HandlerResponse::Handled) { + need_apply_ranges = true; + } + std::string content_type; + std::string boundary; + if (need_apply_ranges) { apply_ranges(req, res, content_type, boundary); } + // Prepare additional headers + if (close_connection || req.get_header_value("Connection") == "close") { + res.set_header("Connection", "close"); + } else { + std::stringstream ss; + ss << "timeout=" << keep_alive_timeout_sec_ + << ", max=" << keep_alive_max_count_; + res.set_header("Keep-Alive", ss.str()); + } -namespace duckdb { + if (!res.has_header("Content-Type") && + (!res.body.empty() || res.content_length_ > 0 || res.content_provider_)) { + res.set_header("Content-Type", "text/plain"); + } -class UpdateRelation : public Relation { -public: - UpdateRelation(ClientContext &context, unique_ptr condition, string schema_name, - string table_name, vector update_columns, vector> expressions); + if (!res.has_header("Content-Length") && res.body.empty() && + !res.content_length_ && !res.content_provider_) { + res.set_header("Content-Length", "0"); + } - vector columns; - unique_ptr condition; - string schema_name; - string table_name; - vector update_columns; - vector> expressions; + if (!res.has_header("Accept-Ranges") && req.method == "HEAD") { + res.set_header("Accept-Ranges", "bytes"); + } -public: - BoundStatement Bind(Binder &binder) override; - const vector &Columns() override; - string ToString(idx_t depth) override; - bool IsReadOnly() override { - return false; - } -}; + if (post_routing_handler_) { post_routing_handler_(req, res); } -} // namespace duckdb + // Response line and headers + { + detail::BufferStream bstrm; + if (!bstrm.write_format("HTTP/1.1 %d %s\r\n", res.status, + detail::status_message(res.status))) { + return false; + } + if (!detail::write_headers(bstrm, res, Headers())) { return false; } -namespace duckdb { + // Flush buffer + auto &data = bstrm.get_buffer(); + strm.write(data.data(), data.size()); + } -TableRelation::TableRelation(ClientContext &context, unique_ptr description) - : Relation(context, RelationType::TABLE_RELATION), description(move(description)) { -} + // Body + auto ret = true; + if (req.method != "HEAD") { + if (!res.body.empty()) { + if (!strm.write(res.body)) { ret = false; } + } else if (res.content_provider_) { + if (!write_content_with_provider(strm, req, res, boundary, + content_type)) { + ret = false; + } + } + } -unique_ptr TableRelation::GetQueryNode() { - auto result = make_unique(); - result->select_list.push_back(make_unique()); - result->from_table = GetTableRef(); - return move(result); -} + // Log + if (logger_) { logger_(req, res); } -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 ret; } -string TableRelation::GetAlias() { - return description->table; -} +inline bool +Server::write_content_with_provider(Stream &strm, const Request &req, + Response &res, const std::string &boundary, + const std::string &content_type) { + auto is_shutting_down = [this]() { + return this->svr_sock_ == INVALID_SOCKET; + }; -const vector &TableRelation::Columns() { - return description->columns; -} + if (res.content_length_ > 0) { + if (req.ranges.empty()) { + return detail::write_content(strm, res.content_provider_, 0, + res.content_length_, is_shutting_down); + } else if (req.ranges.size() == 1) { + auto offsets = + detail::get_range_offset_and_length(req, res.content_length_, 0); + auto offset = offsets.first; + auto length = offsets.second; + return detail::write_content(strm, res.content_provider_, offset, length, + is_shutting_down); + } else { + return detail::write_multipart_ranges_data( + strm, req, res, boundary, content_type, is_shutting_down); + } + } else { + if (res.is_chunked_content_provider_) { + auto type = detail::encoding_type(req, res); -string TableRelation::ToString(idx_t depth) { - return RenderWhitespace(depth) + "Scan Table [" + description->table + "]"; + std::unique_ptr compressor; + if (type == detail::EncodingType::Gzip) { +#ifdef CPPHTTPLIB_ZLIB_SUPPORT + compressor = detail::make_unique(); +#endif + } else if (type == detail::EncodingType::Brotli) { +#ifdef CPPHTTPLIB_BROTLI_SUPPORT + compressor = detail::make_unique(); +#endif + } else { + compressor = detail::make_unique(); + } + assert(compressor != nullptr); + + return detail::write_content_chunked(strm, res.content_provider_, + is_shutting_down, *compressor); + } else { + return detail::write_content_without_length(strm, res.content_provider_, + is_shutting_down); + } + } } -static unique_ptr ParseCondition(const string &condition) { - if (!condition.empty()) { - auto expression_list = Parser::ParseExpressionList(condition); - if (expression_list.size() != 1) { - throw ParserException("Expected a single expression as filter condition"); - } - return move(expression_list[0]); - } else { - return nullptr; - } +inline bool Server::read_content(Stream &strm, Request &req, Response &res) { + MultipartFormDataMap::iterator cur; + if (read_content_core( + strm, req, res, + // Regular + [&](const char *buf, size_t n) { + if (req.body.size() + n > req.body.max_size()) { return false; } + req.body.append(buf, n); + return true; + }, + // Multipart + [&](const MultipartFormData &file) { + cur = req.files.emplace(file.name, file); + return true; + }, + [&](const char *buf, size_t n) { + auto &content = cur->second.content; + if (content.size() + n > content.max_size()) { return false; } + content.append(buf, n); + return true; + })) { + const auto &content_type = req.get_header_value("Content-Type"); + if (!content_type.find("application/x-www-form-urlencoded")) { + detail::parse_query_text(req.body, req.params); + } + return true; + } + return false; } -void TableRelation::Update(const string &update_list, const string &condition) { - vector update_columns; - vector> expressions; - auto cond = ParseCondition(condition); - Parser::ParseUpdateList(update_list, update_columns, expressions); - auto update = make_shared(context, move(cond), description->schema, description->table, - move(update_columns), move(expressions)); - update->Execute(); +inline bool Server::read_content_with_content_receiver( + Stream &strm, Request &req, Response &res, ContentReceiver receiver, + MultipartContentHeader multipart_header, + ContentReceiver multipart_receiver) { + return read_content_core(strm, req, res, std::move(receiver), + std::move(multipart_header), + std::move(multipart_receiver)); } -void TableRelation::Delete(const string &condition) { - auto cond = ParseCondition(condition); - auto del = make_shared(context, move(cond), description->schema, description->table); - del->Execute(); -} +inline bool Server::read_content_core(Stream &strm, Request &req, Response &res, + ContentReceiver receiver, + MultipartContentHeader mulitpart_header, + ContentReceiver multipart_receiver) { + detail::MultipartFormDataParser multipart_form_data_parser; + ContentReceiverWithProgress out; -} // namespace duckdb + if (req.is_multipart_form_data()) { + const auto &content_type = req.get_header_value("Content-Type"); + std::string boundary; + if (!detail::parse_multipart_boundary(content_type, boundary)) { + res.status = 400; + return false; + } -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/statement/update_statement.hpp -// -// -//===----------------------------------------------------------------------===// + multipart_form_data_parser.set_boundary(std::move(boundary)); + out = [&](const char *buf, size_t n, uint64_t /*off*/, uint64_t /*len*/) { + /* For debug + size_t pos = 0; + while (pos < n) { + auto read_size = std::min(1, n - pos); + auto ret = multipart_form_data_parser.parse( + buf + pos, read_size, multipart_receiver, mulitpart_header); + if (!ret) { return false; } + pos += read_size; + } + return true; + */ + return multipart_form_data_parser.parse(buf, n, multipart_receiver, + mulitpart_header); + }; + } else { + out = [receiver](const char *buf, size_t n, uint64_t /*off*/, + uint64_t /*len*/) { return receiver(buf, n); }; + } + if (req.method == "DELETE" && !req.has_header("Content-Length")) { + return true; + } + if (!detail::read_content(strm, req, payload_max_length_, res.status, nullptr, + out, true)) { + return false; + } + if (req.is_multipart_form_data()) { + if (!multipart_form_data_parser.is_valid()) { + res.status = 400; + return false; + } + } + return true; +} +inline bool Server::handle_file_request(const Request &req, Response &res, + bool head) { + for (const auto &entry : base_dirs_) { + // Prefix match + if (!req.path.compare(0, entry.mount_point.size(), entry.mount_point)) { + std::string sub_path = "/" + req.path.substr(entry.mount_point.size()); + if (detail::is_valid_path(sub_path)) { + auto path = entry.base_dir + sub_path; + if (path.back() == '/') { path += "index.html"; } + + if (detail::is_file(path)) { + detail::read_file(path, res.body); + auto type = + detail::find_content_type(path, file_extension_and_mimetype_map_); + if (type) { res.set_header("Content-Type", type); } + for (const auto &kv : entry.headers) { + res.set_header(kv.first.c_str(), kv.second); + } + res.status = req.has_header("Range") ? 206 : 200; + if (!head && file_request_handler_) { + file_request_handler_(req, res); + } + return true; + } + } + } + } + return false; +} +inline socket_t +Server::create_server_socket(const char *host, int port, int socket_flags, + SocketOptions socket_options) const { + return detail::create_socket( + host, port, socket_flags, tcp_nodelay_, std::move(socket_options), + [](socket_t sock, struct addrinfo &ai) -> bool { + if (::bind(sock, ai.ai_addr, static_cast(ai.ai_addrlen))) { + return false; + } + if (::listen(sock, 5)) { // Listen through 5 channels + return false; + } + return true; + }); +} +inline int Server::bind_internal(const char *host, int port, int socket_flags) { + if (!is_valid()) { return -1; } -namespace duckdb { + svr_sock_ = create_server_socket(host, port, socket_flags, socket_options_); + if (svr_sock_ == INVALID_SOCKET) { return -1; } -class UpdateStatement : public SQLStatement { -public: - UpdateStatement(); + if (port == 0) { + struct sockaddr_storage addr; + socklen_t addr_len = sizeof(addr); + if (getsockname(svr_sock_, reinterpret_cast(&addr), + &addr_len) == -1) { + return -1; + } + if (addr.ss_family == AF_INET) { + return ntohs(reinterpret_cast(&addr)->sin_port); + } else if (addr.ss_family == AF_INET6) { + return ntohs(reinterpret_cast(&addr)->sin6_port); + } else { + return -1; + } + } else { + return port; + } +} - unique_ptr condition; - unique_ptr table; - unique_ptr from_table; - vector columns; - vector> expressions; +inline bool Server::listen_internal() { + auto ret = true; + is_running_ = true; -public: - unique_ptr Copy() const override; -}; + { + std::unique_ptr task_queue(new_task_queue()); -} // namespace duckdb + while (svr_sock_ != INVALID_SOCKET) { +#ifndef _WIN32 + if (idle_interval_sec_ > 0 || idle_interval_usec_ > 0) { +#endif + auto val = detail::select_read(svr_sock_, idle_interval_sec_, + idle_interval_usec_); + if (val == 0) { // Timeout + task_queue->on_idle(); + continue; + } +#ifndef _WIN32 + } +#endif + socket_t sock = accept(svr_sock_, nullptr, nullptr); + if (sock == INVALID_SOCKET) { + if (errno == EMFILE) { + // The per-process limit of open file descriptors has been reached. + // Try to accept new connections after a short sleep. + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + continue; + } + if (svr_sock_ != INVALID_SOCKET) { + detail::close_socket(svr_sock_); + ret = false; + } else { + ; // The server socket was closed by user. + } + break; + } +#if __cplusplus > 201703L + task_queue->enqueue([=, this]() { process_and_close_socket(sock); }); +#else + task_queue->enqueue([=]() { process_and_close_socket(sock); }); +#endif + } + task_queue->shutdown(); + } + is_running_ = false; + return ret; +} -namespace duckdb { +inline bool Server::routing(Request &req, Response &res, Stream &strm) { + if (pre_routing_handler_ && + pre_routing_handler_(req, res) == HandlerResponse::Handled) { + return true; + } -UpdateRelation::UpdateRelation(ClientContext &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)) { - D_ASSERT(update_columns.size() == expressions.size()); - context.TryBindRelation(*this, this->columns); -} + // File handler + bool is_head_request = req.method == "HEAD"; + if ((req.method == "GET" || is_head_request) && + handle_file_request(req, res, is_head_request)) { + return true; + } -BoundStatement UpdateRelation::Bind(Binder &binder) { - auto basetable = make_unique(); - basetable->schema_name = schema_name; - basetable->table_name = table_name; + if (detail::expect_content(req)) { + // Content reader handler + { + ContentReader reader( + [&](ContentReceiver receiver) { + return read_content_with_content_receiver( + strm, req, res, std::move(receiver), nullptr, nullptr); + }, + [&](MultipartContentHeader header, ContentReceiver receiver) { + return read_content_with_content_receiver(strm, req, res, nullptr, + std::move(header), + std::move(receiver)); + }); + + if (req.method == "POST") { + if (dispatch_request_for_content_reader( + req, res, std::move(reader), + post_handlers_for_content_reader_)) { + return true; + } + } else if (req.method == "PUT") { + if (dispatch_request_for_content_reader( + req, res, std::move(reader), + put_handlers_for_content_reader_)) { + return true; + } + } else if (req.method == "PATCH") { + if (dispatch_request_for_content_reader( + req, res, std::move(reader), + patch_handlers_for_content_reader_)) { + return true; + } + } else if (req.method == "DELETE") { + if (dispatch_request_for_content_reader( + req, res, std::move(reader), + delete_handlers_for_content_reader_)) { + return true; + } + } + } - UpdateStatement stmt; - stmt.condition = condition ? condition->Copy() : nullptr; - stmt.table = move(basetable); - stmt.columns = update_columns; - for (auto &expr : expressions) { - stmt.expressions.push_back(expr->Copy()); - } - return binder.Bind((SQLStatement &)stmt); -} + // Read content into `req.body` + if (!read_content(strm, req, res)) { return false; } + } -const vector &UpdateRelation::Columns() { - return columns; + // Regular handler + if (req.method == "GET" || req.method == "HEAD") { + return dispatch_request(req, res, get_handlers_); + } else if (req.method == "POST") { + return dispatch_request(req, res, post_handlers_); + } else if (req.method == "PUT") { + return dispatch_request(req, res, put_handlers_); + } else if (req.method == "DELETE") { + return dispatch_request(req, res, delete_handlers_); + } else if (req.method == "OPTIONS") { + return dispatch_request(req, res, options_handlers_); + } else if (req.method == "PATCH") { + return dispatch_request(req, res, patch_handlers_); + } + + res.status = 400; + return false; } -string UpdateRelation::ToString(idx_t depth) { - string str = RenderWhitespace(depth) + "UPDATE " + table_name + " SET\n"; - for (idx_t i = 0; i < expressions.size(); i++) { - str += update_columns[i] + " = " + expressions[i]->ToString() + "\n"; - } - if (condition) { - str += "WHERE " + condition->ToString() + "\n"; - } - return str; +inline bool Server::dispatch_request(Request &req, Response &res, + const Handlers &handlers) { + for (const auto &x : handlers) { + const auto &pattern = x.first; + const auto &handler = x.second; + + if (std::regex_match(req.path, req.matches, pattern)) { + handler(req, res); + return true; + } + } + return false; } -} // namespace duckdb +inline void Server::apply_ranges(const Request &req, Response &res, + std::string &content_type, + std::string &boundary) { + if (req.ranges.size() > 1) { + boundary = detail::make_multipart_data_boundary(); + auto it = res.headers.find("Content-Type"); + if (it != res.headers.end()) { + content_type = it->second; + res.headers.erase(it); + } + res.headers.emplace("Content-Type", + "multipart/byteranges; boundary=" + boundary); + } -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/tableref/expressionlistref.hpp -// -// -//===----------------------------------------------------------------------===// + auto type = detail::encoding_type(req, res); + + if (res.body.empty()) { + if (res.content_length_ > 0) { + size_t length = 0; + if (req.ranges.empty()) { + length = res.content_length_; + } else if (req.ranges.size() == 1) { + auto offsets = + detail::get_range_offset_and_length(req, res.content_length_, 0); + auto offset = offsets.first; + length = offsets.second; + auto content_range = detail::make_content_range_header_field( + offset, length, res.content_length_); + res.set_header("Content-Range", content_range); + } else { + length = detail::get_multipart_ranges_data_length(req, res, boundary, + content_type); + } + res.set_header("Content-Length", std::to_string(length)); + } else { + if (res.content_provider_) { + if (res.is_chunked_content_provider_) { + res.set_header("Transfer-Encoding", "chunked"); + if (type == detail::EncodingType::Gzip) { + res.set_header("Content-Encoding", "gzip"); + } else if (type == detail::EncodingType::Brotli) { + res.set_header("Content-Encoding", "br"); + } + } + } + } + } else { + if (req.ranges.empty()) { + ; + } else if (req.ranges.size() == 1) { + auto offsets = + detail::get_range_offset_and_length(req, res.body.size(), 0); + auto offset = offsets.first; + auto length = offsets.second; + auto content_range = detail::make_content_range_header_field( + offset, length, res.body.size()); + res.set_header("Content-Range", content_range); + if (offset < res.body.size()) { + res.body = res.body.substr(offset, length); + } else { + res.body.clear(); + res.status = 416; + } + } else { + std::string data; + if (detail::make_multipart_ranges_data(req, res, boundary, content_type, + data)) { + res.body.swap(data); + } else { + res.body.clear(); + res.status = 416; + } + } + if (type != detail::EncodingType::None) { + std::unique_ptr compressor; + std::string content_encoding; + if (type == detail::EncodingType::Gzip) { +#ifdef CPPHTTPLIB_ZLIB_SUPPORT + compressor = detail::make_unique(); + content_encoding = "gzip"; +#endif + } else if (type == detail::EncodingType::Brotli) { +#ifdef CPPHTTPLIB_BROTLI_SUPPORT + compressor = detail::make_unique(); + content_encoding = "br"; +#endif + } + if (compressor) { + std::string compressed; + if (compressor->compress(res.body.data(), res.body.size(), true, + [&](const char *data, size_t data_len) { + compressed.append(data, data_len); + return true; + })) { + res.body.swap(compressed); + res.set_header("Content-Encoding", content_encoding); + } + } + } + auto length = std::to_string(res.body.size()); + res.set_header("Content-Length", length); + } +} +inline bool Server::dispatch_request_for_content_reader( + Request &req, Response &res, ContentReader content_reader, + const HandlersForContentReader &handlers) { + for (const auto &x : handlers) { + const auto &pattern = x.first; + const auto &handler = x.second; + if (std::regex_match(req.path, req.matches, pattern)) { + handler(req, res, content_reader); + return true; + } + } + return false; +} +inline bool +Server::process_request(Stream &strm, bool close_connection, + bool &connection_closed, + const std::function &setup_request) { + std::array buf{}; -namespace duckdb { -//! Represents an expression list as generated by a VALUES statement -class ExpressionListRef : public TableRef { -public: - ExpressionListRef() : TableRef(TableReferenceType::EXPRESSION_LIST) { - } + detail::stream_line_reader line_reader(strm, buf.data(), buf.size()); - //! Value list, only used for VALUES statement - vector>> values; - //! Expected SQL types - vector expected_types; - //! The set of expected names - vector expected_names; + // Connection has been closed on client + if (!line_reader.getline()) { return false; } -public: - bool Equals(const TableRef *other_p) const override; + Request req; + Response res; - unique_ptr Copy() override; + res.version = "HTTP/1.1"; - //! Serializes a blob into a ExpressionListRef - void Serialize(Serializer &serializer) override; - //! Deserializes a blob back into a ExpressionListRef - static unique_ptr Deserialize(Deserializer &source); -}; -} // namespace duckdb +#ifdef _WIN32 + // TODO: Increase FD_SETSIZE statically (libzmq), dynamically (MySQL). +#else +#ifndef CPPHTTPLIB_USE_POLL + // Socket file descriptor exceeded FD_SETSIZE... + if (strm.socket() >= FD_SETSIZE) { + Headers dummy; + detail::read_headers(strm, dummy); + res.status = 500; + return write_response(strm, close_connection, req, res); + } +#endif +#endif + // Check if the request URI doesn't exceed the limit + if (line_reader.size() > CPPHTTPLIB_REQUEST_URI_MAX_LENGTH) { + Headers dummy; + detail::read_headers(strm, dummy); + res.status = 414; + return write_response(strm, close_connection, req, res); + } + // Request line and headers + if (!parse_request_line(line_reader.ptr(), req) || + !detail::read_headers(strm, req.headers)) { + res.status = 400; + return write_response(strm, close_connection, req, res); + } + if (req.get_header_value("Connection") == "close") { + connection_closed = true; + } + if (req.version == "HTTP/1.0" && + req.get_header_value("Connection") != "Keep-Alive") { + connection_closed = true; + } -namespace duckdb { + strm.get_remote_ip_and_port(req.remote_addr, req.remote_port); + req.set_header("REMOTE_ADDR", req.remote_addr); + req.set_header("REMOTE_PORT", std::to_string(req.remote_port)); -ValueRelation::ValueRelation(ClientContext &context, const vector> &values, vector names_p, - string alias_p) - : Relation(context, RelationType::VALUE_LIST_RELATION), names(move(names_p)), alias(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]; - vector> expressions; - 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)); - } - context.TryBindRelation(*this, this->columns); + if (req.has_header("Range")) { + const auto &range_header_value = req.get_header_value("Range"); + if (!detail::parse_range_header(range_header_value, req.ranges)) { + res.status = 416; + return write_response(strm, close_connection, req, res); + } + } + + if (setup_request) { setup_request(req); } + + if (req.get_header_value("Expect") == "100-continue") { + auto status = 100; + if (expect_100_continue_handler_) { + status = expect_100_continue_handler_(req, res); + } + switch (status) { + case 100: + case 417: + strm.write_format("HTTP/1.1 %d %s\r\n\r\n", status, + detail::status_message(status)); + break; + default: return write_response(strm, close_connection, req, res); + } + } + + // Rounting + bool routed = false; + try { + routed = routing(req, res, strm); + } catch (std::exception & e) { + if (exception_handler_) { + exception_handler_(req, res, e); + routed = true; + } else { + res.status = 500; + res.set_header("EXCEPTION_WHAT", e.what()); + } + } catch (...) { + res.status = 500; + res.set_header("EXCEPTION_WHAT", "UNKNOWN"); + } + + if (routed) { + if (res.status == -1) { res.status = req.ranges.empty() ? 200 : 206; } + return write_response_with_content(strm, close_connection, req, res); + } else { + if (res.status == -1) { res.status = 404; } + return write_response(strm, close_connection, req, res); + } } -ValueRelation::ValueRelation(ClientContext &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)) { - this->expressions = Parser::ParseValuesList(values_list); - context.TryBindRelation(*this, this->columns); +inline bool Server::is_valid() const { return true; } + +inline bool Server::process_and_close_socket(socket_t sock) { + auto ret = detail::process_server_socket( + sock, keep_alive_max_count_, keep_alive_timeout_sec_, read_timeout_sec_, + read_timeout_usec_, write_timeout_sec_, write_timeout_usec_, + [this](Stream &strm, bool close_connection, bool &connection_closed) { + return process_request(strm, close_connection, connection_closed, + nullptr); + }); + + detail::shutdown_socket(sock); + detail::close_socket(sock); + return ret; } -unique_ptr ValueRelation::GetQueryNode() { - auto result = make_unique(); - result->select_list.push_back(make_unique()); - result->from_table = GetTableRef(); - return move(result); +// HTTP client implementation +inline ClientImpl::ClientImpl(const std::string &host) + : ClientImpl(host, 80, std::string(), std::string()) {} + +inline ClientImpl::ClientImpl(const std::string &host, int port) + : ClientImpl(host, port, std::string(), std::string()) {} + +inline ClientImpl::ClientImpl(const std::string &host, int port, + const std::string &client_cert_path, + const std::string &client_key_path) + // : (Error::Success), host_(host), port_(port), + : host_(host), port_(port), + host_and_port_(host_ + ":" + std::to_string(port_)), + client_cert_path_(client_cert_path), client_key_path_(client_key_path) {} + +inline ClientImpl::~ClientImpl() { lock_socket_and_shutdown_and_close(); } + +inline bool ClientImpl::is_valid() const { return true; } + +inline void ClientImpl::copy_settings(const ClientImpl &rhs) { + client_cert_path_ = rhs.client_cert_path_; + client_key_path_ = rhs.client_key_path_; + connection_timeout_sec_ = rhs.connection_timeout_sec_; + read_timeout_sec_ = rhs.read_timeout_sec_; + read_timeout_usec_ = rhs.read_timeout_usec_; + write_timeout_sec_ = rhs.write_timeout_sec_; + write_timeout_usec_ = rhs.write_timeout_usec_; + basic_auth_username_ = rhs.basic_auth_username_; + basic_auth_password_ = rhs.basic_auth_password_; + bearer_token_auth_token_ = rhs.bearer_token_auth_token_; +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + digest_auth_username_ = rhs.digest_auth_username_; + digest_auth_password_ = rhs.digest_auth_password_; +#endif + keep_alive_ = rhs.keep_alive_; + follow_location_ = rhs.follow_location_; + tcp_nodelay_ = rhs.tcp_nodelay_; + socket_options_ = rhs.socket_options_; + compress_ = rhs.compress_; + decompress_ = rhs.decompress_; + interface_ = rhs.interface_; + proxy_host_ = rhs.proxy_host_; + proxy_port_ = rhs.proxy_port_; + proxy_basic_auth_username_ = rhs.proxy_basic_auth_username_; + proxy_basic_auth_password_ = rhs.proxy_basic_auth_password_; + proxy_bearer_token_auth_token_ = rhs.proxy_bearer_token_auth_token_; +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + proxy_digest_auth_username_ = rhs.proxy_digest_auth_username_; + proxy_digest_auth_password_ = rhs.proxy_digest_auth_password_; +#endif +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + server_certificate_verification_ = rhs.server_certificate_verification_; +#endif + logger_ = rhs.logger_; } -unique_ptr ValueRelation::GetTableRef() { - auto table_ref = make_unique(); - // set the expected types/names - if (columns.empty()) { - // no columns yet: only set up names - for (idx_t i = 0; i < names.size(); i++) { - table_ref->expected_names.push_back(names[i]); - } - } else { - for (idx_t i = 0; i < columns.size(); i++) { - table_ref->expected_names.push_back(columns[i].name); - table_ref->expected_types.push_back(columns[i].type); - D_ASSERT(names.size() == 0 || columns[i].name == names[i]); - } - } - // copy the expressions - for (auto &expr_list : expressions) { - vector> copied_list; - copied_list.reserve(expr_list.size()); - for (auto &expr : expr_list) { - copied_list.push_back(expr->Copy()); - } - table_ref->values.push_back(move(copied_list)); - } - table_ref->alias = GetAlias(); - return move(table_ref); +inline socket_t ClientImpl::create_client_socket(Error &error) const { + if (!proxy_host_.empty() && proxy_port_ != -1) { + return detail::create_client_socket( + proxy_host_.c_str(), proxy_port_, tcp_nodelay_, socket_options_, + connection_timeout_sec_, connection_timeout_usec_, interface_, error); + } + return detail::create_client_socket( + host_.c_str(), port_, tcp_nodelay_, socket_options_, + connection_timeout_sec_, connection_timeout_usec_, interface_, error); } -string ValueRelation::GetAlias() { - return alias; +inline bool ClientImpl::create_and_connect_socket(Socket &socket, + Error &error) { + auto sock = create_client_socket(error); + if (sock == INVALID_SOCKET) { return false; } + socket.sock = sock; + return true; } -const vector &ValueRelation::Columns() { - return columns; +inline void ClientImpl::shutdown_ssl(Socket & /*socket*/, + bool /*shutdown_gracefully*/) { + // If there are any requests in flight from threads other than us, then it's + // a thread-unsafe race because individual ssl* objects are not thread-safe. + assert(socket_requests_in_flight_ == 0 || + socket_requests_are_from_thread_ == std::this_thread::get_id()); } -string ValueRelation::ToString(idx_t depth) { - string str = RenderWhitespace(depth) + "Values "; - for (idx_t row_idx = 0; row_idx < expressions.size(); row_idx++) { - auto &list = expressions[row_idx]; - str += row_idx > 0 ? ", (" : "("; - for (idx_t col_idx = 0; col_idx < list.size(); col_idx++) { - str += col_idx > 0 ? ", " : ""; - str += list[col_idx]->ToString(); - } - str += ")"; - } - str += "\n"; - return str; +inline void ClientImpl::shutdown_socket(Socket &socket) { + if (socket.sock == INVALID_SOCKET) { return; } + detail::shutdown_socket(socket.sock); } -} // namespace duckdb +inline void ClientImpl::close_socket(Socket &socket) { + // If there are requests in flight in another thread, usually closing + // the socket will be fine and they will simply receive an error when + // using the closed socket, but it is still a bug since rarely the OS + // may reassign the socket id to be used for a new socket, and then + // suddenly they will be operating on a live socket that is different + // than the one they intended! + assert(socket_requests_in_flight_ == 0 || + socket_requests_are_from_thread_ == std::this_thread::get_id()); + // It is also a bug if this happens while SSL is still active +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + assert(socket.ssl == nullptr); +#endif + if (socket.sock == INVALID_SOCKET) { return; } + detail::close_socket(socket.sock); + socket.sock = INVALID_SOCKET; +} +inline void ClientImpl::lock_socket_and_shutdown_and_close() { + std::lock_guard guard(socket_mutex_); + shutdown_ssl(socket_, true); + shutdown_socket(socket_); + close_socket(socket_); +} +inline bool ClientImpl::read_response_line(Stream &strm, const Request &req, + Response &res) { + std::array buf; + detail::stream_line_reader line_reader(strm, buf.data(), buf.size()); + if (!line_reader.getline()) { return false; } + const static std::regex re("(HTTP/1\\.[01]) (\\d{3}) (.*?)\r\n"); -namespace duckdb { + std::cmatch m; + if (!std::regex_match(line_reader.ptr(), m, re)) { + return req.method == "CONNECT"; + } + res.version = std::string(m[1]); + res.status = std::stoi(std::string(m[2])); + res.reason = std::string(m[3]); + + // Ignore '100 Continue' + while (res.status == 100) { + if (!line_reader.getline()) { return false; } // CRLF + if (!line_reader.getline()) { return false; } // next response line + + if (!std::regex_match(line_reader.ptr(), m, re)) { return false; } + res.version = std::string(m[1]); + res.status = std::stoi(std::string(m[2])); + res.reason = std::string(m[3]); + } -ViewRelation::ViewRelation(ClientContext &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)) { - context.TryBindRelation(*this, this->columns); + return true; } -unique_ptr ViewRelation::GetQueryNode() { - auto result = make_unique(); - result->select_list.push_back(make_unique()); - result->from_table = GetTableRef(); - return move(result); -} +inline bool ClientImpl::send(const Request &req, Response &res, Error &error) { + std::lock_guard request_mutex_guard(request_mutex_); -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); -} + { + std::lock_guard guard(socket_mutex_); + // Set this to false immediately - if it ever gets set to true by the end of + // the request, we know another thread instructed us to close the socket. + socket_should_be_closed_when_request_is_done_ = false; + + auto is_alive = false; + if (socket_.is_open()) { + is_alive = detail::select_write(socket_.sock, 0, 0) > 0; + if (!is_alive) { + // Attempt to avoid sigpipe by shutting down nongracefully if it seems + // like the other side has already closed the connection Also, there + // cannot be any requests in flight from other threads since we locked + // request_mutex_, so safe to close everything immediately + const bool shutdown_gracefully = false; + shutdown_ssl(socket_, shutdown_gracefully); + shutdown_socket(socket_); + close_socket(socket_); + } + } -string ViewRelation::GetAlias() { - return view_name; -} + if (!is_alive) { + if (!create_and_connect_socket(socket_, error)) { return false; } + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + // TODO: refactoring + if (is_ssl()) { + auto &scli = static_cast(*this); + if (!proxy_host_.empty() && proxy_port_ != -1) { + bool success = false; + if (!scli.connect_with_proxy(socket_, res, success, error)) { + return success; + } + } -const vector &ViewRelation::Columns() { - return columns; + if (!scli.initialize_ssl(socket_, error)) { return false; } + } +#endif + } + + // Mark the current socket as being in use so that it cannot be closed by + // anyone else while this request is ongoing, even though we will be + // releasing the mutex. + if (socket_requests_in_flight_ > 1) { + assert(socket_requests_are_from_thread_ == std::this_thread::get_id()); + } + socket_requests_in_flight_ += 1; + socket_requests_are_from_thread_ = std::this_thread::get_id(); + } + + auto close_connection = !keep_alive_; + auto ret = process_socket(socket_, [&](Stream &strm) { + return handle_request(strm, req, res, close_connection, error); + }); + + // Briefly lock mutex in order to mark that a request is no longer ongoing + { + std::lock_guard guard(socket_mutex_); + socket_requests_in_flight_ -= 1; + if (socket_requests_in_flight_ <= 0) { + assert(socket_requests_in_flight_ == 0); + socket_requests_are_from_thread_ = std::thread::id(); + } + + if (socket_should_be_closed_when_request_is_done_ || close_connection || + !ret) { + shutdown_ssl(socket_, true); + shutdown_socket(socket_); + close_socket(socket_); + } + } + + if (!ret) { + if (error == Error::Success) { error = Error::Unknown; } + } + + return ret; } -string ViewRelation::ToString(idx_t depth) { - return RenderWhitespace(depth) + "View [" + view_name + "]"; +inline Result ClientImpl::send(const Request &req) { + auto res = detail::make_unique(); + auto error = Error::Success; + auto ret = send(req, *res, error); + return Result{ret ? std::move(res) : nullptr, error}; } -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/relation/write_csv_relation.hpp -// -// -//===----------------------------------------------------------------------===// +inline bool ClientImpl::handle_request(Stream &strm, const Request &req, + Response &res, bool close_connection, + Error &error) { + if (req.path.empty()) { + error = Error::Connection; + return false; + } + bool ret; + if (!is_ssl() && !proxy_host_.empty() && proxy_port_ != -1) { + auto req2 = req; + req2.path = "http://" + host_and_port_ + req.path; + ret = process_request(strm, req2, res, close_connection, error); + } else { + ret = process_request(strm, req, res, close_connection, error); + } + if (!ret) { return false; } + if (300 < res.status && res.status < 400 && follow_location_) { + ret = redirect(req, res, error); + } -namespace duckdb { +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + if ((res.status == 401 || res.status == 407) && + req.authorization_count_ < 5) { + auto is_proxy = res.status == 407; + const auto &username = + is_proxy ? proxy_digest_auth_username_ : digest_auth_username_; + const auto &password = + is_proxy ? proxy_digest_auth_password_ : digest_auth_password_; + + if (!username.empty() && !password.empty()) { + std::map auth; + if (detail::parse_www_authenticate(res, auth, is_proxy)) { + Request new_req = req; + new_req.authorization_count_ += 1; + auto key = is_proxy ? "Proxy-Authorization" : "Authorization"; + new_req.headers.erase(key); + new_req.headers.insert(detail::make_digest_authentication_header( + req, auth, new_req.authorization_count_, detail::random_string(10), + username, password, is_proxy)); + + Response new_res; + + ret = send(new_req, new_res, error); + if (ret) { res = new_res; } + } + } + } +#endif -class WriteCSVRelation : public Relation { -public: - WriteCSVRelation(shared_ptr child, string csv_file); + return ret; +} - shared_ptr child; - string csv_file; - vector columns; +inline bool ClientImpl::redirect(const Request &req, Response &res, + Error &error) { + if (req.redirect_count_ == 0) { + error = Error::ExceedRedirectCount; + return false; + } -public: - BoundStatement Bind(Binder &binder) override; - const vector &Columns() override; - string ToString(idx_t depth) override; - bool IsReadOnly() override { - return false; - } -}; + auto location = detail::decode_url(res.get_header_value("location"), true); + if (location.empty()) { return false; } -} // namespace duckdb + const static std::regex re( + R"(^(?:(https?):)?(?://([^:/?#]*)(?::(\d+))?)?([^?#]*(?:\?[^#]*)?)(?:#.*)?)"); -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/statement/copy_statement.hpp -// -// -//===----------------------------------------------------------------------===// + std::smatch m; + if (!std::regex_match(location, m, re)) { return false; } + auto scheme = is_ssl() ? "https" : "http"; + auto next_scheme = m[1].str(); + auto next_host = m[2].str(); + auto port_str = m[3].str(); + auto next_path = m[4].str(); + auto next_port = port_; + if (!port_str.empty()) { + next_port = std::stoi(port_str); + } else if (!next_scheme.empty()) { + next_port = next_scheme == "https" ? 443 : 80; + } + if (next_scheme.empty()) { next_scheme = scheme; } + if (next_host.empty()) { next_host = host_; } + if (next_path.empty()) { next_path = "/"; } + if (next_scheme == scheme && next_host == host_ && next_port == port_) { + return detail::redirect(*this, req, res, next_path, location, error); + } else { + if (next_scheme == "https") { +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + SSLClient cli(next_host.c_str(), next_port); + cli.copy_settings(*this); + return detail::redirect(cli, req, res, next_path, location, error); +#else + return false; +#endif + } else { + ClientImpl cli(next_host.c_str(), next_port); + cli.copy_settings(*this); + return detail::redirect(cli, req, res, next_path, location, error); + } + } +} +inline bool ClientImpl::write_content_with_provider(Stream &strm, + const Request &req, + Error &error) { + auto is_shutting_down = []() { return false; }; -namespace duckdb { + if (req.is_chunked_content_provider_) { + // TODO: Brotli suport + std::unique_ptr compressor; +#ifdef CPPHTTPLIB_ZLIB_SUPPORT + if (compress_) { + compressor = detail::make_unique(); + } else +#endif + { + compressor = detail::make_unique(); + } -class CopyStatement : public SQLStatement { -public: - CopyStatement(); + return detail::write_content_chunked(strm, req.content_provider_, + is_shutting_down, *compressor, error); + } else { + return detail::write_content(strm, req.content_provider_, 0, + req.content_length_, is_shutting_down, error); + } +} // namespace CPPHTTPLIB_NAMESPACE + +inline bool ClientImpl::write_request(Stream &strm, const Request &req, + bool close_connection, Error &error) { + // Prepare additional headers + Headers headers; + if (close_connection) { headers.emplace("Connection", "close"); } + + if (!req.has_header("Host")) { + if (is_ssl()) { + if (port_ == 443) { + headers.emplace("Host", host_); + } else { + headers.emplace("Host", host_and_port_); + } + } else { + if (port_ == 80) { + headers.emplace("Host", host_); + } else { + headers.emplace("Host", host_and_port_); + } + } + } - unique_ptr info; - // The SQL statement used instead of a table when copying data out to a file - unique_ptr select_statement; + if (!req.has_header("Accept")) { headers.emplace("Accept", "*/*"); } -public: - unique_ptr Copy() const override; -}; -} // namespace duckdb + if (!req.has_header("User-Agent")) { + headers.emplace("User-Agent", "cpp-httplib/0.7"); + } + if (req.body.empty()) { + if (req.content_provider_) { + if (!req.is_chunked_content_provider_) { + auto length = std::to_string(req.content_length_); + headers.emplace("Content-Length", length); + } + } else { + if (req.method == "POST" || req.method == "PUT" || + req.method == "PATCH") { + headers.emplace("Content-Length", "0"); + } + } + } else { + if (!req.has_header("Content-Type")) { + headers.emplace("Content-Type", "text/plain"); + } + if (!req.has_header("Content-Length")) { + auto length = std::to_string(req.body.size()); + headers.emplace("Content-Length", length); + } + } + if (!basic_auth_password_.empty()) { + headers.insert(make_basic_authentication_header( + basic_auth_username_, basic_auth_password_, false)); + } + if (!proxy_basic_auth_username_.empty() && + !proxy_basic_auth_password_.empty()) { + headers.insert(make_basic_authentication_header( + proxy_basic_auth_username_, proxy_basic_auth_password_, true)); + } -namespace duckdb { + if (!bearer_token_auth_token_.empty()) { + headers.insert(make_bearer_token_authentication_header( + bearer_token_auth_token_, false)); + } -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)) { - context.TryBindRelation(*this, this->columns); -} + if (!proxy_bearer_token_auth_token_.empty()) { + headers.insert(make_bearer_token_authentication_header( + proxy_bearer_token_auth_token_, true)); + } -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"; - copy.info = move(info); - return binder.Bind((SQLStatement &)copy); -} + // Request line and headers + { + detail::BufferStream bstrm; -const vector &WriteCSVRelation::Columns() { - return columns; -} + const auto &path = detail::encode_url(req.path); + bstrm.write_format("%s %s HTTP/1.1\r\n", req.method.c_str(), path.c_str()); -string WriteCSVRelation::ToString(idx_t depth) { - string str = RenderWhitespace(depth) + "Write To CSV [" + csv_file + "]\n"; - return str + child->ToString(depth + 1); -} + detail::write_headers(bstrm, req, headers); -} // namespace duckdb + // Flush buffer + auto &data = bstrm.get_buffer(); + if (!detail::write_data(strm, data.data(), data.size())) { + error = Error::Write; + return false; + } + } + // Body + if (req.body.empty()) { + return write_content_with_provider(strm, req, error); + } else { + return detail::write_data(strm, req.body.data(), req.body.size()); + } + return true; +} +inline std::unique_ptr ClientImpl::send_with_content_provider( + const char *method, const char *path, const Headers &headers, + const char *body, size_t content_length, ContentProvider content_provider, + ContentProviderWithoutLength content_provider_without_length, + const char *content_type, Error &error) { + Request req; + req.method = method; + req.headers = default_headers_; + req.headers.insert(headers.begin(), headers.end()); + req.path = path; + if (content_type) { req.headers.emplace("Content-Type", content_type); } +#ifdef CPPHTTPLIB_ZLIB_SUPPORT + if (compress_) { req.headers.emplace("Content-Encoding", "gzip"); } +#endif +#ifdef CPPHTTPLIB_ZLIB_SUPPORT + if (compress_ && !content_provider_without_length) { + // TODO: Brotli support + detail::gzip_compressor compressor; + + if (content_provider) { + auto ok = true; + size_t offset = 0; + DataSink data_sink; + + data_sink.write = [&](const char *data, size_t data_len) { + if (ok) { + auto last = offset + data_len == content_length; + + auto ret = compressor.compress( + data, data_len, last, [&](const char *data, size_t data_len) { + req.body.append(data, data_len); + return true; + }); + + if (ret) { + offset += data_len; + } else { + ok = false; + } + } + }; + data_sink.is_writable = [&](void) { return ok && true; }; + while (ok && offset < content_length) { + if (!content_provider(offset, content_length - offset, data_sink)) { + error = Error::Canceled; + return nullptr; + } + } + } else { + if (!compressor.compress(body, content_length, true, + [&](const char *data, size_t data_len) { + req.body.append(data, data_len); + return true; + })) { + error = Error::Compression; + return nullptr; + } + } + } else +#endif + { + if (content_provider) { + req.content_length_ = content_length; + req.content_provider_ = std::move(content_provider); + req.is_chunked_content_provider_ = false; + } else if (content_provider_without_length) { + req.content_length_ = 0; + req.content_provider_ = detail::ContentProviderAdapter( + std::move(content_provider_without_length)); + req.is_chunked_content_provider_ = true; + req.headers.emplace("Transfer-Encoding", "chunked"); + } else { + req.body.assign(body, content_length); + ; + } + } + auto res = detail::make_unique(); + return send(req, *res, error) ? std::move(res) : nullptr; +} +inline Result ClientImpl::send_with_content_provider( + const char *method, const char *path, const Headers &headers, + const char *body, size_t content_length, ContentProvider content_provider, + ContentProviderWithoutLength content_provider_without_length, + const char *content_type) { + auto error = Error::Success; + auto res = send_with_content_provider( + method, path, headers, body, content_length, std::move(content_provider), + std::move(content_provider_without_length), content_type, error); + return Result{std::move(res), error}; +} +inline bool ClientImpl::process_request(Stream &strm, const Request &req, + Response &res, bool close_connection, + Error &error) { + // Send request + if (!write_request(strm, req, close_connection, error)) { return false; } + // Receive response and headers + if (!read_response_line(strm, req, res) || + !detail::read_headers(strm, res.headers)) { + error = Error::Read; + return false; + } + if (req.response_handler_) { + if (!req.response_handler_(res)) { + error = Error::Canceled; + return false; + } + } + // Body + if ((res.status != 204) && req.method != "HEAD" && req.method != "CONNECT") { + auto out = + req.content_receiver_ + ? static_cast( + [&](const char *buf, size_t n, uint64_t off, uint64_t len) { + auto ret = req.content_receiver_(buf, n, off, len); + if (!ret) { error = Error::Canceled; } + return ret; + }) + : static_cast( + [&](const char *buf, size_t n, uint64_t /*off*/, + uint64_t /*len*/) { + if (res.body.size() + n > res.body.max_size()) { + return false; + } + res.body.append(buf, n); + return true; + }); + + auto progress = [&](uint64_t current, uint64_t total) { + if (!req.progress_) { return true; } + auto ret = req.progress_(current, total); + if (!ret) { error = Error::Canceled; } + return ret; + }; + int dummy_status; + if (!detail::read_content(strm, res, (std::numeric_limits::max)(), + dummy_status, std::move(progress), std::move(out), + decompress_)) { + if (error != Error::Canceled) { error = Error::Read; } + return false; + } + } + if (res.get_header_value("Connection") == "close" || + (res.version == "HTTP/1.0" && res.reason != "Connection established")) { + // TODO this requires a not-entirely-obvious chain of calls to be correct + // for this to be safe. Maybe a code refactor (such as moving this out to + // the send function and getting rid of the recursiveness of the mutex) + // could make this more obvious. + + // This is safe to call because process_request is only called by + // handle_request which is only called by send, which locks the request + // mutex during the process. It would be a bug to call it from a different + // thread since it's a thread-safety issue to do these things to the socket + // if another thread is using the socket. + lock_socket_and_shutdown_and_close(); + } + // Log + if (logger_) { logger_(req, res); } + return true; +} +inline bool +ClientImpl::process_socket(const Socket &socket, + std::function callback) { + return detail::process_client_socket( + socket.sock, read_timeout_sec_, read_timeout_usec_, write_timeout_sec_, + write_timeout_usec_, std::move(callback)); +} +inline bool ClientImpl::is_ssl() const { return false; } +inline Result ClientImpl::Get(const char *path) { + return Get(path, Headers(), Progress()); +} +inline Result ClientImpl::Get(const char *path, Progress progress) { + return Get(path, Headers(), std::move(progress)); +} +inline Result ClientImpl::Get(const char *path, const Headers &headers) { + return Get(path, headers, Progress()); +} +inline Result ClientImpl::Get(const char *path, const Headers &headers, + Progress progress) { + Request req; + req.method = "GET"; + req.path = path; + req.headers = default_headers_; + req.headers.insert(headers.begin(), headers.end()); + req.progress_ = std::move(progress); -namespace duckdb { + return send(req); +} -shared_ptr Relation::Project(const string &select_list) { - return Project(select_list, vector()); +inline Result ClientImpl::Get(const char *path, + ContentReceiver content_receiver) { + return Get(path, Headers(), nullptr, std::move(content_receiver), nullptr); } -shared_ptr Relation::Project(const string &expression, const string &alias) { - return Project(expression, vector({alias})); +inline Result ClientImpl::Get(const char *path, + ContentReceiver content_receiver, + Progress progress) { + return Get(path, Headers(), nullptr, std::move(content_receiver), + std::move(progress)); } -shared_ptr Relation::Project(const string &select_list, const vector &aliases) { - auto expressions = Parser::ParseExpressionList(select_list); - return make_shared(shared_from_this(), move(expressions), aliases); +inline Result ClientImpl::Get(const char *path, const Headers &headers, + ContentReceiver content_receiver) { + return Get(path, headers, nullptr, std::move(content_receiver), nullptr); } -shared_ptr Relation::Project(const vector &expressions) { - vector aliases; - return Project(expressions, aliases); +inline Result ClientImpl::Get(const char *path, const Headers &headers, + ContentReceiver content_receiver, + Progress progress) { + return Get(path, headers, nullptr, std::move(content_receiver), + std::move(progress)); } -static vector> StringListToExpressionList(const vector &expressions) { - if (expressions.empty()) { - throw ParserException("Zero expressions provided"); - } - vector> result_list; - for (auto &expr : expressions) { - auto expression_list = Parser::ParseExpressionList(expr); - if (expression_list.size() != 1) { - throw ParserException("Expected a single expression in the expression list"); - } - result_list.push_back(move(expression_list[0])); - } - return result_list; +inline Result ClientImpl::Get(const char *path, + ResponseHandler response_handler, + ContentReceiver content_receiver) { + return Get(path, Headers(), std::move(response_handler), + std::move(content_receiver), nullptr); } -shared_ptr Relation::Project(const vector &expressions, const vector &aliases) { - auto result_list = StringListToExpressionList(expressions); - return make_shared(shared_from_this(), move(result_list), aliases); +inline Result ClientImpl::Get(const char *path, const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver) { + return Get(path, headers, std::move(response_handler), + std::move(content_receiver), nullptr); } -shared_ptr Relation::Filter(const string &expression) { - auto expression_list = Parser::ParseExpressionList(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])); +inline Result ClientImpl::Get(const char *path, + ResponseHandler response_handler, + ContentReceiver content_receiver, + Progress progress) { + return Get(path, Headers(), std::move(response_handler), + std::move(content_receiver), std::move(progress)); } -shared_ptr Relation::Filter(const vector &expressions) { - // if there are multiple expressions, we AND them together - auto expression_list = StringListToExpressionList(expressions); - D_ASSERT(!expression_list.empty()); +inline Result ClientImpl::Get(const char *path, const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver, + Progress progress) { + Request req; + req.method = "GET"; + req.path = path; + req.headers = default_headers_; + req.headers.insert(headers.begin(), headers.end()); + req.response_handler_ = std::move(response_handler); + req.content_receiver_ = + [content_receiver](const char *data, size_t data_length, + uint64_t /*offset*/, uint64_t /*total_length*/) { + return content_receiver(data, data_length); + }; + req.progress_ = std::move(progress); - auto expr = 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])); - } - return make_shared(shared_from_this(), move(expr)); + return send(req); } -shared_ptr Relation::Limit(int64_t limit, int64_t offset) { - return make_shared(shared_from_this(), limit, offset); -} +inline Result ClientImpl::Get(const char *path, const Params ¶ms, + const Headers &headers, Progress progress) { + if (params.empty()) { return Get(path, headers); } -shared_ptr Relation::Order(const string &expression) { - auto order_list = Parser::ParseOrderList(expression); - return make_shared(shared_from_this(), move(order_list)); + std::string path_with_query = detail::append_query_params(path, params); + return Get(path_with_query.c_str(), headers, progress); } -shared_ptr Relation::Order(const vector &expressions) { - if (expressions.empty()) { - throw ParserException("Zero ORDER BY expressions provided"); - } - vector order_list; - for (auto &expression : expressions) { - auto inner_list = Parser::ParseOrderList(expression); - 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])); - } - return make_shared(shared_from_this(), move(order_list)); +inline Result ClientImpl::Get(const char *path, const Params ¶ms, + const Headers &headers, + ContentReceiver content_receiver, + Progress progress) { + return Get(path, params, headers, nullptr, content_receiver, progress); } -shared_ptr Relation::Join(const shared_ptr &other, const string &condition, JoinType type) { - auto expression_list = Parser::ParseExpressionList(condition); - D_ASSERT(!expression_list.empty()); +inline Result ClientImpl::Get(const char *path, const Params ¶ms, + const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver, + Progress progress) { + if (params.empty()) { + return Get(path, headers, response_handler, content_receiver, progress); + } - if (expression_list.size() > 1 || expression_list[0]->type == ExpressionType::COLUMN_REF) { - // multiple columns or single column ref: the condition is a USING list - vector using_columns; - for (auto &expr : expression_list) { - if (expr->type != ExpressionType::COLUMN_REF) { - throw ParserException("Expected a single expression as join condition"); - } - auto &colref = (ColumnRefExpression &)*expr; - if (!colref.table_name.empty()) { - throw ParserException("Expected empty table name for column in USING clause"); - } - using_columns.push_back(colref.column_name); - } - return make_shared(shared_from_this(), other, 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); - } + std::string path_with_query = detail::append_query_params(path, params); + return Get(path_with_query.c_str(), params, headers, response_handler, + content_receiver, progress); } -shared_ptr Relation::Union(const shared_ptr &other) { - return make_shared(shared_from_this(), other, SetOperationType::UNION); +inline Result ClientImpl::Head(const char *path) { + return Head(path, Headers()); } -shared_ptr Relation::Except(const shared_ptr &other) { - return make_shared(shared_from_this(), other, SetOperationType::EXCEPT); +inline Result ClientImpl::Head(const char *path, const Headers &headers) { + Request req; + req.method = "HEAD"; + req.headers = default_headers_; + req.headers.insert(headers.begin(), headers.end()); + req.path = path; + + return send(req); } -shared_ptr Relation::Intersect(const shared_ptr &other) { - return make_shared(shared_from_this(), other, SetOperationType::INTERSECT); +inline Result ClientImpl::Post(const char *path) { + return Post(path, std::string(), nullptr); } -shared_ptr Relation::Distinct() { - return make_shared(shared_from_this()); +inline Result ClientImpl::Post(const char *path, const char *body, + size_t content_length, + const char *content_type) { + return Post(path, Headers(), body, content_length, content_type); } -shared_ptr Relation::Alias(const string &alias) { - return make_shared(shared_from_this(), alias); +inline Result ClientImpl::Post(const char *path, const Headers &headers, + const char *body, size_t content_length, + const char *content_type) { + return send_with_content_provider("POST", path, headers, body, content_length, + nullptr, nullptr, content_type); } -shared_ptr Relation::Aggregate(const string &aggregate_list) { - auto expression_list = Parser::ParseExpressionList(aggregate_list); - return make_shared(shared_from_this(), move(expression_list)); +inline Result ClientImpl::Post(const char *path, const std::string &body, + const char *content_type) { + return Post(path, Headers(), body, content_type); } -shared_ptr Relation::Aggregate(const string &aggregate_list, const string &group_list) { - auto expression_list = Parser::ParseExpressionList(aggregate_list); - auto groups = Parser::ParseExpressionList(group_list); - return make_shared(shared_from_this(), move(expression_list), move(groups)); +inline Result ClientImpl::Post(const char *path, const Headers &headers, + const std::string &body, + const char *content_type) { + return send_with_content_provider("POST", path, headers, body.data(), + body.size(), nullptr, nullptr, + content_type); } -shared_ptr Relation::Aggregate(const vector &aggregates) { - auto aggregate_list = StringListToExpressionList(aggregates); - return make_shared(shared_from_this(), move(aggregate_list)); +inline Result ClientImpl::Post(const char *path, const Params ¶ms) { + return Post(path, Headers(), params); } -shared_ptr Relation::Aggregate(const vector &aggregates, const vector &groups) { - auto aggregate_list = StringListToExpressionList(aggregates); - auto group_list = StringListToExpressionList(groups); - return make_shared(shared_from_this(), move(aggregate_list), move(group_list)); +inline Result ClientImpl::Post(const char *path, size_t content_length, + ContentProvider content_provider, + const char *content_type) { + return Post(path, Headers(), content_length, std::move(content_provider), + content_type); } -string Relation::GetAlias() { - return "relation"; +inline Result ClientImpl::Post(const char *path, + ContentProviderWithoutLength content_provider, + const char *content_type) { + return Post(path, Headers(), std::move(content_provider), content_type); } -unique_ptr Relation::GetTableRef() { - auto select = make_unique(); - select->node = GetQueryNode(); - return make_unique(move(select), GetAlias()); +inline Result ClientImpl::Post(const char *path, const Headers &headers, + size_t content_length, + ContentProvider content_provider, + const char *content_type) { + return send_with_content_provider("POST", path, headers, nullptr, + content_length, std::move(content_provider), + nullptr, content_type); } -unique_ptr Relation::Execute() { - return context.Execute(shared_from_this()); +inline Result ClientImpl::Post(const char *path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const char *content_type) { + return send_with_content_provider("POST", path, headers, nullptr, 0, nullptr, + std::move(content_provider), content_type); } -BoundStatement Relation::Bind(Binder &binder) { - SelectStatement stmt; - stmt.node = GetQueryNode(); - return binder.Bind((SQLStatement &)stmt); +inline Result ClientImpl::Post(const char *path, const Headers &headers, + const Params ¶ms) { + auto query = detail::params_to_query_str(params); + return Post(path, headers, query, "application/x-www-form-urlencoded"); } -void Relation::Insert(const string &table_name) { - Insert(DEFAULT_SCHEMA, table_name); +inline Result ClientImpl::Post(const char *path, + const MultipartFormDataItems &items) { + return Post(path, Headers(), items); } -void Relation::Insert(const string &schema_name, const string &table_name) { - auto insert = make_shared(shared_from_this(), schema_name, table_name); - auto res = insert->Execute(); - if (!res->success) { - throw Exception("Failed to insert into table '" + table_name + "': " + res->error); - } +inline Result ClientImpl::Post(const char *path, const Headers &headers, + const MultipartFormDataItems &items) { + return Post(path, headers, items, detail::make_multipart_data_boundary()); } +inline Result ClientImpl::Post(const char *path, const Headers &headers, + const MultipartFormDataItems &items, + const std::string &boundary) { + for (size_t i = 0; i < boundary.size(); i++) { + char c = boundary[i]; + if (!std::isalnum(c) && c != '-' && c != '_') { + return Result{nullptr, Error::UnsupportedMultipartBoundaryChars}; + } + } -void Relation::Insert(const vector> &values) { - vector column_names; - auto rel = make_shared(context, values, move(column_names), "values"); - rel->Insert(GetAlias()); + std::string body; + + for (const auto &item : items) { + body += "--" + boundary + "\r\n"; + body += "Content-Disposition: form-data; name=\"" + item.name + "\""; + if (!item.filename.empty()) { + body += "; filename=\"" + item.filename + "\""; + } + body += "\r\n"; + if (!item.content_type.empty()) { + body += "Content-Type: " + item.content_type + "\r\n"; + } + body += "\r\n"; + body += item.content + "\r\n"; + } + + body += "--" + boundary + "--\r\n"; + + std::string content_type = "multipart/form-data; boundary=" + boundary; + return Post(path, headers, body, content_type.c_str()); } -void Relation::Create(const string &table_name) { - Create(DEFAULT_SCHEMA, table_name); +inline Result ClientImpl::Put(const char *path) { + return Put(path, std::string(), nullptr); } -void Relation::Create(const string &schema_name, const string &table_name) { - auto create = make_shared(shared_from_this(), schema_name, table_name); - auto res = create->Execute(); - if (!res->success) { - throw Exception("Failed to create table '" + table_name + "': " + res->error); - } +inline Result ClientImpl::Put(const char *path, const char *body, + size_t content_length, const char *content_type) { + return Put(path, Headers(), body, content_length, content_type); } -void Relation::WriteCSV(const string &csv_file) { - auto write_csv = make_shared(shared_from_this(), csv_file); - auto res = write_csv->Execute(); - if (!res->success) { - throw Exception("Failed to write '" + csv_file + "': " + res->error); - } +inline Result ClientImpl::Put(const char *path, const Headers &headers, + const char *body, size_t content_length, + const char *content_type) { + return send_with_content_provider("PUT", path, headers, body, content_length, + nullptr, nullptr, content_type); } -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(); - if (!res->success) { - throw Exception("Failed to create view '" + name + "': " + res->error); - } - return shared_from_this(); +inline Result ClientImpl::Put(const char *path, const std::string &body, + const char *content_type) { + return Put(path, Headers(), body, content_type); } -unique_ptr Relation::Query(const string &sql) { - return context.Query(sql, false); +inline Result ClientImpl::Put(const char *path, const Headers &headers, + const std::string &body, + const char *content_type) { + return send_with_content_provider("PUT", path, headers, body.data(), + body.size(), nullptr, nullptr, + content_type); } -unique_ptr Relation::Query(const string &name, const string &sql) { - CreateView(name); - return Query(sql); +inline Result ClientImpl::Put(const char *path, size_t content_length, + ContentProvider content_provider, + const char *content_type) { + return Put(path, Headers(), content_length, std::move(content_provider), + content_type); } -unique_ptr Relation::Explain() { - auto explain = make_shared(shared_from_this()); - return explain->Execute(); +inline Result ClientImpl::Put(const char *path, + ContentProviderWithoutLength content_provider, + const char *content_type) { + return Put(path, Headers(), std::move(content_provider), content_type); } -void Relation::Update(const string &update, const string &condition) { - throw Exception("UPDATE can only be used on base tables!"); +inline Result ClientImpl::Put(const char *path, const Headers &headers, + size_t content_length, + ContentProvider content_provider, + const char *content_type) { + return send_with_content_provider("PUT", path, headers, nullptr, + content_length, std::move(content_provider), + nullptr, content_type); } -void Relation::Delete(const string &condition) { - throw Exception("DELETE can only be used on base tables!"); +inline Result ClientImpl::Put(const char *path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const char *content_type) { + return send_with_content_provider("PUT", path, headers, nullptr, 0, nullptr, + std::move(content_provider), content_type); } -shared_ptr Relation::TableFunction(const std::string &fname, const vector &values, - const unordered_map &named_parameters) { - return make_shared(context, fname, values, named_parameters, shared_from_this()); +inline Result ClientImpl::Put(const char *path, const Params ¶ms) { + return Put(path, Headers(), params); } -shared_ptr Relation::TableFunction(const std::string &fname, const vector &values) { - return make_shared(context, fname, values, shared_from_this()); +inline Result ClientImpl::Put(const char *path, const Headers &headers, + const Params ¶ms) { + auto query = detail::params_to_query_str(params); + return Put(path, headers, query, "application/x-www-form-urlencoded"); } -string Relation::ToString() { - string str; - str += "---------------------\n"; - str += "-- Expression Tree --\n"; - str += "---------------------\n"; - str += ToString(0); - str += "\n\n"; - str += "---------------------\n"; - str += "-- Result Columns --\n"; - str += "---------------------\n"; - auto &cols = Columns(); - for (idx_t i = 0; i < cols.size(); i++) { - str += "- " + cols[i].name + " (" + cols[i].type.ToString() + ")\n"; - } - return str; +inline Result ClientImpl::Patch(const char *path) { + return Patch(path, std::string(), nullptr); } -// LCOV_EXCL_START -unique_ptr Relation::GetQueryNode() { - throw InternalException("Cannot create a query node from this node type"); +inline Result ClientImpl::Patch(const char *path, const char *body, + size_t content_length, + const char *content_type) { + return Patch(path, Headers(), body, content_length, content_type); } -void Relation::Head(idx_t limit) { - auto limit_node = Limit(limit); - limit_node->Execute()->Print(); +inline Result ClientImpl::Patch(const char *path, const Headers &headers, + const char *body, size_t content_length, + const char *content_type) { + return send_with_content_provider("PATCH", path, headers, body, + content_length, nullptr, nullptr, + content_type); } -// LCOV_EXCL_STOP -void Relation::Print() { - Printer::Print(ToString()); +inline Result ClientImpl::Patch(const char *path, const std::string &body, + const char *content_type) { + return Patch(path, Headers(), body, content_type); } -string Relation::RenderWhitespace(idx_t depth) { - return string(depth * 2, ' '); +inline Result ClientImpl::Patch(const char *path, const Headers &headers, + const std::string &body, + const char *content_type) { + return send_with_content_provider("PATCH", path, headers, body.data(), + body.size(), nullptr, nullptr, + content_type); } -} // namespace duckdb +inline Result ClientImpl::Patch(const char *path, size_t content_length, + ContentProvider content_provider, + const char *content_type) { + return Patch(path, Headers(), content_length, std::move(content_provider), + content_type); +} +inline Result ClientImpl::Patch(const char *path, + ContentProviderWithoutLength content_provider, + const char *content_type) { + return Patch(path, Headers(), std::move(content_provider), content_type); +} +inline Result ClientImpl::Patch(const char *path, const Headers &headers, + size_t content_length, + ContentProvider content_provider, + const char *content_type) { + return send_with_content_provider("PATCH", path, headers, nullptr, + content_length, std::move(content_provider), + nullptr, content_type); +} +inline Result ClientImpl::Patch(const char *path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const char *content_type) { + return send_with_content_provider("PATCH", path, headers, nullptr, 0, nullptr, + std::move(content_provider), content_type); +} +inline Result ClientImpl::Delete(const char *path) { + return Delete(path, Headers(), std::string(), nullptr); +} -namespace duckdb { +inline Result ClientImpl::Delete(const char *path, const Headers &headers) { + return Delete(path, headers, std::string(), nullptr); +} -StreamQueryResult::StreamQueryResult(StatementType statement_type, shared_ptr context, - vector types, vector names, - shared_ptr prepared) - : QueryResult(QueryResultType::STREAM_RESULT, statement_type, move(types), move(names)), is_open(true), - context(move(context)), prepared(move(prepared)) { +inline Result ClientImpl::Delete(const char *path, const char *body, + size_t content_length, + const char *content_type) { + return Delete(path, Headers(), body, content_length, content_type); } -StreamQueryResult::~StreamQueryResult() { - Close(); +inline Result ClientImpl::Delete(const char *path, const Headers &headers, + const char *body, size_t content_length, + const char *content_type) { + Request req; + req.method = "DELETE"; + req.headers = default_headers_; + req.headers.insert(headers.begin(), headers.end()); + req.path = path; + + if (content_type) { req.headers.emplace("Content-Type", content_type); } + req.body.assign(body, content_length); + + return send(req); } -string StreamQueryResult::ToString() { - string result; - if (success) { - result = HeaderToString(); - result += "[[STREAM RESULT]]"; - } else { - result = error + "\n"; - } - return result; +inline Result ClientImpl::Delete(const char *path, const std::string &body, + const char *content_type) { + return Delete(path, Headers(), body.data(), body.size(), content_type); } -unique_ptr StreamQueryResult::FetchRaw() { - if (!success || !is_open) { - throw InvalidInputException( - "Attempting to fetch from an unsuccessful or closed streaming query result\nError: %s", error); - } - auto chunk = context->Fetch(); - if (!chunk || chunk->ColumnCount() == 0 || chunk->size() == 0) { - Close(); - return nullptr; - } - return chunk; +inline Result ClientImpl::Delete(const char *path, const Headers &headers, + const std::string &body, + const char *content_type) { + return Delete(path, headers, body.data(), body.size(), content_type); } -unique_ptr StreamQueryResult::Materialize() { - if (!success) { - return make_unique(error); - } - auto result = make_unique(statement_type, types, names); - while (true) { - auto chunk = Fetch(); - if (!chunk || chunk->size() == 0) { - break; - } - result->collection.Append(*chunk); - } - if (!success) { - return make_unique(error); - } - return result; +inline Result ClientImpl::Options(const char *path) { + return Options(path, Headers()); } -void StreamQueryResult::Close() { - if (!is_open) { - return; - } - is_open = false; - context->Cleanup(); +inline Result ClientImpl::Options(const char *path, const Headers &headers) { + Request req; + req.method = "OPTIONS"; + req.headers = default_headers_; + req.headers.insert(headers.begin(), headers.end()); + req.path = path; + + return send(req); } -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/optimizer/column_lifetime_optimizer.hpp -// -// -//===----------------------------------------------------------------------===// +inline size_t ClientImpl::is_socket_open() const { + std::lock_guard guard(socket_mutex_); + return socket_.is_open(); +} +inline void ClientImpl::stop() { + std::lock_guard guard(socket_mutex_); + // If there is anything ongoing right now, the ONLY thread-safe thing we can + // do is to shutdown_socket, so that threads using this socket suddenly + // discover they can't read/write any more and error out. Everything else + // (closing the socket, shutting ssl down) is unsafe because these actions are + // not thread-safe. + if (socket_requests_in_flight_ > 0) { + shutdown_socket(socket_); + // Aside from that, we set a flag for the socket to be closed when we're + // done. + socket_should_be_closed_when_request_is_done_ = true; + return; + } + // Otherwise, sitll holding the mutex, we can shut everything down ourselves + shutdown_ssl(socket_, true); + shutdown_socket(socket_); + close_socket(socket_); +} +inline void ClientImpl::set_connection_timeout(time_t sec, time_t usec) { + connection_timeout_sec_ = sec; + connection_timeout_usec_ = usec; +} +inline void ClientImpl::set_read_timeout(time_t sec, time_t usec) { + read_timeout_sec_ = sec; + read_timeout_usec_ = usec; +} -namespace duckdb { -class BoundColumnRefExpression; +inline void ClientImpl::set_write_timeout(time_t sec, time_t usec) { + write_timeout_sec_ = sec; + write_timeout_usec_ = usec; +} -//! 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) { - } +inline void ClientImpl::set_basic_auth(const char *username, + const char *password) { + basic_auth_username_ = username; + basic_auth_password_ = password; +} - void VisitOperator(LogicalOperator &op) override; +inline void ClientImpl::set_bearer_token_auth(const char *token) { + bearer_token_auth_token_ = token; +} -protected: - unique_ptr VisitReplace(BoundColumnRefExpression &expr, unique_ptr *expr_ptr) override; - unique_ptr VisitReplace(BoundReferenceExpression &expr, unique_ptr *expr_ptr) override; +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +inline void ClientImpl::set_digest_auth(const char *username, + const char *password) { + digest_auth_username_ = username; + digest_auth_password_ = password; +} +#endif -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; +inline void ClientImpl::set_keep_alive(bool on) { keep_alive_ = on; } -private: - void StandardVisitOperator(LogicalOperator &op); +inline void ClientImpl::set_follow_location(bool on) { follow_location_ = on; } - void ExtractUnusedColumnBindings(vector bindings, column_binding_set_t &unused_bindings); - void GenerateProjectionMap(vector bindings, column_binding_set_t &unused_bindings, - vector &map); -}; -} // namespace duckdb +inline void ClientImpl::set_default_headers(Headers headers) { + default_headers_ = std::move(headers); +} +inline void ClientImpl::set_tcp_nodelay(bool on) { tcp_nodelay_ = on; } +inline void ClientImpl::set_socket_options(SocketOptions socket_options) { + socket_options_ = std::move(socket_options); +} +inline void ClientImpl::set_compress(bool on) { compress_ = on; } +inline void ClientImpl::set_decompress(bool on) { decompress_ = on; } +inline void ClientImpl::set_interface(const char *intf) { interface_ = intf; } +inline void ClientImpl::set_proxy(const char *host, int port) { + proxy_host_ = host; + proxy_port_ = port; +} +inline void ClientImpl::set_proxy_basic_auth(const char *username, + const char *password) { + proxy_basic_auth_username_ = username; + proxy_basic_auth_password_ = password; +} -namespace duckdb { +inline void ClientImpl::set_proxy_bearer_token_auth(const char *token) { + proxy_bearer_token_auth_token_ = token; +} -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]); - } - } +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +inline void ClientImpl::set_proxy_digest_auth(const char *username, + const char *password) { + proxy_digest_auth_username_ = username; + proxy_digest_auth_password_ = password; } +#endif -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(); - } +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +inline void ClientImpl::enable_server_certificate_verification(bool enabled) { + server_certificate_verification_ = enabled; } +#endif -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); +inline void ClientImpl::set_logger(Logger logger) { + logger_ = std::move(logger); } -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); +/* + * SSL Implementation + */ +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +namespace detail { - // now recurse into the filter and its children - StandardVisitOperator(op); +template +inline SSL *ssl_new(socket_t sock, SSL_CTX *ctx, std::mutex &ctx_mutex, + U SSL_connect_or_accept, V setup) { + SSL *ssl = nullptr; + { + std::lock_guard guard(ctx_mutex); + ssl = SSL_new(ctx); + } - // 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); + if (ssl) { + set_nonblocking(sock, true); + auto bio = BIO_new_socket(static_cast(sock), BIO_NOCLOSE); + BIO_set_nbio(bio, 1); + SSL_set_bio(ssl, bio, bio); - // now recurse into the filter and its children - StandardVisitOperator(op); + if (!setup(ssl) || SSL_connect_or_accept(ssl) != 1) { + SSL_shutdown(ssl); + { + std::lock_guard guard(ctx_mutex); + SSL_free(ssl); + } + set_nonblocking(sock, false); + return nullptr; + } + BIO_set_nbio(bio, 0); + set_nonblocking(sock, false); + } - // then generate the projection map - GenerateProjectionMap(op.children[0]->GetColumnBindings(), unused_bindings, filter.projection_map); - return; - } - default: - break; - } - StandardVisitOperator(op); + return ssl; } -unique_ptr ColumnLifetimeAnalyzer::VisitReplace(BoundColumnRefExpression &expr, - unique_ptr *expr_ptr) { - column_references.insert(expr.binding); - return nullptr; +inline void ssl_delete(std::mutex &ctx_mutex, SSL *ssl, + bool shutdown_gracefully) { + // sometimes we may want to skip this to try to avoid SIGPIPE if we know + // the remote has closed the network connection + // Note that it is not always possible to avoid SIGPIPE, this is merely a + // best-efforts. + if (shutdown_gracefully) { SSL_shutdown(ssl); } + + std::lock_guard guard(ctx_mutex); + SSL_free(ssl); } -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!"); +template +bool ssl_connect_or_accept_nonblocking(socket_t sock, SSL *ssl, + U ssl_connect_or_accept, + time_t timeout_sec, + time_t timeout_usec) { + int res = 0; + while ((res = ssl_connect_or_accept(ssl)) != 1) { + auto err = SSL_get_error(ssl, res); + switch (err) { + case SSL_ERROR_WANT_READ: + if (select_read(sock, timeout_sec, timeout_usec) > 0) { continue; } + break; + case SSL_ERROR_WANT_WRITE: + if (select_write(sock, timeout_sec, timeout_usec) > 0) { continue; } + break; + default: break; + } + return false; + } + return true; } -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/optimizer/common_aggregate_optimizer.hpp -// -// -//===----------------------------------------------------------------------===// +template +inline bool +process_server_socket_ssl(SSL *ssl, socket_t sock, size_t keep_alive_max_count, + time_t keep_alive_timeout_sec, + time_t read_timeout_sec, time_t read_timeout_usec, + time_t write_timeout_sec, time_t write_timeout_usec, + T callback) { + return process_server_socket_core( + sock, keep_alive_max_count, keep_alive_timeout_sec, + [&](bool close_connection, bool &connection_closed) { + SSLSocketStream strm(sock, ssl, read_timeout_sec, read_timeout_usec, + write_timeout_sec, write_timeout_usec); + return callback(strm, close_connection, connection_closed); + }); +} + +template +inline bool +process_client_socket_ssl(SSL *ssl, socket_t sock, time_t read_timeout_sec, + time_t read_timeout_usec, time_t write_timeout_sec, + time_t write_timeout_usec, T callback) { + SSLSocketStream strm(sock, ssl, read_timeout_sec, read_timeout_usec, + write_timeout_sec, write_timeout_usec); + return callback(strm); +} +#if OPENSSL_VERSION_NUMBER < 0x10100000L +static std::shared_ptr> openSSL_locks_; +class SSLThreadLocks { +public: + SSLThreadLocks() { + openSSL_locks_ = + std::make_shared>(CRYPTO_num_locks()); + CRYPTO_set_locking_callback(locking_callback); + } + ~SSLThreadLocks() { CRYPTO_set_locking_callback(nullptr); } +private: + static void locking_callback(int mode, int type, const char * /*file*/, + int /*line*/) { + auto &lk = (*openSSL_locks_)[static_cast(type)]; + if (mode & CRYPTO_LOCK) { + lk.lock(); + } else { + lk.unlock(); + } + } +}; +#endif -namespace duckdb { -//! The CommonAggregateOptimizer optimizer eliminates duplicate aggregates from aggregate nodes -class CommonAggregateOptimizer : public LogicalOperatorVisitor { +class SSLInit { public: - void VisitOperator(LogicalOperator &op) override; - -private: - unique_ptr VisitReplace(BoundColumnRefExpression &expr, unique_ptr *expr_ptr) override; + SSLInit() { +#if OPENSSL_VERSION_NUMBER < 0x1010001fL + SSL_load_error_strings(); + SSL_library_init(); +#else + OPENSSL_init_ssl( + OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); +#endif + } - void ExtractCommonAggregates(LogicalAggregate &aggr); + ~SSLInit() { +#if OPENSSL_VERSION_NUMBER < 0x1010001fL + ERR_free_strings(); +#endif + } private: - column_binding_map_t aggregate_map; +#if OPENSSL_VERSION_NUMBER < 0x10100000L + SSLThreadLocks thread_init_; +#endif }; -} // namespace duckdb +// SSL socket stream implementation +inline SSLSocketStream::SSLSocketStream(socket_t sock, SSL *ssl, + time_t read_timeout_sec, + time_t read_timeout_usec, + time_t write_timeout_sec, + time_t write_timeout_usec) + : sock_(sock), ssl_(ssl), read_timeout_sec_(read_timeout_sec), + read_timeout_usec_(read_timeout_usec), + write_timeout_sec_(write_timeout_sec), + write_timeout_usec_(write_timeout_usec) { + SSL_clear_mode(ssl, SSL_MODE_AUTO_RETRY); +} + +inline SSLSocketStream::~SSLSocketStream() {} + +inline bool SSLSocketStream::is_readable() const { + return detail::select_read(sock_, read_timeout_sec_, read_timeout_usec_) > 0; +} + +inline bool SSLSocketStream::is_writable() const { + return detail::select_write(sock_, write_timeout_sec_, write_timeout_usec_) > + 0; +} + +inline ssize_t SSLSocketStream::read(char *ptr, size_t size) { + if (SSL_pending(ssl_) > 0) { + return SSL_read(ssl_, ptr, static_cast(size)); + } else if (is_readable()) { + auto ret = SSL_read(ssl_, ptr, static_cast(size)); + if (ret < 0) { + auto err = SSL_get_error(ssl_, ret); + while (err == SSL_ERROR_WANT_READ) { + if (SSL_pending(ssl_) > 0) { + return SSL_read(ssl_, ptr, static_cast(size)); + } else if (is_readable()) { + ret = SSL_read(ssl_, ptr, static_cast(size)); + if (ret >= 0) { return ret; } + err = SSL_get_error(ssl_, ret); + } else { + return -1; + } + } + } + return ret; + } + return -1; +} +inline ssize_t SSLSocketStream::write(const char *ptr, size_t size) { + if (is_writable()) { return SSL_write(ssl_, ptr, static_cast(size)); } + return -1; +} +inline void SSLSocketStream::get_remote_ip_and_port(std::string &ip, + int &port) const { + detail::get_remote_ip_and_port(sock_, ip, port); +} -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/expression_map.hpp -// -// -//===----------------------------------------------------------------------===// +inline socket_t SSLSocketStream::socket() const { return sock_; } +static SSLInit sslinit_; +} // namespace detail +// SSL HTTP server implementation +inline SSLServer::SSLServer(const char *cert_path, const char *private_key_path, + const char *client_ca_cert_file_path, + const char *client_ca_cert_dir_path) { + ctx_ = SSL_CTX_new(SSLv23_server_method()); + if (ctx_) { + SSL_CTX_set_options(ctx_, + SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | + SSL_OP_NO_COMPRESSION | + SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); + // auto ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + // SSL_CTX_set_tmp_ecdh(ctx_, ecdh); + // EC_KEY_free(ecdh); + if (SSL_CTX_use_certificate_chain_file(ctx_, cert_path) != 1 || + SSL_CTX_use_PrivateKey_file(ctx_, private_key_path, SSL_FILETYPE_PEM) != + 1) { + SSL_CTX_free(ctx_); + ctx_ = nullptr; + } else if (client_ca_cert_file_path || client_ca_cert_dir_path) { + // if (client_ca_cert_file_path) { + // auto list = SSL_load_client_CA_file(client_ca_cert_file_path); + // SSL_CTX_set_client_CA_list(ctx_, list); + // } -namespace duckdb { -class Expression; + SSL_CTX_load_verify_locations(ctx_, client_ca_cert_file_path, + client_ca_cert_dir_path); -struct ExpressionHashFunction { - uint64_t operator()(const BaseExpression *const &expr) const { - return (uint64_t)expr->Hash(); - } -}; + SSL_CTX_set_verify( + ctx_, + SSL_VERIFY_PEER | + SSL_VERIFY_FAIL_IF_NO_PEER_CERT, // SSL_VERIFY_CLIENT_ONCE, + nullptr); + } + } +} -struct ExpressionEquality { - bool operator()(const BaseExpression *const &a, const BaseExpression *const &b) const { - return a->Equals(b); - } -}; +inline SSLServer::SSLServer(X509 *cert, EVP_PKEY *private_key, + X509_STORE *client_ca_cert_store) { + ctx_ = SSL_CTX_new(SSLv23_server_method()); -template -using expression_map_t = unordered_map; + if (ctx_) { + SSL_CTX_set_options(ctx_, + SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | + SSL_OP_NO_COMPRESSION | + SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); -using expression_set_t = unordered_set; + if (SSL_CTX_use_certificate(ctx_, cert) != 1 || + SSL_CTX_use_PrivateKey(ctx_, private_key) != 1) { + SSL_CTX_free(ctx_); + ctx_ = nullptr; + } else if (client_ca_cert_store) { -} // namespace duckdb + SSL_CTX_set_cert_store(ctx_, client_ca_cert_store); + SSL_CTX_set_verify( + ctx_, + SSL_VERIFY_PEER | + SSL_VERIFY_FAIL_IF_NO_PEER_CERT, // SSL_VERIFY_CLIENT_ONCE, + nullptr); + } + } +} +inline SSLServer::~SSLServer() { + if (ctx_) { SSL_CTX_free(ctx_); } +} + +inline bool SSLServer::is_valid() const { return ctx_; } + +inline bool SSLServer::process_and_close_socket(socket_t sock) { + auto ssl = detail::ssl_new( + sock, ctx_, ctx_mutex_, + [&](SSL *ssl) { + return detail::ssl_connect_or_accept_nonblocking( + sock, ssl, SSL_accept, read_timeout_sec_, read_timeout_usec_); + }, + [](SSL * /*ssl*/) { return true; }); + + bool ret = false; + if (ssl) { + ret = detail::process_server_socket_ssl( + ssl, sock, keep_alive_max_count_, keep_alive_timeout_sec_, + read_timeout_sec_, read_timeout_usec_, write_timeout_sec_, + write_timeout_usec_, + [this, ssl](Stream &strm, bool close_connection, + bool &connection_closed) { + return process_request(strm, close_connection, connection_closed, + [&](Request &req) { req.ssl = ssl; }); + }); + + // Shutdown gracefully if the result seemed successful, non-gracefully if + // the connection appeared to be closed. + const bool shutdown_gracefully = ret; + detail::ssl_delete(ctx_mutex_, ssl, shutdown_gracefully); + } -namespace duckdb { + detail::shutdown_socket(sock); + detail::close_socket(sock); + return ret; +} -void CommonAggregateOptimizer::VisitOperator(LogicalOperator &op) { - LogicalOperatorVisitor::VisitOperator(op); - switch (op.type) { - case LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY: - ExtractCommonAggregates((LogicalAggregate &)op); - break; - default: - break; - } +// SSL HTTP client implementation +inline SSLClient::SSLClient(const std::string &host) + : SSLClient(host, 443, std::string(), std::string()) {} + +inline SSLClient::SSLClient(const std::string &host, int port) + : SSLClient(host, port, std::string(), std::string()) {} + +inline SSLClient::SSLClient(const std::string &host, int port, + const std::string &client_cert_path, + const std::string &client_key_path) + : ClientImpl(host, port, client_cert_path, client_key_path) { + ctx_ = SSL_CTX_new(SSLv23_client_method()); + + detail::split(&host_[0], &host_[host_.size()], '.', + [&](const char *b, const char *e) { + host_components_.emplace_back(std::string(b, e)); + }); + if (!client_cert_path.empty() && !client_key_path.empty()) { + if (SSL_CTX_use_certificate_file(ctx_, client_cert_path.c_str(), + SSL_FILETYPE_PEM) != 1 || + SSL_CTX_use_PrivateKey_file(ctx_, client_key_path.c_str(), + SSL_FILETYPE_PEM) != 1) { + SSL_CTX_free(ctx_); + ctx_ = nullptr; + } + } } -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; +inline SSLClient::SSLClient(const std::string &host, int port, + X509 *client_cert, EVP_PKEY *client_key) + : ClientImpl(host, port) { + ctx_ = SSL_CTX_new(SSLv23_client_method()); + + detail::split(&host_[0], &host_[host_.size()], '.', + [&](const char *b, const char *e) { + host_components_.emplace_back(std::string(b, e)); + }); + if (client_cert != nullptr && client_key != nullptr) { + if (SSL_CTX_use_certificate(ctx_, client_cert) != 1 || + SSL_CTX_use_PrivateKey(ctx_, client_key) != 1) { + SSL_CTX_free(ctx_); + ctx_ = 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; - } - } +inline SSLClient::~SSLClient() { + if (ctx_) { SSL_CTX_free(ctx_); } + // Make sure to shut down SSL since shutdown_ssl will resolve to the + // base function rather than the derived function once we get to the + // base class destructor, and won't free the SSL (causing a leak). + SSLClient::shutdown_ssl(socket_, true); } -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/optimizer/cse_optimizer.hpp -// -// -//===----------------------------------------------------------------------===// +inline bool SSLClient::is_valid() const { return ctx_; } +inline void SSLClient::set_ca_cert_path(const char *ca_cert_file_path, + const char *ca_cert_dir_path) { + if (ca_cert_file_path) { ca_cert_file_path_ = ca_cert_file_path; } + if (ca_cert_dir_path) { ca_cert_dir_path_ = ca_cert_dir_path; } +} +inline void SSLClient::set_ca_cert_store(X509_STORE *ca_cert_store) { + if (ca_cert_store) { + if (ctx_) { + if (SSL_CTX_get_cert_store(ctx_) != ca_cert_store) { + // Free memory allocated for old cert and use new store `ca_cert_store` + SSL_CTX_set_cert_store(ctx_, ca_cert_store); + } + } else { + X509_STORE_free(ca_cert_store); + } + } +} +inline long SSLClient::get_openssl_verify_result() const { + return verify_result_; +} +inline SSL_CTX *SSLClient::ssl_context() const { return ctx_; } +inline bool SSLClient::create_and_connect_socket(Socket &socket, Error &error) { + return is_valid() && ClientImpl::create_and_connect_socket(socket, error); +} +// Assumes that socket_mutex_ is locked and that there are no requests in flight +inline bool SSLClient::connect_with_proxy(Socket &socket, Response &res, + bool &success, Error &error) { + success = true; + Response res2; + if (!detail::process_client_socket( + socket.sock, read_timeout_sec_, read_timeout_usec_, + write_timeout_sec_, write_timeout_usec_, [&](Stream &strm) { + Request req2; + req2.method = "CONNECT"; + req2.path = host_and_port_; + return process_request(strm, req2, res2, false, error); + })) { + // Thread-safe to close everything because we are assuming there are no + // requests in flight + shutdown_ssl(socket, true); + shutdown_socket(socket); + close_socket(socket); + success = false; + return false; + } -namespace duckdb { -class Binder; -struct CSEReplacementState; + if (res2.status == 407) { + if (!proxy_digest_auth_username_.empty() && + !proxy_digest_auth_password_.empty()) { + std::map auth; + if (detail::parse_www_authenticate(res2, auth, true)) { + Response res3; + if (!detail::process_client_socket( + socket.sock, read_timeout_sec_, read_timeout_usec_, + write_timeout_sec_, write_timeout_usec_, [&](Stream &strm) { + Request req3; + req3.method = "CONNECT"; + req3.path = host_and_port_; + req3.headers.insert(detail::make_digest_authentication_header( + req3, auth, 1, detail::random_string(10), + proxy_digest_auth_username_, proxy_digest_auth_password_, + true)); + return process_request(strm, req3, res3, false, error); + })) { + // Thread-safe to close everything because we are assuming there are + // no requests in flight + shutdown_ssl(socket, true); + shutdown_socket(socket); + close_socket(socket); + success = false; + return false; + } + } + } else { + res = res2; + return false; + } + } -//! 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) { - } + return true; +} -public: - void VisitOperator(LogicalOperator &op) override; +inline bool SSLClient::load_certs() { + bool ret = true; -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); + std::call_once(initialize_cert_, [&]() { + std::lock_guard guard(ctx_mutex_); + if (!ca_cert_file_path_.empty()) { + if (!SSL_CTX_load_verify_locations(ctx_, ca_cert_file_path_.c_str(), + nullptr)) { + ret = false; + } + } else if (!ca_cert_dir_path_.empty()) { + if (!SSL_CTX_load_verify_locations(ctx_, nullptr, + ca_cert_dir_path_.c_str())) { + ret = false; + } + } else { +#ifdef _WIN32 + detail::load_system_certs_on_windows(SSL_CTX_get_cert_store(ctx_)); +#else + SSL_CTX_set_default_verify_paths(ctx_); +#endif + } + }); - //! Main method to extract common subexpressions - void ExtractCommonSubExpresions(LogicalOperator &op); + return ret; +} -private: - Binder &binder; -}; -} // namespace duckdb +inline bool SSLClient::initialize_ssl(Socket &socket, Error &error) { + auto ssl = detail::ssl_new( + socket.sock, ctx_, ctx_mutex_, + [&](SSL *ssl) { + if (server_certificate_verification_) { + if (!load_certs()) { + error = Error::SSLLoadingCerts; + return false; + } + SSL_set_verify(ssl, SSL_VERIFY_NONE, nullptr); + } + if (!detail::ssl_connect_or_accept_nonblocking( + socket.sock, ssl, SSL_connect, connection_timeout_sec_, + connection_timeout_usec_)) { + error = Error::SSLConnection; + return false; + } + if (server_certificate_verification_) { + verify_result_ = SSL_get_verify_result(ssl); + if (verify_result_ != X509_V_OK) { + error = Error::SSLServerVerification; + return false; + } + auto server_cert = SSL_get_peer_certificate(ssl); + if (server_cert == nullptr) { + error = Error::SSLServerVerification; + return false; + } + if (!verify_host(server_cert)) { + X509_free(server_cert); + error = Error::SSLServerVerification; + return false; + } + X509_free(server_cert); + } + return true; + }, + [&](SSL *ssl) { + SSL_set_tlsext_host_name(ssl, host_.c_str()); + return true; + }); + if (ssl) { + socket.ssl = ssl; + return true; + } -namespace duckdb { + shutdown_socket(socket); + close_socket(socket); + return false; +} -//! 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; +inline void SSLClient::shutdown_ssl(Socket &socket, bool shutdown_gracefully) { + if (socket.sock == INVALID_SOCKET) { + assert(socket.ssl == nullptr); + return; + } + if (socket.ssl) { + detail::ssl_delete(ctx_mutex_, socket.ssl, shutdown_gracefully); + socket.ssl = nullptr; + } + assert(socket.ssl == nullptr); +} - CSENode() : count(1), column_index(INVALID_INDEX) { - } -}; +inline bool +SSLClient::process_socket(const Socket &socket, + std::function callback) { + assert(socket.ssl); + return detail::process_client_socket_ssl( + socket.ssl, socket.sock, read_timeout_sec_, read_timeout_usec_, + write_timeout_sec_, write_timeout_usec_, std::move(callback)); +} -//! 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; -}; +inline bool SSLClient::is_ssl() const { return true; } -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); +inline bool SSLClient::verify_host(X509 *server_cert) const { + /* Quote from RFC2818 section 3.1 "Server Identity" + + If a subjectAltName extension of type dNSName is present, that MUST + be used as the identity. Otherwise, the (most specific) Common Name + field in the Subject field of the certificate MUST be used. Although + the use of the Common Name is existing practice, it is deprecated and + Certification Authorities are encouraged to use the dNSName instead. + + Matching is performed using the matching rules specified by + [RFC2459]. If more than one identity of a given type is present in + the certificate (e.g., more than one dNSName name, a match in any one + of the set is considered acceptable.) Names may contain the wildcard + character * which is considered to match any single domain name + component or component fragment. E.g., *.a.com matches foo.a.com but + not bar.foo.a.com. f*.com matches foo.com but not bar.com. + + In some cases, the URI is specified as an IP address rather than a + hostname. In this case, the iPAddress subjectAltName must be present + in the certificate and must exactly match the IP in the URI. + + */ + return verify_host_with_subject_alt_name(server_cert) || + verify_host_with_common_name(server_cert); } -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: - 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); }); +inline bool +SSLClient::verify_host_with_subject_alt_name(X509 *server_cert) const { + auto ret = false; + + auto type = GEN_DNS; + + struct in6_addr addr6; + struct in_addr addr; + size_t addr_len = 0; + +#ifndef __MINGW32__ + if (inet_pton(AF_INET6, host_.c_str(), &addr6)) { + type = GEN_IPADD; + addr_len = sizeof(struct in6_addr); + } else if (inet_pton(AF_INET, host_.c_str(), &addr)) { + type = GEN_IPADD; + addr_len = sizeof(struct in_addr); + } +#endif + + auto alt_names = static_cast( + X509_get_ext_d2i(server_cert, NID_subject_alt_name, nullptr, nullptr)); + + if (alt_names) { + auto dsn_matched = false; + auto ip_mached = false; + + auto count = sk_GENERAL_NAME_num(alt_names); + + for (decltype(count) i = 0; i < count && !dsn_matched; i++) { + auto val = sk_GENERAL_NAME_value(alt_names, i); + if (val->type == type) { + auto name = (const char *)ASN1_STRING_get0_data(val->d.ia5); + auto name_len = (size_t)ASN1_STRING_length(val->d.ia5); + + switch (type) { + case GEN_DNS: dsn_matched = check_host_name(name, name_len); break; + + case GEN_IPADD: + if (!memcmp(&addr6, name, addr_len) || + !memcmp(&addr, name, addr_len)) { + ip_mached = true; + } + break; + } + } + } + + if (dsn_matched || ip_mached) { ret = true; } + } + + GENERAL_NAMES_free((STACK_OF(GENERAL_NAME) *)alt_names); + return ret; } -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 - if (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 == INVALID_INDEX) { - // has not been pushed yet: push it - node.column_index = state.expressions.size(); - state.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); }); +inline bool SSLClient::verify_host_with_common_name(X509 *server_cert) const { + const auto subject_name = X509_get_subject_name(server_cert); + + if (subject_name != nullptr) { + char name[BUFSIZ]; + auto name_len = X509_NAME_get_text_by_NID(subject_name, NID_commonName, + name, sizeof(name)); + + if (name_len != -1) { + return check_host_name(name, static_cast(name_len)); + } + } + + return false; } -void CommonSubExpressionOptimizer::ExtractCommonSubExpresions(LogicalOperator &op) { - D_ASSERT(op.children.size() == 1); +inline bool SSLClient::check_host_name(const char *pattern, + size_t pattern_len) const { + if (host_.size() == pattern_len && host_ == pattern) { return true; } - // 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); + // Wildcard match + // https://bugs.launchpad.net/ubuntu/+source/firefox-3.0/+bug/376484 + std::vector pattern_components; + detail::split(&pattern[0], &pattern[pattern_len], '.', + [&](const char *b, const char *e) { + pattern_components.emplace_back(std::string(b, e)); + }); + + if (host_components_.size() != pattern_components.size()) { return false; } + + auto itr = pattern_components.begin(); + for (const auto &h : host_components_) { + auto &p = *itr; + if (p != h && p != "*") { + auto partial_match = (p.size() > 0 && p[p.size() - 1] == '*' && + !p.compare(0, p.size() - 1, h)); + if (!partial_match) { return false; } + } + ++itr; + } + + return true; } +#endif -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/optimizer/deliminator.hpp -// -// -//===----------------------------------------------------------------------===// +// Universal client implementation +inline Client::Client(const char *scheme_host_port) + : Client(scheme_host_port, std::string(), std::string()) {} +inline Client::Client(const char *scheme_host_port, + const std::string &client_cert_path, + const std::string &client_key_path) { + const static std::regex re(R"(^(?:([a-z]+)://)?([^:/?#]+)(?::(\d+))?)"); + std::cmatch m; + if (std::regex_match(scheme_host_port, m, re)) { + auto scheme = m[1].str(); +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + if (!scheme.empty() && (scheme != "http" && scheme != "https")) { +#else + if (!scheme.empty() && scheme != "http") { +#endif + std::string msg = "'" + scheme + "' scheme is not supported."; + throw std::invalid_argument(msg); + return; + } + auto is_ssl = scheme == "https"; + auto host = m[2].str(); + auto port_str = m[3].str(); + auto port = !port_str.empty() ? std::stoi(port_str) : (is_ssl ? 443 : 80); + if (is_ssl) { +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + cli_ = detail::make_unique(host.c_str(), port, + client_cert_path, client_key_path); + is_ssl_ = is_ssl; +#endif + } else { + cli_ = detail::make_unique(host.c_str(), port, + client_cert_path, client_key_path); + } + } else { + cli_ = detail::make_unique(scheme_host_port, 80, + client_cert_path, client_key_path); + } +} -namespace duckdb { +inline Client::Client(const std::string &host, int port) + : cli_(detail::make_unique(host, port)) {} -class Optimizer; -class DeliminatorPlanUpdater; +inline Client::Client(const std::string &host, int port, + const std::string &client_cert_path, + const std::string &client_key_path) + : cli_(detail::make_unique(host, port, client_cert_path, + client_key_path)) {} -//! 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); +inline Client::~Client() {} -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 *op_ptr, DeliminatorPlanUpdater &updater); - //! Replace references to a removed DelimGet, remove DelimJoins if all their DelimGets are gone - void UpdatePlan(LogicalOperator &op, expression_map_t &expr_map, - column_binding_map_t &projection_map); - //! Whether the operator has one or more children of type DELIM_GET - bool HasChildDelimGet(LogicalOperator &op); -}; +inline bool Client::is_valid() const { + return cli_ != nullptr && cli_->is_valid(); +} -} // namespace duckdb +inline Result Client::Get(const char *path) { return cli_->Get(path); } +inline Result Client::Get(const char *path, const Headers &headers) { + return cli_->Get(path, headers); +} +inline Result Client::Get(const char *path, Progress progress) { + return cli_->Get(path, std::move(progress)); +} +inline Result Client::Get(const char *path, const Headers &headers, + Progress progress) { + return cli_->Get(path, headers, std::move(progress)); +} +inline Result Client::Get(const char *path, ContentReceiver content_receiver) { + return cli_->Get(path, std::move(content_receiver)); +} +inline Result Client::Get(const char *path, const Headers &headers, + ContentReceiver content_receiver) { + return cli_->Get(path, headers, std::move(content_receiver)); +} +inline Result Client::Get(const char *path, ContentReceiver content_receiver, + Progress progress) { + return cli_->Get(path, std::move(content_receiver), std::move(progress)); +} +inline Result Client::Get(const char *path, const Headers &headers, + ContentReceiver content_receiver, Progress progress) { + return cli_->Get(path, headers, std::move(content_receiver), + std::move(progress)); +} +inline Result Client::Get(const char *path, ResponseHandler response_handler, + ContentReceiver content_receiver) { + return cli_->Get(path, std::move(response_handler), + std::move(content_receiver)); +} +inline Result Client::Get(const char *path, const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver) { + return cli_->Get(path, headers, std::move(response_handler), + std::move(content_receiver)); +} +inline Result Client::Get(const char *path, ResponseHandler response_handler, + ContentReceiver content_receiver, Progress progress) { + return cli_->Get(path, std::move(response_handler), + std::move(content_receiver), std::move(progress)); +} +inline Result Client::Get(const char *path, const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver, Progress progress) { + return cli_->Get(path, headers, std::move(response_handler), + std::move(content_receiver), std::move(progress)); +} +inline Result Client::Get(const char *path, const Params ¶ms, + const Headers &headers, Progress progress) { + return cli_->Get(path, params, headers, progress); +} +inline Result Client::Get(const char *path, const Params ¶ms, + const Headers &headers, + ContentReceiver content_receiver, Progress progress) { + return cli_->Get(path, params, headers, content_receiver, progress); +} +inline Result Client::Get(const char *path, const Params ¶ms, + const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver, Progress progress) { + return cli_->Get(path, params, headers, response_handler, content_receiver, + progress); +} + +inline Result Client::Head(const char *path) { return cli_->Head(path); } +inline Result Client::Head(const char *path, const Headers &headers) { + return cli_->Head(path, headers); +} + +inline Result Client::Post(const char *path) { return cli_->Post(path); } +inline Result Client::Post(const char *path, const char *body, + size_t content_length, const char *content_type) { + return cli_->Post(path, body, content_length, content_type); +} +inline Result Client::Post(const char *path, const Headers &headers, + const char *body, size_t content_length, + const char *content_type) { + return cli_->Post(path, headers, body, content_length, content_type); +} +inline Result Client::Post(const char *path, const std::string &body, + const char *content_type) { + return cli_->Post(path, body, content_type); +} +inline Result Client::Post(const char *path, const Headers &headers, + const std::string &body, const char *content_type) { + return cli_->Post(path, headers, body, content_type); +} +inline Result Client::Post(const char *path, size_t content_length, + ContentProvider content_provider, + const char *content_type) { + return cli_->Post(path, content_length, std::move(content_provider), + content_type); +} +inline Result Client::Post(const char *path, + ContentProviderWithoutLength content_provider, + const char *content_type) { + return cli_->Post(path, std::move(content_provider), content_type); +} +inline Result Client::Post(const char *path, const Headers &headers, + size_t content_length, + ContentProvider content_provider, + const char *content_type) { + return cli_->Post(path, headers, content_length, std::move(content_provider), + content_type); +} +inline Result Client::Post(const char *path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const char *content_type) { + return cli_->Post(path, headers, std::move(content_provider), content_type); +} +inline Result Client::Post(const char *path, const Params ¶ms) { + return cli_->Post(path, params); +} +inline Result Client::Post(const char *path, const Headers &headers, + const Params ¶ms) { + return cli_->Post(path, headers, params); +} +inline Result Client::Post(const char *path, + const MultipartFormDataItems &items) { + return cli_->Post(path, items); +} +inline Result Client::Post(const char *path, const Headers &headers, + const MultipartFormDataItems &items) { + return cli_->Post(path, headers, items); +} +inline Result Client::Post(const char *path, const Headers &headers, + const MultipartFormDataItems &items, + const std::string &boundary) { + return cli_->Post(path, headers, items, boundary); +} +inline Result Client::Put(const char *path) { return cli_->Put(path); } +inline Result Client::Put(const char *path, const char *body, + size_t content_length, const char *content_type) { + return cli_->Put(path, body, content_length, content_type); +} +inline Result Client::Put(const char *path, const Headers &headers, + const char *body, size_t content_length, + const char *content_type) { + return cli_->Put(path, headers, body, content_length, content_type); +} +inline Result Client::Put(const char *path, const std::string &body, + const char *content_type) { + return cli_->Put(path, body, content_type); +} +inline Result Client::Put(const char *path, const Headers &headers, + const std::string &body, const char *content_type) { + return cli_->Put(path, headers, body, content_type); +} +inline Result Client::Put(const char *path, size_t content_length, + ContentProvider content_provider, + const char *content_type) { + return cli_->Put(path, content_length, std::move(content_provider), + content_type); +} +inline Result Client::Put(const char *path, + ContentProviderWithoutLength content_provider, + const char *content_type) { + return cli_->Put(path, std::move(content_provider), content_type); +} +inline Result Client::Put(const char *path, const Headers &headers, + size_t content_length, + ContentProvider content_provider, + const char *content_type) { + return cli_->Put(path, headers, content_length, std::move(content_provider), + content_type); +} +inline Result Client::Put(const char *path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const char *content_type) { + return cli_->Put(path, headers, std::move(content_provider), content_type); +} +inline Result Client::Put(const char *path, const Params ¶ms) { + return cli_->Put(path, params); +} +inline Result Client::Put(const char *path, const Headers &headers, + const Params ¶ms) { + return cli_->Put(path, headers, params); +} +inline Result Client::Patch(const char *path) { return cli_->Patch(path); } +inline Result Client::Patch(const char *path, const char *body, + size_t content_length, const char *content_type) { + return cli_->Patch(path, body, content_length, content_type); +} +inline Result Client::Patch(const char *path, const Headers &headers, + const char *body, size_t content_length, + const char *content_type) { + return cli_->Patch(path, headers, body, content_length, content_type); +} +inline Result Client::Patch(const char *path, const std::string &body, + const char *content_type) { + return cli_->Patch(path, body, content_type); +} +inline Result Client::Patch(const char *path, const Headers &headers, + const std::string &body, const char *content_type) { + return cli_->Patch(path, headers, body, content_type); +} +inline Result Client::Patch(const char *path, size_t content_length, + ContentProvider content_provider, + const char *content_type) { + return cli_->Patch(path, content_length, std::move(content_provider), + content_type); +} +inline Result Client::Patch(const char *path, + ContentProviderWithoutLength content_provider, + const char *content_type) { + return cli_->Patch(path, std::move(content_provider), content_type); +} +inline Result Client::Patch(const char *path, const Headers &headers, + size_t content_length, + ContentProvider content_provider, + const char *content_type) { + return cli_->Patch(path, headers, content_length, std::move(content_provider), + content_type); +} +inline Result Client::Patch(const char *path, const Headers &headers, + ContentProviderWithoutLength content_provider, + const char *content_type) { + return cli_->Patch(path, headers, std::move(content_provider), content_type); +} +inline Result Client::Delete(const char *path) { return cli_->Delete(path); } +inline Result Client::Delete(const char *path, const Headers &headers) { + return cli_->Delete(path, headers); +} +inline Result Client::Delete(const char *path, const char *body, + size_t content_length, const char *content_type) { + return cli_->Delete(path, body, content_length, content_type); +} +inline Result Client::Delete(const char *path, const Headers &headers, + const char *body, size_t content_length, + const char *content_type) { + return cli_->Delete(path, headers, body, content_length, content_type); +} +inline Result Client::Delete(const char *path, const std::string &body, + const char *content_type) { + return cli_->Delete(path, body, content_type); +} +inline Result Client::Delete(const char *path, const Headers &headers, + const std::string &body, + const char *content_type) { + return cli_->Delete(path, headers, body, content_type); +} +inline Result Client::Options(const char *path) { return cli_->Options(path); } +inline Result Client::Options(const char *path, const Headers &headers) { + return cli_->Options(path, headers); +} +inline bool Client::send(const Request &req, Response &res, Error &error) { + return cli_->send(req, res, error); +} +inline Result Client::send(const Request &req) { return cli_->send(req); } +inline size_t Client::is_socket_open() const { return cli_->is_socket_open(); } +inline void Client::stop() { cli_->stop(); } +inline void Client::set_default_headers(Headers headers) { + cli_->set_default_headers(std::move(headers)); +} +inline void Client::set_tcp_nodelay(bool on) { cli_->set_tcp_nodelay(on); } +inline void Client::set_socket_options(SocketOptions socket_options) { + cli_->set_socket_options(std::move(socket_options)); +} +inline void Client::set_connection_timeout(time_t sec, time_t usec) { + cli_->set_connection_timeout(sec, usec); +} +inline void Client::set_read_timeout(time_t sec, time_t usec) { + cli_->set_read_timeout(sec, usec); +} +inline void Client::set_write_timeout(time_t sec, time_t usec) { + cli_->set_write_timeout(sec, usec); +} +inline void Client::set_basic_auth(const char *username, const char *password) { + cli_->set_basic_auth(username, password); +} +inline void Client::set_bearer_token_auth(const char *token) { + cli_->set_bearer_token_auth(token); +} +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +inline void Client::set_digest_auth(const char *username, + const char *password) { + cli_->set_digest_auth(username, password); +} +#endif +inline void Client::set_keep_alive(bool on) { cli_->set_keep_alive(on); } +inline void Client::set_follow_location(bool on) { + cli_->set_follow_location(on); +} -namespace duckdb { +inline void Client::set_compress(bool on) { cli_->set_compress(on); } -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; - //! Whether the operator has one or more children of type DELIM_GET - bool HasChildDelimGet(LogicalOperator &op); +inline void Client::set_decompress(bool on) { cli_->set_decompress(on); } - expression_map_t expr_map; - column_binding_map_t projection_map; - unique_ptr temp_ptr; -}; +inline void Client::set_interface(const char *intf) { + cli_->set_interface(intf); +} -void DeliminatorPlanUpdater::VisitOperator(LogicalOperator &op) { - VisitOperatorChildren(op); - VisitOperatorExpressions(op); - // now check if this is a delim join that can be removed - if (op.type == LogicalOperatorType::LOGICAL_DELIM_JOIN && !HasChildDelimGet(op)) { - auto &delim_join = (LogicalDelimJoin &)op; - auto decs = &delim_join.duplicate_eliminated_columns; - for (auto &cond : delim_join.conditions) { - if (cond.comparison != ExpressionType::COMPARE_EQUAL) { - continue; - } - auto &colref = (BoundColumnRefExpression &)*cond.right; - 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.null_values_are_equal = true; // projection_map[colref.binding]; - } - } - // change type if there are no more duplicate-eliminated columns - if (decs->empty()) { - delim_join.type = LogicalOperatorType::LOGICAL_COMPARISON_JOIN; - } - } +inline void Client::set_proxy(const char *host, int port) { + cli_->set_proxy(host, port); +} +inline void Client::set_proxy_basic_auth(const char *username, + const char *password) { + cli_->set_proxy_basic_auth(username, password); } +inline void Client::set_proxy_bearer_token_auth(const char *token) { + cli_->set_proxy_bearer_token_auth(token); +} +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +inline void Client::set_proxy_digest_auth(const char *username, + const char *password) { + cli_->set_proxy_digest_auth(username, password); +} +#endif -void DeliminatorPlanUpdater::VisitExpression(unique_ptr *expression) { - if (expr_map.find(expression->get()) != expr_map.end()) { - *expression = expr_map[expression->get()]->Copy(); - } else { - VisitExpressionChildren(**expression); - } +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +inline void Client::enable_server_certificate_verification(bool enabled) { + cli_->enable_server_certificate_verification(enabled); } +#endif -bool DeliminatorPlanUpdater::HasChildDelimGet(LogicalOperator &op) { - if (op.type == LogicalOperatorType::LOGICAL_DELIM_GET) { - return true; - } - for (auto &child : op.children) { - if (HasChildDelimGet(*child)) { - return true; - } - } - return false; +inline void Client::set_logger(Logger logger) { cli_->set_logger(logger); } + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +inline void Client::set_ca_cert_path(const char *ca_cert_file_path, + const char *ca_cert_dir_path) { + if (is_ssl_) { + static_cast(*cli_).set_ca_cert_path(ca_cert_file_path, + ca_cert_dir_path); + } } -unique_ptr Deliminator::Optimize(unique_ptr op) { - vector *> candidates; - FindCandidates(&op, candidates); +inline void Client::set_ca_cert_store(X509_STORE *ca_cert_store) { + if (is_ssl_) { + static_cast(*cli_).set_ca_cert_store(ca_cert_store); + } +} - for (auto candidate : candidates) { - DeliminatorPlanUpdater updater; - if (RemoveCandidate(candidate, updater)) { - updater.VisitOperator(*op); - } - } - return op; +inline long Client::get_openssl_verify_result() const { + if (is_ssl_) { + return static_cast(*cli_).get_openssl_verify_result(); + } + return -1; // NOTE: -1 doesn't match any of X509_V_ERR_??? } -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; +inline SSL_CTX *Client::ssl_context() const { + if (is_ssl_) { return static_cast(*cli_).ssl_context(); } + return nullptr; +} +#endif + +// ---------------------------------------------------------------------------- + +} // namespace CPPHTTPLIB_NAMESPACE + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#endif // CPPHTTPLIB_HTTPLIB_H + + +// LICENSE_CHANGE_END + +#endif + + +#include + +namespace duckdb { + +//===--------------------------------------------------------------------===// +// Install Extension +//===--------------------------------------------------------------------===// +const vector ExtensionHelper::PathComponents() { + return vector {".duckdb", "extensions", DuckDB::SourceID(), DuckDB::Platform()}; +} + +void ExtensionHelper::InstallExtension(DatabaseInstance &db, const string &extension, bool force_install) { + auto &config = DBConfig::GetConfig(db); + if (!config.enable_external_access) { + throw PermissionException("Installing extensions is disabled through configuration"); } - // followed by a join - if (op->children[0]->type != LogicalOperatorType::LOGICAL_COMPARISON_JOIN) { - return; + auto &fs = FileSystem::GetFileSystem(db); + + string local_path = fs.GetHomeDirectory(); + if (!fs.DirectoryExists(local_path)) { + throw InternalException("Can't find the home directory at " + local_path); } - 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; + auto path_components = PathComponents(); + for (auto &path_ele : path_components) { + local_path = fs.JoinPath(local_path, path_ele); + if (!fs.DirectoryExists(local_path)) { + fs.CreateDirectory(local_path); + } } - // 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); + + auto extension_name = fs.ExtractBaseName(extension); + + string local_extension_path = fs.JoinPath(local_path, extension_name + ".duckdb_extension"); + if (fs.FileExists(local_extension_path) && !force_install) { 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); + + auto is_http_url = StringUtil::Contains(extension, "http://"); + if (fs.FileExists(extension)) { + std::ifstream in(extension, std::ios::binary); + if (in.bad()) { + throw IOException("Failed to read extension from \"%s\"", extension); + } + std::ofstream out(local_extension_path, std::ios::binary); + out << in.rdbuf(); + if (out.bad()) { + throw IOException("Failed to write extension to \"%s\"", local_extension_path); + } + in.close(); + out.close(); return; + } else if (StringUtil::Contains(extension, "/") && !is_http_url) { + throw IOException("Failed to read extension from \"%s\": no such file", extension); } -} -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; -} +#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"; -bool Deliminator::RemoveCandidate(unique_ptr *op_ptr, DeliminatorPlanUpdater &updater) { - auto &proj_or_agg = **op_ptr; - auto &join = (LogicalComparisonJoin &)*proj_or_agg.children[0]; - if (join.join_type != JoinType::INNER && join.join_type != JoinType::SEMI) { - 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; + if (is_http_url) { + url_template = extension; + extension_name = ""; } - // check if joining with the DelimGet is redundant, and collect relevant column information - vector nulls_are_not_equal_exprs; - for (auto &cond : join.conditions) { - if (cond.comparison != ExpressionType::COMPARE_EQUAL) { - // non-equality join condition - return false; - } - 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.null_values_are_equal) { - nulls_are_not_equal_exprs.push_back(other_side); - } + + auto url = StringUtil::Replace(url_template, "${REVISION}", DuckDB::SourceID()); + url = StringUtil::Replace(url, "${PLATFORM}", DuckDB::Platform()); + url = StringUtil::Replace(url, "${NAME}", extension_name); + + string no_http = StringUtil::Replace(url, "http://", ""); + + idx_t next = no_http.find('/', 0); + if (next == string::npos) { + throw IOException("No slash in URL template"); } - // 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; - 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; - for (auto &cb : agg.GetColumnBindings()) { - updater.projection_map[cb] = true; - 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; - } - } - } + + // Push the substring [last, next) on to splits + auto hostname_without_http = no_http.substr(0, next); + auto url_local_part = no_http.substr(next); + + auto url_base = "http://" + hostname_without_http; + duckdb_httplib::Client cli(url_base.c_str()); + + duckdb_httplib::Headers headers = {{"User-Agent", StringUtil::Format("DuckDB %s %s %s", DuckDB::LibraryVersion(), + DuckDB::SourceID(), DuckDB::Platform())}}; + + auto res = cli.Get(url_local_part.c_str(), headers); + if (!res || res->status != 200) { + throw IOException("Failed to download extension %s%s", url_base, url_local_part); } - // 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); + auto decompressed_body = GZipFileSystem::UncompressGZIPString(res->body); + std::ofstream out(local_extension_path, std::ios::binary); + out.write(decompressed_body.data(), decompressed_body.size()); + if (out.bad()) { + throw IOException("Failed to write extension to %s", local_extension_path); } - // 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; +#endif } } // namespace duckdb + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/optimizer/expression_heuristics.hpp +// duckdb/common/dl.hpp // // //===----------------------------------------------------------------------===// @@ -107499,257 +112751,233 @@ bool Deliminator::RemoveCandidate(unique_ptr *op_ptr, Deliminat +#ifndef _WIN32 +#include +#else +#define RTLD_LAZY 0 +#define RTLD_LOCAL 0 +#endif 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); +#ifdef _WIN32 - unique_ptr VisitReplace(BoundConjunctionExpression &expr, unique_ptr *expr_ptr) override; - //! Override this function to search for filter operators - void VisitOperator(LogicalOperator &op) override; +void *dlopen(const char *file, int mode) { + D_ASSERT(file); + return (void *)LoadLibrary(file); +} -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}}; +void *dlsym(void *handle, const char *name) { + D_ASSERT(handle); + return (void *)GetProcAddress((HINSTANCE)handle, name); +} +#endif - 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; +//===--------------------------------------------------------------------===// +// Load External Extension +//===--------------------------------------------------------------------===// +typedef void (*ext_init_fun_t)(DatabaseInstance &); +typedef const char *(*ext_version_fun_t)(void); + +template +static T LoadFunctionFromDLL(void *dll, const string &function_name, const string &filename) { + auto function = dlsym(dll, function_name.c_str()); + if (!function) { + throw IOException("File \"%s\" did not contain function \"%s\"", filename, function_name); + } + return (T)function; } -void ExpressionHeuristics::VisitOperator(LogicalOperator &op) { - if (op.type == LogicalOperatorType::LOGICAL_FILTER) { - // reorder all filter expressions - if (op.expressions.size() > 1) { - ReorderExpressions(op.expressions); +void ExtensionHelper::LoadExternalExtension(DatabaseInstance &db, const string &extension) { + auto &config = DBConfig::GetConfig(db); + if (!config.enable_external_access) { + throw PermissionException("Loading external extensions is disabled through configuration"); + } + auto &fs = FileSystem::GetFileSystem(db); + auto filename = fs.ConvertSeparators(extension); + + // shorthand case + if (!StringUtil::Contains(extension, ".") && !StringUtil::Contains(extension, fs.PathSeparator())) { + string local_path = fs.GetHomeDirectory(); + auto path_components = PathComponents(); + for (auto &path_ele : path_components) { + local_path = fs.JoinPath(local_path, path_ele); } + filename = fs.JoinPath(local_path, extension + ".duckdb_extension"); } - // traverse recursively through the operator tree - VisitOperatorChildren(op); - VisitOperatorExpressions(op); + if (!fs.FileExists(filename)) { + throw IOException("File \"%s\" not found", filename); + } + auto lib_hdl = dlopen(filename.c_str(), RTLD_LAZY | RTLD_LOCAL); + if (!lib_hdl) { + throw IOException("File \"%s\" could not be loaded", filename); + } + + auto basename = fs.ExtractBaseName(filename); + auto init_fun_name = basename + "_init"; + auto version_fun_name = basename + "_version"; + + ext_init_fun_t init_fun; + ext_version_fun_t version_fun; + + init_fun = LoadFunctionFromDLL(lib_hdl, init_fun_name, filename); + version_fun = LoadFunctionFromDLL(lib_hdl, version_fun_name, filename); + + auto extension_version = std::string((*version_fun)()); + auto engine_version = DuckDB::LibraryVersion(); + if (extension_version != engine_version) { + throw InvalidInputException("Extension \"%s\" version (%s) does not match DuckDB version (%s)", filename, + extension_version, engine_version); + } + + try { + (*init_fun)(db); + } catch (std::exception &e) { + throw InvalidInputException("Initialization function \"%s\" from file \"%s\" threw an exception: \"%s\"", + init_fun_name, filename, e.what()); + } } -unique_ptr ExpressionHeuristics::VisitReplace(BoundConjunctionExpression &expr, - unique_ptr *expr_ptr) { - ReorderExpressions(expr.children); - return nullptr; +} // namespace duckdb + + +namespace duckdb { + +Extension::~Extension() { } -void ExpressionHeuristics::ReorderExpressions(vector> &expressions) { +} // namespace duckdb - 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}); - } +namespace duckdb { - // 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); - } +MaterializedQueryResult::MaterializedQueryResult(StatementType statement_type) + : QueryResult(QueryResultType::MATERIALIZED_RESULT, statement_type) { } -idx_t ExpressionHeuristics::ExpressionCost(BoundBetweenExpression &expr) { - return Cost(*expr.input) + Cost(*expr.lower) + Cost(*expr.upper) + 10; +MaterializedQueryResult::MaterializedQueryResult(StatementType statement_type, vector types, + vector names) + : QueryResult(QueryResultType::MATERIALIZED_RESULT, statement_type, move(types), move(names)) { } -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; +MaterializedQueryResult::MaterializedQueryResult(string error) + : QueryResult(QueryResultType::MATERIALIZED_RESULT, move(error)) { } -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; +Value MaterializedQueryResult::GetValue(idx_t column, idx_t index) { + auto &data = collection.GetChunkForRow(index).data[column]; + auto offset_in_chunk = index % STANDARD_VECTOR_SIZE; + return data.GetValue(offset_in_chunk); +} + +string MaterializedQueryResult::ToString() { + string result; + if (success) { + result = HeaderToString(); + result += "[ Rows: " + to_string(collection.Count()) + "]\n"; + for (idx_t j = 0; j < collection.Count(); j++) { + for (idx_t i = 0; i < collection.ColumnCount(); i++) { + auto val = collection.GetValue(i, j); + result += val.IsNull() ? "NULL" : val.ToString(); + result += "\t"; + } + result += "\n"; } + result += "\n"; + } else { + result = error + "\n"; } - return Cost(*expr.child) + cast_cost; + return result; } -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); +unique_ptr MaterializedQueryResult::Fetch() { + return FetchRaw(); } -idx_t ExpressionHeuristics::ExpressionCost(BoundConjunctionExpression &expr) { - // CONJUNCTION_AND, CONJUNCTION_OR - idx_t cost = 5; - for (auto &child : expr.children) { - cost += Cost(*child); +unique_ptr MaterializedQueryResult::FetchRaw() { + if (!success) { + throw InvalidInputException("Attempting to fetch from an unsuccessful query result\nError: %s", error); } - return cost; + return collection.Fetch(); } -idx_t ExpressionHeuristics::ExpressionCost(BoundFunctionExpression &expr) { - idx_t cost_children = 0; - for (auto &child : expr.children) { - cost_children += Cost(*child); - } +} // namespace duckdb - 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; - } + + + +namespace duckdb { + +PendingQueryResult::PendingQueryResult(shared_ptr context_p, PreparedStatementData &statement, + vector types_p) + : BaseQueryResult(QueryResultType::PENDING_RESULT, statement.statement_type, move(types_p), statement.names), + context(move(context_p)) { } -idx_t ExpressionHeuristics::ExpressionCost(BoundOperatorExpression &expr, ExpressionType &expr_type) { - idx_t sum = 0; - for (auto &child : expr.children) { - sum += Cost(*child); - } +PendingQueryResult::PendingQueryResult(string error) : BaseQueryResult(QueryResultType::PENDING_RESULT, move(error)) { +} - // 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; - } +PendingQueryResult::~PendingQueryResult() { } -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; +unique_ptr PendingQueryResult::LockContext() { + if (!context) { + throw InvalidInputException("Attempting to execute an unsuccessful or closed pending query result\nError: %s", + error); } + return context->LockContext(); } -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; +void PendingQueryResult::CheckExecutableInternal(ClientContextLock &lock) { + bool invalidated = !success || !context; + if (!invalidated) { + invalidated = !context->IsActiveResult(lock, this); } + if (invalidated) { + throw InvalidInputException("Attempting to execute an unsuccessful or closed pending query result\nError: %s", + error); } +} - // return a very high value if nothing matches - return 1000; +PendingExecutionResult PendingQueryResult::ExecuteTask() { + auto lock = LockContext(); + return ExecuteTaskInternal(*lock); } -} // namespace duckdb +PendingExecutionResult PendingQueryResult::ExecuteTaskInternal(ClientContextLock &lock) { + CheckExecutableInternal(lock); + return context->ExecuteTaskInternal(lock, *this); +} + +unique_ptr PendingQueryResult::ExecuteInternal(ClientContextLock &lock, bool allow_streaming_result) { + CheckExecutableInternal(lock); + while (ExecuteTaskInternal(lock) == PendingExecutionResult::RESULT_NOT_READY) { + } + if (!success) { + return make_unique(error); + } + auto result = context->FetchResultInternal(lock, *this, allow_streaming_result); + Close(); + return result; +} +unique_ptr PendingQueryResult::Execute(bool allow_streaming_result) { + auto lock = LockContext(); + return ExecuteInternal(*lock, allow_streaming_result); +} +void PendingQueryResult::Close() { + context.reset(); +} +} // namespace duckdb @@ -107757,1367 +112985,1173 @@ idx_t ExpressionHeuristics::Cost(Expression &expr) { 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; +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) { + D_ASSERT(data || !success); } -unique_ptr ExpressionRewriter::ConstantOrNull(unique_ptr child, Value value) { - vector> children; - children.push_back(move(child)); - return ConstantOrNull(move(children), move(value)); +PreparedStatement::PreparedStatement(string error) : context(nullptr), success(false), error(move(error)) { } -unique_ptr ExpressionRewriter::ConstantOrNull(vector> children, Value value) { - auto type = value.type(); - return make_unique(type, ConstantOrNull::GetFunction(type), move(children), - ConstantOrNull::Bind(move(value))); +PreparedStatement::~PreparedStatement() { } -void ExpressionRewriter::VisitOperator(LogicalOperator &op) { - VisitOperatorChildren(op); - this->op = &op; +idx_t PreparedStatement::ColumnCount() { + D_ASSERT(data); + return data->types.size(); +} - 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; - } +StatementType PreparedStatement::GetStatementType() { + D_ASSERT(data); + return data->statement_type; +} - VisitOperatorExpressions(op); +const vector &PreparedStatement::GetTypes() { + D_ASSERT(data); + return data->types; +} - // if it is a LogicalFilter, we split up filter conjunctions again - if (op.type == LogicalOperatorType::LOGICAL_FILTER) { - auto &filter = (LogicalFilter &)op; - filter.SplitPredicates(); +const vector &PreparedStatement::GetNames() { + D_ASSERT(data); + return data->names; +} + +unique_ptr PreparedStatement::Execute(vector &values, bool allow_stream_result) { + auto pending = PendingQuery(values); + if (!pending->success) { + return make_unique(pending->error); } + return pending->Execute(allow_stream_result && data->allow_stream_result); } -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); +unique_ptr PreparedStatement::PendingQuery(vector &values) { + if (!success) { + throw InvalidInputException("Attempting to execute an unsuccessfully prepared statement!"); + } + D_ASSERT(data); + auto result = context->PendingQuery(query, data, values); + return result; } } // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/optimizer/filter_combiner.hpp -// -// -//===----------------------------------------------------------------------===// - - +namespace duckdb { +PreparedStatementData::PreparedStatementData(StatementType type) + : statement_type(type), read_only(true), requires_valid_transaction(true), allow_stream_result(false) { +} +PreparedStatementData::~PreparedStatementData() { +} -#include +void PreparedStatementData::Bind(vector values) { + // set parameters + const auto required = unbound_statement ? unbound_statement->n_param : 0; + if (values.size() != required) { + throw BinderException("Parameter/argument count mismatch for prepared statement. Expected %llu, got %llu", + required, values.size()); + } -namespace duckdb { + // bind the required values + for (auto &it : value_map) { + const idx_t i = it.first - 1; + if (i >= values.size()) { + throw BinderException("Could not find parameter with index %llu", i + 1); + } + D_ASSERT(!it.second.empty()); + if (!values[i].TryCastAs(it.second[0]->type())) { + throw BinderException( + "Type mismatch for binding parameter with index %llu, expected type %s but got type %s", i + 1, + it.second[0]->type().ToString().c_str(), values[i].type().ToString().c_str()); + } + for (auto &target : it.second) { + *target = values[i]; + } + } +} -enum class ValueComparisonResult { PRUNE_LEFT, PRUNE_RIGHT, UNSATISFIABLE_CONDITION, PRUNE_NOTHING }; -enum class FilterResult { UNSATISFIABLE, SUCCESS, UNSUPPORTED }; - -//! The FilterCombiner combines several filters and generates a logically equivalent set that is more efficient -//! Amongst others: -//! (1) it prunes obsolete filter conditions: i.e. [X > 5 and X > 7] => [X > 7] -//! (2) it generates new filters for expressions in the same equivalence set: i.e. [X = Y and X = 500] => [Y = 500] -//! (3) it prunes branches that have unsatisfiable filters: i.e. [X = 5 AND X > 6] => FALSE, prune branch -class FilterCombiner { -public: - struct ExpressionValueInformation { - Value constant; - ExpressionType comparison_type; - }; - - FilterResult AddFilter(unique_ptr expr); - - void GenerateFilters(const std::function filter)> &callback); - bool HasFilters(); - TableFilterSet GenerateTableScanFilters(vector &column_ids); - // vector> GenerateZonemapChecks(vector &column_ids, vector> - // &pushed_filters); - -private: - FilterResult AddFilter(Expression *expr); - FilterResult AddBoundComparisonFilter(Expression *expr); - FilterResult AddTransitiveFilters(BoundComparisonExpression &comparison); - unique_ptr FindTransitiveFilter(Expression *expr); - // unordered_map> - // FindZonemapChecks(vector &column_ids, unordered_set ¬_constants, Expression *filter); - Expression *GetNode(Expression *expr); - idx_t GetEquivalenceSet(Expression *expr); - FilterResult AddConstantComparison(vector &info_list, ExpressionValueInformation info); - -private: - vector> remaining_filters; - - expression_map_t> stored_expressions; - unordered_map equivalence_set_map; - unordered_map> constant_values; - unordered_map> equivalence_map; - idx_t set_index = 0; -}; +LogicalType PreparedStatementData::GetType(idx_t param_idx) { + auto it = value_map.find(param_idx); + if (it == value_map.end()) { + throw BinderException("Could not find parameter with index %llu", param_idx); + } + D_ASSERT(!it->second.empty()); + return it->second[0]->type(); +} } // namespace duckdb - - - - - - - - - - - //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/planner/filter/constant_filter.hpp +// duckdb/common/fstream.hpp // // //===----------------------------------------------------------------------===// - - - +#include +#include namespace duckdb { +using std::endl; +using std::fstream; +using std::ifstream; +using std::ios; +using std::ios_base; +using std::ofstream; +} // namespace duckdb -class ConstantFilter : public TableFilter { -public: - ConstantFilter(ExpressionType comparison_type, Value constant); - - //! The comparison type (e.g. COMPARE_EQUAL, COMPARE_GREATERTHAN, COMPARE_LESSTHAN, ...) - ExpressionType comparison_type; - //! The constant value to filter on - Value constant; -public: - FilterPropagateResult CheckStatistics(BaseStatistics &stats) override; - string ToString(const string &column_name) override; - bool Equals(const TableFilter &other) const override; -}; -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/filter/null_filter.hpp -// -// -//===----------------------------------------------------------------------===// -namespace duckdb { -class IsNullFilter : public TableFilter { -public: - IsNullFilter(); -public: - FilterPropagateResult CheckStatistics(BaseStatistics &stats) override; - string ToString(const string &column_name) override; -}; -class IsNotNullFilter : public TableFilter { -public: - IsNotNullFilter(); -public: - FilterPropagateResult CheckStatistics(BaseStatistics &stats) override; - string ToString(const string &column_name) override; -}; +#include +#include -} // namespace duckdb +namespace duckdb { +QueryProfiler::QueryProfiler(ClientContext &context_p) + : context(context_p), running(false), query_requires_profiling(false), is_explain_analyze(false) { +} +bool QueryProfiler::IsEnabled() const { + return is_explain_analyze ? true : ClientConfig::GetConfig(context).enable_profiler; +} +bool QueryProfiler::IsDetailedEnabled() const { + return is_explain_analyze ? false : ClientConfig::GetConfig(context).enable_detailed_profiling; +} -namespace duckdb { +ProfilerPrintFormat QueryProfiler::GetPrintFormat() const { + return is_explain_analyze ? ProfilerPrintFormat::NONE : ClientConfig::GetConfig(context).profiler_print_format; +} -using ExpressionValueInformation = FilterCombiner::ExpressionValueInformation; +string QueryProfiler::GetSaveLocation() const { + return is_explain_analyze ? string() : ClientConfig::GetConfig(context).profiler_save_location; +} -ValueComparisonResult CompareValueInformation(ExpressionValueInformation &left, ExpressionValueInformation &right); +QueryProfiler &QueryProfiler::Get(ClientContext &context) { + return *context.profiler; +} -Expression *FilterCombiner::GetNode(Expression *expr) { - auto entry = stored_expressions.find(expr); - if (entry != stored_expressions.end()) { - // expression already exists: return a reference to the stored expression - return entry->second.get(); +void QueryProfiler::StartQuery(string query, bool is_explain_analyze) { + if (is_explain_analyze) { + StartExplainAnalyze(); } - // expression does not exist yet: create a copy and store it - 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))); - return pointer_copy; + if (!IsEnabled()) { + return; + } + this->running = true; + this->query = move(query); + tree_map.clear(); + root = nullptr; + phase_timings.clear(); + phase_stack.clear(); + + main_query.Start(); } -idx_t FilterCombiner::GetEquivalenceSet(Expression *expr) { - D_ASSERT(stored_expressions.find(expr) != stored_expressions.end()); - D_ASSERT(stored_expressions.find(expr)->second.get() == expr); - auto entry = equivalence_set_map.find(expr); - if (entry == equivalence_set_map.end()) { - idx_t index = set_index++; - equivalence_set_map[expr] = index; - equivalence_map[index].push_back(expr); - constant_values.insert(make_pair(index, vector())); - return index; - } else { - return entry->second; +bool QueryProfiler::OperatorRequiresProfiling(PhysicalOperatorType op_type) { + switch (op_type) { + case PhysicalOperatorType::ORDER_BY: + case PhysicalOperatorType::RESERVOIR_SAMPLE: + case PhysicalOperatorType::STREAMING_SAMPLE: + case PhysicalOperatorType::LIMIT: + case PhysicalOperatorType::LIMIT_PERCENT: + case PhysicalOperatorType::TOP_N: + case PhysicalOperatorType::WINDOW: + case PhysicalOperatorType::UNNEST: + case PhysicalOperatorType::SIMPLE_AGGREGATE: + case PhysicalOperatorType::HASH_GROUP_BY: + case PhysicalOperatorType::FILTER: + case PhysicalOperatorType::PROJECTION: + case PhysicalOperatorType::COPY_TO_FILE: + case PhysicalOperatorType::TABLE_SCAN: + case PhysicalOperatorType::CHUNK_SCAN: + case PhysicalOperatorType::DELIM_SCAN: + case PhysicalOperatorType::EXPRESSION_SCAN: + case PhysicalOperatorType::BLOCKWISE_NL_JOIN: + case PhysicalOperatorType::NESTED_LOOP_JOIN: + case PhysicalOperatorType::HASH_JOIN: + case PhysicalOperatorType::CROSS_PRODUCT: + case PhysicalOperatorType::PIECEWISE_MERGE_JOIN: + case PhysicalOperatorType::DELIM_JOIN: + case PhysicalOperatorType::UNION: + case PhysicalOperatorType::RECURSIVE_CTE: + case PhysicalOperatorType::EMPTY_RESULT: + return true; + default: + return false; } } -FilterResult FilterCombiner::AddConstantComparison(vector &info_list, - ExpressionValueInformation info) { - for (idx_t i = 0; i < info_list.size(); i++) { - auto comparison = CompareValueInformation(info_list[i], info); - switch (comparison) { - case ValueComparisonResult::PRUNE_LEFT: - // prune the entry from the info list - info_list.erase(info_list.begin() + i); - i--; - break; - case ValueComparisonResult::PRUNE_RIGHT: - // prune the current info - return FilterResult::SUCCESS; - case ValueComparisonResult::UNSATISFIABLE_CONDITION: - // combination of filters is unsatisfiable: prune the entire branch - return FilterResult::UNSATISFIABLE; - default: - // prune nothing, move to the next condition - break; +void QueryProfiler::Finalize(TreeNode &node) { + for (auto &child : node.children) { + Finalize(*child); + if (node.type == PhysicalOperatorType::UNION) { + node.info.elements += child->info.elements; } } - // finally add the entry to the list - info_list.push_back(info); - return FilterResult::SUCCESS; } -FilterResult FilterCombiner::AddFilter(unique_ptr expr) { - // try to push the filter into the combiner - auto result = AddFilter(expr.get()); - if (result == FilterResult::UNSUPPORTED) { - // unsupported filter, push into remaining filters - remaining_filters.push_back(move(expr)); - return FilterResult::SUCCESS; - } - return result; +void QueryProfiler::StartExplainAnalyze() { + this->is_explain_analyze = true; } -void FilterCombiner::GenerateFilters(const std::function filter)> &callback) { - // first loop over the remaining filters - for (auto &filter : remaining_filters) { - callback(move(filter)); +void QueryProfiler::EndQuery() { + lock_guard guard(flush_lock); + if (!IsEnabled() || !running) { + return; } - remaining_filters.clear(); - // now loop over the equivalence sets - for (auto &entry : equivalence_map) { - auto equivalence_set = entry.first; - auto &entries = entry.second; - auto &constant_list = constant_values.find(equivalence_set)->second; - // for each entry generate an equality expression comparing to each other - for (idx_t i = 0; i < entries.size(); i++) { - for (idx_t k = i + 1; k < entries.size(); k++) { - auto comparison = make_unique(ExpressionType::COMPARE_EQUAL, - entries[i]->Copy(), entries[k]->Copy()); - callback(move(comparison)); - } - // for each entry also create a comparison with each constant - int lower_index = -1, upper_index = -1; - bool lower_inclusive, upper_inclusive; - for (idx_t k = 0; k < constant_list.size(); k++) { - auto &info = constant_list[k]; - if (info.comparison_type == ExpressionType::COMPARE_GREATERTHAN || - info.comparison_type == ExpressionType::COMPARE_GREATERTHANOREQUALTO) { - lower_index = k; - lower_inclusive = info.comparison_type == ExpressionType::COMPARE_GREATERTHANOREQUALTO; - } else if (info.comparison_type == ExpressionType::COMPARE_LESSTHAN || - info.comparison_type == ExpressionType::COMPARE_LESSTHANOREQUALTO) { - upper_index = k; - upper_inclusive = info.comparison_type == ExpressionType::COMPARE_LESSTHANOREQUALTO; - } else { - auto constant = make_unique(info.constant); - auto comparison = make_unique(info.comparison_type, entries[i]->Copy(), - move(constant)); - callback(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)); - } 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)); - } 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)); - } + + main_query.End(); + if (root) { + Finalize(*root); + } + this->running = false; + auto automatic_print_format = GetPrintFormat(); + // print or output the query profiling after termination, if this is enabled + if (automatic_print_format != ProfilerPrintFormat::NONE) { + // check if this query should be output based on the operator types + string query_info; + if (automatic_print_format == ProfilerPrintFormat::JSON) { + query_info = ToJSON(); + } else if (automatic_print_format == ProfilerPrintFormat::QUERY_TREE) { + query_info = ToString(); + } else if (automatic_print_format == ProfilerPrintFormat::QUERY_TREE_OPTIMIZER) { + query_info = ToString(true); + } + auto save_location = GetSaveLocation(); + if (save_location.empty()) { + Printer::Print(query_info); + Printer::Print("\n"); + } else { + WriteToFile(save_location.c_str(), query_info); } } - stored_expressions.clear(); - equivalence_set_map.clear(); - constant_values.clear(); - equivalence_map.clear(); + this->is_explain_analyze = false; } -bool FilterCombiner::HasFilters() { - bool has_filters = false; - GenerateFilters([&](unique_ptr child) { has_filters = true; }); - return has_filters; -} +void QueryProfiler::StartPhase(string new_phase) { + if (!IsEnabled() || !running) { + return; + } -// unordered_map> MergeAnd(unordered_map> &f_1, -// unordered_map> &f_2) { -// unordered_map> result; -// for (auto &f : f_1) { -// auto it = f_2.find(f.first); -// if (it == f_2.end()) { -// result[f.first] = f.second; -// } else { -// Value *min = nullptr, *max = nullptr; -// if (it->second.first && f.second.first) { -// if (*f.second.first > *it->second.first) { -// min = f.second.first; -// } else { -// min = it->second.first; -// } + if (!phase_stack.empty()) { + // there are active phases + phase_profiler.End(); + // add the timing to all phases prior to this one + string prefix = ""; + for (auto &phase : phase_stack) { + phase_timings[phase] += phase_profiler.Elapsed(); + prefix += phase + " > "; + } + // when there are previous phases, we prefix the current phase with those phases + new_phase = prefix + new_phase; + } -// } else if (it->second.first) { -// min = it->second.first; -// } else if (f.second.first) { -// min = f.second.first; -// } else { -// min = nullptr; -// } -// if (it->second.second && f.second.second) { -// if (*f.second.second < *it->second.second) { -// max = f.second.second; -// } else { -// max = it->second.second; -// } -// } else if (it->second.second) { -// max = it->second.second; -// } else if (f.second.second) { -// max = f.second.second; -// } else { -// max = nullptr; -// } -// result[f.first] = {min, max}; -// f_2.erase(f.first); -// } -// } -// for (auto &f : f_2) { -// result[f.first] = f.second; -// } -// return result; -// } + // start a new phase + phase_stack.push_back(new_phase); + // restart the timer + phase_profiler.Start(); +} -// unordered_map> MergeOr(unordered_map> &f_1, -// unordered_map> &f_2) { -// unordered_map> result; -// for (auto &f : f_1) { -// auto it = f_2.find(f.first); -// if (it != f_2.end()) { -// Value *min = nullptr, *max = nullptr; -// if (it->second.first && f.second.first) { -// if (*f.second.first < *it->second.first) { -// min = f.second.first; -// } else { -// min = it->second.first; -// } -// } -// if (it->second.second && f.second.second) { -// if (*f.second.second > *it->second.second) { -// max = f.second.second; -// } else { -// max = it->second.second; -// } -// } -// result[f.first] = {min, max}; -// f_2.erase(f.first); -// } -// } -// return result; -// } +void QueryProfiler::EndPhase() { + if (!IsEnabled() || !running) { + return; + } + D_ASSERT(phase_stack.size() > 0); -// unordered_map> -// FilterCombiner::FindZonemapChecks(vector &column_ids, unordered_set ¬_constants, Expression *filter) -// { unordered_map> checks; switch (filter->type) { case -// ExpressionType::CONJUNCTION_OR: { -// //! For a filter to -// auto &or_exp = (BoundConjunctionExpression &)*filter; -// checks = FindZonemapChecks(column_ids, not_constants, or_exp.children[0].get()); -// for (size_t i = 1; i < or_exp.children.size(); ++i) { -// auto child_check = FindZonemapChecks(column_ids, not_constants, or_exp.children[i].get()); -// checks = MergeOr(checks, child_check); -// } -// return checks; -// } -// case ExpressionType::CONJUNCTION_AND: { -// auto &and_exp = (BoundConjunctionExpression &)*filter; -// checks = FindZonemapChecks(column_ids, not_constants, and_exp.children[0].get()); -// for (size_t i = 1; i < and_exp.children.size(); ++i) { -// auto child_check = FindZonemapChecks(column_ids, not_constants, and_exp.children[i].get()); -// checks = MergeAnd(checks, child_check); -// } -// return checks; -// } -// case ExpressionType::COMPARE_IN: { -// auto &comp_in_exp = (BoundOperatorExpression &)*filter; -// if (comp_in_exp.children[0]->type == ExpressionType::BOUND_COLUMN_REF) { -// Value *min = nullptr, *max = nullptr; -// auto &column_ref = (BoundColumnRefExpression &)*comp_in_exp.children[0].get(); -// for (size_t i {1}; i < comp_in_exp.children.size(); i++) { -// if (comp_in_exp.children[i]->type != ExpressionType::VALUE_CONSTANT) { -// //! This indicates the column has a comparison that is not with a constant -// not_constants.insert(column_ids[column_ref.binding.column_index]); -// break; -// } else { -// auto &const_value_expr = (BoundConstantExpression &)*comp_in_exp.children[i].get(); -// if (const_value_expr.value.is_null) { -// return checks; -// } -// if (!min && !max) { -// min = &const_value_expr.value; -// max = min; -// } else { -// if (*min > const_value_expr.value) { -// min = &const_value_expr.value; -// } -// if (*max < const_value_expr.value) { -// max = &const_value_expr.value; -// } -// } -// } -// } -// checks[column_ids[column_ref.binding.column_index]] = {min, max}; -// } -// return checks; -// } -// case ExpressionType::COMPARE_EQUAL: { -// auto &comp_exp = (BoundComparisonExpression &)*filter; -// if ((comp_exp.left->expression_class == ExpressionClass::BOUND_COLUMN_REF && -// comp_exp.right->expression_class == ExpressionClass::BOUND_CONSTANT)) { -// auto &column_ref = (BoundColumnRefExpression &)*comp_exp.left; -// auto &constant_value_expr = (BoundConstantExpression &)*comp_exp.right; -// checks[column_ids[column_ref.binding.column_index]] = {&constant_value_expr.value, -// &constant_value_expr.value}; -// } -// if ((comp_exp.left->expression_class == ExpressionClass::BOUND_CONSTANT && -// comp_exp.right->expression_class == ExpressionClass::BOUND_COLUMN_REF)) { -// auto &column_ref = (BoundColumnRefExpression &)*comp_exp.right; -// auto &constant_value_expr = (BoundConstantExpression &)*comp_exp.left; -// checks[column_ids[column_ref.binding.column_index]] = {&constant_value_expr.value, -// &constant_value_expr.value}; -// } -// return checks; -// } -// case ExpressionType::COMPARE_LESSTHAN: -// case ExpressionType::COMPARE_LESSTHANOREQUALTO: { -// auto &comp_exp = (BoundComparisonExpression &)*filter; -// if ((comp_exp.left->expression_class == ExpressionClass::BOUND_COLUMN_REF && -// comp_exp.right->expression_class == ExpressionClass::BOUND_CONSTANT)) { -// auto &column_ref = (BoundColumnRefExpression &)*comp_exp.left; -// auto &constant_value_expr = (BoundConstantExpression &)*comp_exp.right; -// checks[column_ids[column_ref.binding.column_index]] = {nullptr, &constant_value_expr.value}; -// } -// if ((comp_exp.left->expression_class == ExpressionClass::BOUND_CONSTANT && -// comp_exp.right->expression_class == ExpressionClass::BOUND_COLUMN_REF)) { -// auto &column_ref = (BoundColumnRefExpression &)*comp_exp.right; -// auto &constant_value_expr = (BoundConstantExpression &)*comp_exp.left; -// checks[column_ids[column_ref.binding.column_index]] = {&constant_value_expr.value, nullptr}; -// } -// return checks; -// } -// case ExpressionType::COMPARE_GREATERTHANOREQUALTO: -// case ExpressionType::COMPARE_GREATERTHAN: { -// auto &comp_exp = (BoundComparisonExpression &)*filter; -// if ((comp_exp.left->expression_class == ExpressionClass::BOUND_COLUMN_REF && -// comp_exp.right->expression_class == ExpressionClass::BOUND_CONSTANT)) { -// auto &column_ref = (BoundColumnRefExpression &)*comp_exp.left; -// auto &constant_value_expr = (BoundConstantExpression &)*comp_exp.right; -// checks[column_ids[column_ref.binding.column_index]] = {&constant_value_expr.value, nullptr}; -// } -// if ((comp_exp.left->expression_class == ExpressionClass::BOUND_CONSTANT && -// comp_exp.right->expression_class == ExpressionClass::BOUND_COLUMN_REF)) { -// auto &column_ref = (BoundColumnRefExpression &)*comp_exp.right; -// auto &constant_value_expr = (BoundConstantExpression &)*comp_exp.left; -// checks[column_ids[column_ref.binding.column_index]] = {nullptr, &constant_value_expr.value}; -// } -// return checks; -// } -// default: -// return checks; -// } -// } + // end the timer + phase_profiler.End(); + // add the timing to all currently active phases + for (auto &phase : phase_stack) { + phase_timings[phase] += phase_profiler.Elapsed(); + } + // now remove the last added phase + phase_stack.pop_back(); -// vector FilterCombiner::GenerateZonemapChecks(vector &column_ids, -// vector &pushed_filters) { -// vector zonemap_checks; -// unordered_set not_constants; -// //! We go through the remaining filters and capture their min max -// if (remaining_filters.empty()) { -// return zonemap_checks; -// } + if (!phase_stack.empty()) { + phase_profiler.Start(); + } +} -// auto checks = FindZonemapChecks(column_ids, not_constants, remaining_filters[0].get()); -// for (size_t i = 1; i < remaining_filters.size(); ++i) { -// auto child_check = FindZonemapChecks(column_ids, not_constants, remaining_filters[i].get()); -// checks = MergeAnd(checks, child_check); -// } -// //! We construct the equivalent filters -// for (auto not_constant : not_constants) { -// checks.erase(not_constant); -// } -// for (const auto &pushed_filter : pushed_filters) { -// checks.erase(column_ids[pushed_filter.column_index]); -// } -// for (const auto &check : checks) { -// if (check.second.first) { -// zonemap_checks.emplace_back(check.second.first->Copy(), ExpressionType::COMPARE_GREATERTHANOREQUALTO, -// check.first); -// } -// if (check.second.second) { -// zonemap_checks.emplace_back(check.second.second->Copy(), ExpressionType::COMPARE_LESSTHANOREQUALTO, -// check.first); -// } -// } -// return zonemap_checks; -// } +void QueryProfiler::Initialize(PhysicalOperator *root_op) { + if (!IsEnabled() || !running) { + return; + } + this->query_requires_profiling = false; + this->root = CreateTree(root_op); + if (!query_requires_profiling) { + // query does not require profiling: disable profiling for this query + this->running = false; + tree_map.clear(); + root = nullptr; + phase_timings.clear(); + phase_stack.clear(); + } +} -TableFilterSet FilterCombiner::GenerateTableScanFilters(vector &column_ids) { - TableFilterSet table_filters; - //! First, we figure the filters that have constant expressions that we can push down to the table scan - for (auto &constant_value : constant_values) { - if (!constant_value.second.empty()) { - auto filter_exp = equivalence_map.end(); - if ((constant_value.second[0].comparison_type == ExpressionType::COMPARE_EQUAL || - constant_value.second[0].comparison_type == ExpressionType::COMPARE_GREATERTHAN || - constant_value.second[0].comparison_type == ExpressionType::COMPARE_GREATERTHANOREQUALTO || - constant_value.second[0].comparison_type == ExpressionType::COMPARE_LESSTHAN || - constant_value.second[0].comparison_type == ExpressionType::COMPARE_LESSTHANOREQUALTO) && - (TypeIsNumeric(constant_value.second[0].constant.type().InternalType()) || - constant_value.second[0].constant.type().InternalType() == PhysicalType::VARCHAR || - constant_value.second[0].constant.type().InternalType() == PhysicalType::BOOL)) { - //! Here we check if these filters are column references - filter_exp = equivalence_map.find(constant_value.first); - if (filter_exp->second.size() == 1 && filter_exp->second[0]->type == ExpressionType::BOUND_COLUMN_REF) { - auto filter_col_exp = static_cast(filter_exp->second[0]); - auto column_index = column_ids[filter_col_exp->binding.column_index]; - if (column_index == COLUMN_IDENTIFIER_ROW_ID) { - break; - } - auto equivalence_set = filter_exp->first; - auto &entries = filter_exp->second; - auto &constant_list = constant_values.find(equivalence_set)->second; - // for each entry generate an equality expression comparing to each other - for (idx_t i = 0; i < entries.size(); i++) { - // for each entry also create a comparison with each constant - 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, make_unique()); - } - equivalence_map.erase(filter_exp); - } - } - } +OperatorProfiler::OperatorProfiler(bool enabled_p) : enabled(enabled_p), active_operator(nullptr) { +} + +void OperatorProfiler::StartOperator(const PhysicalOperator *phys_op) { + if (!enabled) { + return; } - //! Here we look for LIKE or IN filters - for (idx_t rem_fil_idx = 0; rem_fil_idx < remaining_filters.size(); rem_fil_idx++) { - auto &remaining_filter = remaining_filters[rem_fil_idx]; - if (remaining_filter->expression_class == ExpressionClass::BOUND_FUNCTION) { - auto &func = (BoundFunctionExpression &)*remaining_filter; - if (func.function.name == "prefix" && - func.children[0]->expression_class == ExpressionClass::BOUND_COLUMN_REF && - func.children[1]->type == ExpressionType::VALUE_CONSTANT) { - //! This is a like function. - auto &column_ref = (BoundColumnRefExpression &)*func.children[0].get(); - auto &constant_value_expr = (BoundConstantExpression &)*func.children[1].get(); - string like_string = constant_value_expr.value.str_value; - if (like_string.empty()) { - continue; - } - auto column_index = column_ids[column_ref.binding.column_index]; - auto const_value = constant_value_expr.value.Copy(); - const_value.str_value = like_string; - //! Here the like must be transformed to a BOUND COMPARISON geq le - auto lower_bound = - make_unique(ExpressionType::COMPARE_GREATERTHANOREQUALTO, const_value); - const_value.str_value[const_value.str_value.size() - 1]++; - auto upper_bound = make_unique(ExpressionType::COMPARE_LESSTHAN, const_value); - table_filters.PushFilter(column_index, move(lower_bound)); - table_filters.PushFilter(column_index, move(upper_bound)); - table_filters.PushFilter(column_index, make_unique()); - } - if (func.function.name == "~~" && func.children[0]->expression_class == ExpressionClass::BOUND_COLUMN_REF && - func.children[1]->type == ExpressionType::VALUE_CONSTANT) { - //! This is a like function. - auto &column_ref = (BoundColumnRefExpression &)*func.children[0].get(); - auto &constant_value_expr = (BoundConstantExpression &)*func.children[1].get(); - string like_string = constant_value_expr.value.str_value; - auto const_value = constant_value_expr.value.Copy(); - if (like_string[0] == '%' || like_string[0] == '_') { - //! We have no prefix so nothing to pushdown - break; - } - string prefix; - bool equality = true; - for (char const &c : like_string) { - if (c == '%' || c == '_') { - equality = false; - break; - } - prefix += c; - } - const_value.str_value = prefix; - auto column_index = column_ids[column_ref.binding.column_index]; - if (equality) { - //! Here the like can be transformed to an equality query - auto equal_filter = make_unique(ExpressionType::COMPARE_EQUAL, const_value); - table_filters.PushFilter(column_index, move(equal_filter)); - table_filters.PushFilter(column_index, make_unique()); - } else { - //! Here the like must be transformed to a BOUND COMPARISON geq le - auto lower_bound = - make_unique(ExpressionType::COMPARE_GREATERTHANOREQUALTO, const_value); - const_value.str_value[const_value.str_value.size() - 1]++; - auto upper_bound = make_unique(ExpressionType::COMPARE_LESSTHAN, const_value); - table_filters.PushFilter(column_index, move(lower_bound)); - table_filters.PushFilter(column_index, move(upper_bound)); - table_filters.PushFilter(column_index, make_unique()); - } - } - } else if (remaining_filter->type == ExpressionType::COMPARE_IN) { - auto &func = (BoundOperatorExpression &)*remaining_filter; - vector in_values; - D_ASSERT(func.children.size() > 1); - if (func.children[0]->expression_class != ExpressionClass::BOUND_COLUMN_REF) { - continue; - } - auto &column_ref = (BoundColumnRefExpression &)*func.children[0].get(); - auto column_index = column_ids[column_ref.binding.column_index]; - if (column_index == COLUMN_IDENTIFIER_ROW_ID) { - break; - } - //! check if all children are const expr - bool children_constant = true; - for (size_t i {1}; i < func.children.size(); i++) { - if (func.children[i]->type != ExpressionType::VALUE_CONSTANT) { - children_constant = false; - } - } - if (!children_constant) { - continue; - } - auto &fst_const_value_expr = (BoundConstantExpression &)*func.children[1].get(); - //! Check if values are consecutive, if yes transform them to >= <= (only for integers) - // e.g. if we have x IN (1, 2, 3, 4, 5) we transform this into x >= 1 AND x <= 5 - if (!fst_const_value_expr.value.type().IsIntegral()) { - continue; - } + if (active_operator) { + throw InternalException("OperatorProfiler: Attempting to call StartOperator while another operator is active"); + } - bool can_simplify_in_clause = true; - for (idx_t i = 1; i < func.children.size(); i++) { - auto &const_value_expr = (BoundConstantExpression &)*func.children[i].get(); - if (const_value_expr.value.is_null) { - can_simplify_in_clause = false; - break; - } - in_values.push_back(const_value_expr.value); - } - if (!can_simplify_in_clause || in_values.empty()) { - continue; - } - Value one(1); + active_operator = phys_op; - sort(in_values.begin(), in_values.end()); + // start timing for current element + op.Start(); +} - for (idx_t in_val_idx = 1; in_val_idx < in_values.size(); in_val_idx++) { - if (in_values[in_val_idx] - in_values[in_val_idx - 1] > one || in_values[in_val_idx - 1].is_null) { - can_simplify_in_clause = false; - break; - } - } - if (!can_simplify_in_clause) { - continue; - } - auto lower_bound = - make_unique(ExpressionType::COMPARE_GREATERTHANOREQUALTO, in_values.front()); - auto upper_bound = make_unique(ExpressionType::COMPARE_LESSTHANOREQUALTO, in_values.back()); - table_filters.PushFilter(column_index, move(lower_bound)); - table_filters.PushFilter(column_index, move(upper_bound)); - table_filters.PushFilter(column_index, make_unique()); +void OperatorProfiler::EndOperator(DataChunk *chunk) { + if (!enabled) { + return; + } - remaining_filters.erase(remaining_filters.begin() + rem_fil_idx); - } + if (!active_operator) { + throw InternalException("OperatorProfiler: Attempting to call EndOperator while another operator is active"); } - return table_filters; -} + // finish timing for the current element + op.End(); -static bool IsGreaterThan(ExpressionType type) { - return type == ExpressionType::COMPARE_GREATERTHAN || type == ExpressionType::COMPARE_GREATERTHANOREQUALTO; + AddTiming(active_operator, op.Elapsed(), chunk ? chunk->size() : 0); + active_operator = nullptr; } -static bool IsLessThan(ExpressionType type) { - return type == ExpressionType::COMPARE_LESSTHAN || type == ExpressionType::COMPARE_LESSTHANOREQUALTO; +void OperatorProfiler::AddTiming(const PhysicalOperator *op, double time, idx_t elements) { + if (!enabled) { + return; + } + if (!Value::DoubleIsValid(time)) { + return; + } + auto entry = timings.find(op); + if (entry == timings.end()) { + // add new entry + timings[op] = OperatorInformation(time, elements); + } else { + // add to existing entry + entry->second.time += time; + entry->second.elements += elements; + } } - -FilterResult FilterCombiner::AddBoundComparisonFilter(Expression *expr) { - auto &comparison = (BoundComparisonExpression &)*expr; - if (comparison.type != ExpressionType::COMPARE_LESSTHAN && - comparison.type != ExpressionType::COMPARE_LESSTHANOREQUALTO && - comparison.type != ExpressionType::COMPARE_GREATERTHAN && - comparison.type != ExpressionType::COMPARE_GREATERTHANOREQUALTO && - comparison.type != ExpressionType::COMPARE_EQUAL && comparison.type != ExpressionType::COMPARE_NOTEQUAL) { - // only support [>, >=, <, <=, ==] expressions - return FilterResult::UNSUPPORTED; +void OperatorProfiler::Flush(const PhysicalOperator *phys_op, ExpressionExecutor *expression_executor, + const string &name, int id) { + auto entry = timings.find(phys_op); + if (entry == timings.end()) { + return; } - // check if one of the sides is a scalar value - bool left_is_scalar = comparison.left->IsFoldable(); - bool right_is_scalar = comparison.right->IsFoldable(); - if (left_is_scalar || right_is_scalar) { - // comparison with scalar - auto node = GetNode(left_is_scalar ? comparison.right.get() : comparison.left.get()); - idx_t equivalence_set = GetEquivalenceSet(node); - auto scalar = left_is_scalar ? comparison.left.get() : comparison.right.get(); - auto constant_value = ExpressionExecutor::EvaluateScalar(*scalar); - if (constant_value.is_null) { - // comparisons with null are always null (i.e. will never result in rows) - return FilterResult::UNSATISFIABLE; - } - - // create the ExpressionValueInformation - ExpressionValueInformation info; - info.comparison_type = left_is_scalar ? FlipComparisionExpression(comparison.type) : comparison.type; - info.constant = constant_value; + auto &operator_timing = timings.find(phys_op)->second; + if (int(operator_timing.executors_info.size()) <= id) { + operator_timing.executors_info.resize(id + 1); + } + operator_timing.executors_info[id] = make_unique(*expression_executor, name, id); + operator_timing.name = phys_op->GetName(); +} - // 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; - // check the existing constant comparisons to see if we can do any pruning - auto ret = AddConstantComparison(info_list, info); +void QueryProfiler::Flush(OperatorProfiler &profiler) { + lock_guard guard(flush_lock); + if (!IsEnabled() || !running) { + return; + } + for (auto &node : profiler.timings) { + auto entry = tree_map.find(node.first); + D_ASSERT(entry != tree_map.end()); - auto non_scalar = left_is_scalar ? comparison.right.get() : comparison.left.get(); - auto transitive_filter = FindTransitiveFilter(non_scalar); - if (transitive_filter != nullptr) { - // 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)); - } + entry->second->info.time += node.second.time; + entry->second->info.elements += node.second.elements; + if (!IsDetailedEnabled()) { + continue; } - return ret; - } else { - // comparison between two non-scalars - // only handle comparisons for now - if (expr->type != ExpressionType::COMPARE_EQUAL) { - if (IsGreaterThan(expr->type) || IsLessThan(expr->type)) { - return AddTransitiveFilters(comparison); + for (auto &info : node.second.executors_info) { + if (!info) { + continue; } - return FilterResult::UNSUPPORTED; - } - // get the LHS and RHS nodes - auto left_node = GetNode(comparison.left.get()); - auto right_node = GetNode(comparison.right.get()); - if (BaseExpression::Equals(left_node, right_node)) { - return FilterResult::UNSUPPORTED; - } - // get the equivalence sets of the LHS and RHS - auto left_equivalence_set = GetEquivalenceSet(left_node); - auto right_equivalence_set = GetEquivalenceSet(right_node); - if (left_equivalence_set == right_equivalence_set) { - // this equality filter already exists, prune it - return FilterResult::SUCCESS; - } - // add the right bucket into the left bucket - D_ASSERT(equivalence_map.find(left_equivalence_set) != equivalence_map.end()); - D_ASSERT(equivalence_map.find(right_equivalence_set) != equivalence_map.end()); - - auto &left_bucket = equivalence_map.find(left_equivalence_set)->second; - auto &right_bucket = equivalence_map.find(right_equivalence_set)->second; - for (auto &i : right_bucket) { - // rewrite the equivalence set mapping for this node - equivalence_set_map[i] = left_equivalence_set; - // add the node to the left bucket - left_bucket.push_back(i); - } - // now add all constant values from the right bucket to the left bucket - D_ASSERT(constant_values.find(left_equivalence_set) != constant_values.end()); - D_ASSERT(constant_values.find(right_equivalence_set) != constant_values.end()); - auto &left_constant_bucket = constant_values.find(left_equivalence_set)->second; - auto &right_constant_bucket = constant_values.find(right_equivalence_set)->second; - for (auto &i : right_constant_bucket) { - if (AddConstantComparison(left_constant_bucket, i) == FilterResult::UNSATISFIABLE) { - return FilterResult::UNSATISFIABLE; + auto info_id = info->id; + 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); } } - return FilterResult::SUCCESS; + profiler.timings.clear(); } -FilterResult FilterCombiner::AddFilter(Expression *expr) { - if (expr->HasParameter()) { - return FilterResult::UNSUPPORTED; - } - if (expr->IsFoldable()) { - // scalar condition, evaluate it - auto result = ExpressionExecutor::EvaluateScalar(*expr).CastAs(LogicalType::BOOLEAN); - // check if the filter passes - if (result.is_null || !result.value_.boolean) { - // the filter does not pass the scalar test, create an empty result - return FilterResult::UNSATISFIABLE; - } else { - // the filter passes the scalar test, just remove the condition - return FilterResult::SUCCESS; - } +static string DrawPadded(const string &str, idx_t width) { + if (str.size() > width) { + return str.substr(0, width); + } else { + width -= str.size(); + int half_spaces = width / 2; + int extra_left_space = width % 2 != 0 ? 1 : 0; + return string(half_spaces + extra_left_space, ' ') + str + string(half_spaces, ' '); } - D_ASSERT(!expr->IsFoldable()); - if (expr->GetExpressionClass() == ExpressionClass::BOUND_BETWEEN) { - auto &comparison = (BoundBetweenExpression &)*expr; - //! check if one of the sides is a scalar value - bool left_is_scalar = comparison.lower->IsFoldable(); - bool right_is_scalar = comparison.upper->IsFoldable(); - if (left_is_scalar || right_is_scalar) { - //! comparison with scalar - auto node = GetNode(comparison.input.get()); - idx_t equivalence_set = GetEquivalenceSet(node); - auto scalar = comparison.lower.get(); - auto constant_value = ExpressionExecutor::EvaluateScalar(*scalar); - - // create the ExpressionValueInformation - ExpressionValueInformation info; - if (comparison.lower_inclusive) { - info.comparison_type = ExpressionType::COMPARE_GREATERTHANOREQUALTO; - } else { - info.comparison_type = ExpressionType::COMPARE_GREATERTHAN; - } - info.constant = constant_value; - - // 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; - // check the existing constant comparisons to see if we can do any pruning - AddConstantComparison(info_list, info); - scalar = comparison.upper.get(); - constant_value = ExpressionExecutor::EvaluateScalar(*scalar); +} - // create the ExpressionValueInformation - if (comparison.upper_inclusive) { - info.comparison_type = ExpressionType::COMPARE_LESSTHANOREQUALTO; - } else { - info.comparison_type = ExpressionType::COMPARE_LESSTHAN; +static string RenderTitleCase(string str) { + str = StringUtil::Lower(str); + str[0] = toupper(str[0]); + for (idx_t i = 0; i < str.size(); i++) { + if (str[i] == '_') { + str[i] = ' '; + if (i + 1 < str.size()) { + str[i + 1] = toupper(str[i + 1]); } - info.constant = constant_value; - - // get the current bucket of constant values - D_ASSERT(constant_values.find(equivalence_set) != constant_values.end()); - // check the existing constant comparisons to see if we can do any pruning - return AddConstantComparison(constant_values.find(equivalence_set)->second, info); } - } else if (expr->GetExpressionClass() == ExpressionClass::BOUND_COMPARISON) { - return AddBoundComparisonFilter(expr); } - // only comparisons supported for now - return FilterResult::UNSUPPORTED; + return str; } -/* - * Create and add new transitive filters from a two non-scalar filter such as j > i, j >= i, j < i, and j <= i - * It's missing to create another method to add transitive filters from scalar filters, e.g, i > 10 - */ -FilterResult FilterCombiner::AddTransitiveFilters(BoundComparisonExpression &comparison) { - D_ASSERT(IsGreaterThan(comparison.type) || IsLessThan(comparison.type)); - // get the LHS and RHS nodes - Expression *left_node = GetNode(comparison.left.get()); - Expression *right_node = GetNode(comparison.right.get()); - // In case with filters like CAST(i) = j and i = 5 we replace the COLUMN_REF i with the constant 5 - if (right_node->type == ExpressionType::OPERATOR_CAST) { - auto &bound_cast_expr = (BoundCastExpression &)*right_node; - if (bound_cast_expr.child->type == ExpressionType::BOUND_COLUMN_REF) { - auto &col_ref = (BoundColumnRefExpression &)*bound_cast_expr.child; - 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) { - bound_cast_expr.child = stored_exp.second->Copy(); - right_node = GetNode(bound_cast_expr.child.get()); - break; - } - } - } - } +static string RenderTiming(double timing) { + string timing_s; + if (timing >= 1) { + timing_s = StringUtil::Format("%.2f", timing); + } else if (timing >= 0.1) { + timing_s = StringUtil::Format("%.3f", timing); + } else { + timing_s = StringUtil::Format("%.4f", timing); } + return timing_s + "s"; +} - if (BaseExpression::Equals(left_node, right_node)) { - return FilterResult::UNSUPPORTED; +string QueryProfiler::ToString(bool print_optimizer_output) const { + std::stringstream str; + ToStream(str, print_optimizer_output); + return str.str(); +} + +void QueryProfiler::ToStream(std::ostream &ss, bool print_optimizer_output) const { + if (!IsEnabled()) { + ss << "Query profiling is disabled. Call " + "Connection::EnableProfiling() to enable profiling!"; + return; } - // get the equivalence sets of the LHS and RHS - idx_t left_equivalence_set = GetEquivalenceSet(left_node); - idx_t right_equivalence_set = GetEquivalenceSet(right_node); - if (left_equivalence_set == right_equivalence_set) { - // this equality filter already exists, prune it - return FilterResult::SUCCESS; + ss << "┌─────────────────────────────────────┐\n"; + ss << "│┌───────────────────────────────────┐│\n"; + ss << "││ Query Profiling Information ││\n"; + ss << "│└───────────────────────────────────┘│\n"; + ss << "└─────────────────────────────────────┘\n"; + ss << StringUtil::Replace(query, "\n", " ") + "\n"; + if (query.empty()) { + return; } - vector &left_constants = constant_values.find(left_equivalence_set)->second; - vector &right_constants = constant_values.find(right_equivalence_set)->second; - bool is_successful = false; - bool is_inserted = false; - // read every constant filters already inserted for the right scalar variable - // and see if we can create new transitive filters, e.g., there is already a filter i > 10, - // suppose that we have now the j >= i, then we can infer a new filter j > 10 - for (const auto &right_constant : right_constants) { - ExpressionValueInformation info; - info.constant = right_constant.constant; - // there is already an equality filter, e.g., i = 10 - if (right_constant.comparison_type == ExpressionType::COMPARE_EQUAL) { - // create filter j [>, >=, <, <=] 10 - // suppose the new comparison is j >= i and we have already a filter i = 10, - // then we create a new filter j >= 10 - // and the filter j >= i can be pruned by not adding it into the remaining filters - info.comparison_type = comparison.type; - } else if ((comparison.type == ExpressionType::COMPARE_GREATERTHANOREQUALTO && - IsGreaterThan(right_constant.comparison_type)) || - (comparison.type == ExpressionType::COMPARE_LESSTHANOREQUALTO && - IsLessThan(right_constant.comparison_type))) { - // filters (j >= i AND i [>, >=] 10) OR (j <= i AND i [<, <=] 10) - // create filter j [>, >=] 10 and add the filter j [>=, <=] i into the remaining filters - info.comparison_type = right_constant.comparison_type; // create filter j [>, >=, <, <=] 10 - if (!is_inserted) { - // 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)); - is_inserted = true; - } - } else if ((comparison.type == ExpressionType::COMPARE_GREATERTHAN && - IsGreaterThan(right_constant.comparison_type)) || - (comparison.type == ExpressionType::COMPARE_LESSTHAN && - IsLessThan(right_constant.comparison_type))) { - // filters (j > i AND i [>, >=] 10) OR j < i AND i [<, <=] 10 - // create filter j [>, <] 10 and add the filter j [>, <] i into the remaining filters - // the comparisons j > i and j < i are more restrictive - info.comparison_type = comparison.type; - if (!is_inserted) { - // Add the filter j [>, <] i - auto filter = make_unique(comparison.type, comparison.left->Copy(), - comparison.right->Copy()); - remaining_filters.push_back(move(filter)); - is_inserted = true; - } - } else { - // we cannot add a new filter - continue; - } - // Add the new filer into the left set - if (AddConstantComparison(left_constants, info) == FilterResult::UNSATISFIABLE) { - return FilterResult::UNSATISFIABLE; - } - is_successful = true; - } - if (is_successful) { - // now check for remaining trasitive filters from the left column - auto transitive_filter = FindTransitiveFilter(comparison.left.get()); - if (transitive_filter != nullptr) { - // 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)); - } - } - return FilterResult::SUCCESS; - } - - return FilterResult::UNSUPPORTED; -} - -/* - * Find a transitive filter already inserted into the remaining filters - * Check for a match between the right column of bound comparisons and the expression, - * then removes the bound comparison from the remaining filters and returns it - */ -unique_ptr FilterCombiner::FindTransitiveFilter(Expression *expr) { - // We only check for bound column ref - if (expr->type == ExpressionType::BOUND_COLUMN_REF) { - for (idx_t i = 0; i < remaining_filters.size(); i++) { - 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]); - remaining_filters.erase(remaining_filters.begin() + i); - return filter; + constexpr idx_t TOTAL_BOX_WIDTH = 39; + ss << "┌─────────────────────────────────────┐\n"; + ss << "│┌───────────────────────────────────┐│\n"; + string total_time = "Total Time: " + RenderTiming(main_query.Elapsed()); + ss << "││" + DrawPadded(total_time, TOTAL_BOX_WIDTH - 4) + "││\n"; + ss << "│└───────────────────────────────────┘│\n"; + ss << "└─────────────────────────────────────┘\n"; + // print phase timings + if (print_optimizer_output) { + bool has_previous_phase = false; + for (const auto &entry : GetOrderedPhaseTimings()) { + if (!StringUtil::Contains(entry.first, " > ")) { + // primary phase! + if (has_previous_phase) { + ss << "│└───────────────────────────────────┘│\n"; + ss << "└─────────────────────────────────────┘\n"; } + ss << "┌─────────────────────────────────────┐\n"; + ss << "│" + + DrawPadded(RenderTitleCase(entry.first) + ": " + RenderTiming(entry.second), + TOTAL_BOX_WIDTH - 2) + + "│\n"; + ss << "│┌───────────────────────────────────┐│\n"; + has_previous_phase = true; + } else { + string entry_name = StringUtil::Split(entry.first, " > ")[1]; + ss << "││" + + DrawPadded(RenderTitleCase(entry_name) + ": " + RenderTiming(entry.second), + TOTAL_BOX_WIDTH - 4) + + "││\n"; } } + if (has_previous_phase) { + ss << "│└───────────────────────────────────┘│\n"; + ss << "└─────────────────────────────────────┘\n"; + } } - return nullptr; -} - -ValueComparisonResult InvertValueComparisonResult(ValueComparisonResult result) { - if (result == ValueComparisonResult::PRUNE_RIGHT) { - return ValueComparisonResult::PRUNE_LEFT; - } - if (result == ValueComparisonResult::PRUNE_LEFT) { - return ValueComparisonResult::PRUNE_RIGHT; + // render the main operator tree + if (root) { + Render(*root, ss); } - return result; } -ValueComparisonResult CompareValueInformation(ExpressionValueInformation &left, ExpressionValueInformation &right) { - if (left.comparison_type == ExpressionType::COMPARE_EQUAL) { - // left is COMPARE_EQUAL, we can either - // (1) prune the right side or - // (2) return UNSATISFIABLE - bool prune_right_side = false; - switch (right.comparison_type) { - case ExpressionType::COMPARE_LESSTHAN: - prune_right_side = left.constant < right.constant; - break; - case ExpressionType::COMPARE_LESSTHANOREQUALTO: - prune_right_side = left.constant <= right.constant; - break; - case ExpressionType::COMPARE_GREATERTHAN: - prune_right_side = left.constant > right.constant; - break; - case ExpressionType::COMPARE_GREATERTHANOREQUALTO: - prune_right_side = left.constant >= right.constant; +static string JSONSanitize(const string &text) { + string result; + result.reserve(text.size()); + for (idx_t i = 0; i < text.size(); i++) { + switch (text[i]) { + case '\b': + result += "\\b"; break; - case ExpressionType::COMPARE_NOTEQUAL: - prune_right_side = left.constant != right.constant; + case '\f': + result += "\\f"; break; - default: - D_ASSERT(right.comparison_type == ExpressionType::COMPARE_EQUAL); - prune_right_side = left.constant == right.constant; + case '\n': + result += "\\n"; break; - } - if (prune_right_side) { - return ValueComparisonResult::PRUNE_RIGHT; - } else { - return ValueComparisonResult::UNSATISFIABLE_CONDITION; - } - } else if (right.comparison_type == ExpressionType::COMPARE_EQUAL) { - // right is COMPARE_EQUAL - return InvertValueComparisonResult(CompareValueInformation(right, left)); - } else if (left.comparison_type == ExpressionType::COMPARE_NOTEQUAL) { - // left is COMPARE_NOTEQUAL, we can either - // (1) prune the left side or - // (2) not prune anything - bool prune_left_side = false; - switch (right.comparison_type) { - case ExpressionType::COMPARE_LESSTHAN: - prune_left_side = left.constant >= right.constant; + case '\r': + result += "\\r"; break; - case ExpressionType::COMPARE_LESSTHANOREQUALTO: - prune_left_side = left.constant > right.constant; + case '\t': + result += "\\t"; break; - case ExpressionType::COMPARE_GREATERTHAN: - prune_left_side = left.constant <= right.constant; + case '"': + result += "\\\""; break; - case ExpressionType::COMPARE_GREATERTHANOREQUALTO: - prune_left_side = left.constant < right.constant; + case '\\': + result += "\\\\"; break; default: - D_ASSERT(right.comparison_type == ExpressionType::COMPARE_NOTEQUAL); - prune_left_side = left.constant == right.constant; + result += text[i]; break; } - if (prune_left_side) { - return ValueComparisonResult::PRUNE_LEFT; - } else { - return ValueComparisonResult::PRUNE_NOTHING; + } + return result; +} + +// Print a row +static void PrintRow(std::ostream &ss, const string &annotation, int id, const string &name, double time, + int sample_counter, int tuple_counter, const string &extra_info, int depth) { + ss << string(depth * 3, ' ') << " {\n"; + ss << string(depth * 3, ' ') << " \"annotation\": \"" + JSONSanitize(annotation) + "\",\n"; + ss << string(depth * 3, ' ') << " \"id\": " + to_string(id) + ",\n"; + ss << string(depth * 3, ' ') << " \"name\": \"" + JSONSanitize(name) + "\",\n"; +#if defined(RDTSC) + ss << string(depth * 3, ' ') << " \"timing\": \"NULL\" ,\n"; + ss << string(depth * 3, ' ') << " \"cycles_per_tuple\": " + StringUtil::Format("%.4f", time) + ",\n"; +#else + ss << string(depth * 3, ' ') << " \"timing\":" + to_string(time) + ",\n"; + ss << string(depth * 3, ' ') << " \"cycles_per_tuple\": \"NULL\" ,\n"; +#endif + ss << string(depth * 3, ' ') << " \"sample_size\": " << to_string(sample_counter) + ",\n"; + ss << string(depth * 3, ' ') << " \"input_size\": " << to_string(tuple_counter) + ",\n"; + ss << string(depth * 3, ' ') << " \"extra_info\": \"" << JSONSanitize(extra_info) + "\"\n"; + ss << string(depth * 3, ' ') << " },\n"; +} + +static void ExtractFunctions(std::ostream &ss, ExpressionInfo &info, int &fun_id, int depth) { + if (info.hasfunction) { + D_ASSERT(info.sample_tuples_count != 0); + PrintRow(ss, "Function", fun_id++, info.function_name, + int(info.function_time) / double(info.sample_tuples_count), info.sample_tuples_count, + info.tuples_count, "", depth); + } + if (info.children.empty()) { + return; + } + // extract the children of this node + for (auto &child : info.children) { + ExtractFunctions(ss, *child, fun_id, depth); + } +} + +static void ToJSONRecursive(QueryProfiler::TreeNode &node, std::ostream &ss, int depth = 1) { + ss << string(depth * 3, ' ') << " {\n"; + ss << string(depth * 3, ' ') << " \"name\": \"" + JSONSanitize(node.name) + "\",\n"; + ss << string(depth * 3, ' ') << " \"timing\":" + to_string(node.info.time) + ",\n"; + ss << string(depth * 3, ' ') << " \"cardinality\":" + to_string(node.info.elements) + ",\n"; + ss << string(depth * 3, ' ') << " \"extra_info\": \"" + JSONSanitize(node.extra_info) + "\",\n"; + ss << string(depth * 3, ' ') << " \"timings\": ["; + int32_t function_counter = 1; + int32_t expression_counter = 1; + ss << "\n "; + for (auto &expr_executor : node.info.executors_info) { + // For each Expression tree + if (!expr_executor) { + continue; } - } else if (right.comparison_type == ExpressionType::COMPARE_NOTEQUAL) { - return InvertValueComparisonResult(CompareValueInformation(right, left)); - } else if (IsGreaterThan(left.comparison_type) && IsGreaterThan(right.comparison_type)) { - // both comparisons are [>], we can either - // (1) prune the left side or - // (2) prune the right side - if (left.constant > right.constant) { - // left constant is more selective, prune right - return ValueComparisonResult::PRUNE_RIGHT; - } else if (left.constant < right.constant) { - // right constant is more selective, prune left - return ValueComparisonResult::PRUNE_LEFT; - } else { - // constants are equivalent - // however we can still have the scenario where one is [>=] and the other is [>] - // we want to prune the [>=] because [>] is more selective - // if left is [>=] we prune the left, else we prune the right - if (left.comparison_type == ExpressionType::COMPARE_GREATERTHANOREQUALTO) { - return ValueComparisonResult::PRUNE_LEFT; - } else { - return ValueComparisonResult::PRUNE_RIGHT; - } + for (auto &expr_timer : expr_executor->roots) { + D_ASSERT(expr_timer->sample_tuples_count != 0); + PrintRow(ss, "ExpressionRoot", expression_counter++, expr_timer->name, + int(expr_timer->time) / double(expr_timer->sample_tuples_count), expr_timer->sample_tuples_count, + expr_timer->tuples_count, expr_timer->extra_info, depth + 1); + // Extract all functions inside the tree + ExtractFunctions(ss, *expr_timer->root, function_counter, depth + 1); } - } else if (IsLessThan(left.comparison_type) && IsLessThan(right.comparison_type)) { - // both comparisons are [<], we can either - // (1) prune the left side or - // (2) prune the right side - if (left.constant < right.constant) { - // left constant is more selective, prune right - return ValueComparisonResult::PRUNE_RIGHT; - } else if (left.constant > right.constant) { - // right constant is more selective, prune left - return ValueComparisonResult::PRUNE_LEFT; - } else { - // constants are equivalent - // however we can still have the scenario where one is [<=] and the other is [<] - // we want to prune the [<=] because [<] is more selective - // if left is [<=] we prune the left, else we prune the right - if (left.comparison_type == ExpressionType::COMPARE_LESSTHANOREQUALTO) { - return ValueComparisonResult::PRUNE_LEFT; - } else { - return ValueComparisonResult::PRUNE_RIGHT; + } + ss.seekp(-2, ss.cur); + ss << "\n"; + ss << string(depth * 3, ' ') << " ],\n"; + ss << string(depth * 3, ' ') << " \"children\": [\n"; + if (node.children.empty()) { + ss << string(depth * 3, ' ') << " ]\n"; + } else { + for (idx_t i = 0; i < node.children.size(); i++) { + if (i > 0) { + ss << ",\n"; } + ToJSONRecursive(*node.children[i], ss, depth + 1); } - } else if (IsLessThan(left.comparison_type)) { - D_ASSERT(IsGreaterThan(right.comparison_type)); - // left is [<] and right is [>], in this case we can either - // (1) prune nothing or - // (2) return UNSATISFIABLE - // the SMALLER THAN constant has to be greater than the BIGGER THAN constant - if (left.constant >= right.constant) { - return ValueComparisonResult::PRUNE_NOTHING; - } else { - return ValueComparisonResult::UNSATISFIABLE_CONDITION; + ss << string(depth * 3, ' ') << " ]\n"; + } + ss << string(depth * 3, ' ') << " }\n"; +} + +string QueryProfiler::ToJSON() const { + if (!IsEnabled()) { + return "{ \"result\": \"disabled\" }\n"; + } + if (query.empty()) { + return "{ \"result\": \"empty\" }\n"; + } + if (!root) { + return "{ \"result\": \"error\" }\n"; + } + std::stringstream ss; + ss << "{\n"; + ss << " \"name\": \"Query\", \n"; + ss << " \"result\": " + to_string(main_query.Elapsed()) + ",\n"; + ss << " \"timing\": " + to_string(main_query.Elapsed()) + ",\n"; + ss << " \"cardinality\": " + to_string(root->info.elements) + ",\n"; + // JSON cannot have literal control characters in string literals + string extra_info = JSONSanitize(query); + ss << " \"extra-info\": \"" + extra_info + "\", \n"; + // print the phase timings + ss << " \"timings\": [\n"; + const auto &ordered_phase_timings = GetOrderedPhaseTimings(); + for (idx_t i = 0; i < ordered_phase_timings.size(); i++) { + if (i > 0) { + ss << ",\n"; } - } else { - // left is [>] and right is [<] or [!=] - D_ASSERT(IsLessThan(right.comparison_type) && IsGreaterThan(left.comparison_type)); - return InvertValueComparisonResult(CompareValueInformation(right, left)); + ss << " {\n"; + ss << " \"annotation\": \"" + ordered_phase_timings[i].first + "\", \n"; + ss << " \"timing\": " + to_string(ordered_phase_timings[i].second) + "\n"; + ss << " }"; } + ss << "\n"; + ss << " ],\n"; + // recursively print the physical operator tree + ss << " \"children\": [\n"; + ToJSONRecursive(*root, ss); + ss << " ]\n"; + ss << "}"; + return ss.str(); } -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/optimizer/filter_pullup.hpp -// -// -//===----------------------------------------------------------------------===// +void QueryProfiler::WriteToFile(const char *path, string &info) const { + ofstream out(path); + out << info; + out.close(); + // throw an IO exception if it fails to write the file + if (out.fail()) { + throw IOException(strerror(errno)); + } +} +unique_ptr QueryProfiler::CreateTree(PhysicalOperator *root, idx_t depth) { + if (OperatorRequiresProfiling(root->type)) { + this->query_requires_profiling = true; + } + auto node = make_unique(); + node->type = root->type; + node->name = root->GetName(); + node->extra_info = root->ParamsToString(); + node->depth = depth; + tree_map[root] = node.get(); + for (auto &child : root->children) { + auto child_node = CreateTree(child.get(), depth + 1); + node->children.push_back(move(child_node)); + } + switch (root->type) { + case PhysicalOperatorType::DELIM_JOIN: { + auto &delim_join = (PhysicalDelimJoin &)*root; + auto child_node = CreateTree((PhysicalOperator *)delim_join.join.get(), depth + 1); + node->children.push_back(move(child_node)); + child_node = CreateTree((PhysicalOperator *)delim_join.distinct.get(), depth + 1); + node->children.push_back(move(child_node)); + break; + } + case PhysicalOperatorType::EXECUTE: { + auto &execute = (PhysicalExecute &)*root; + auto child_node = CreateTree((PhysicalOperator *)execute.plan, depth + 1); + node->children.push_back(move(child_node)); + break; + } + default: + break; + } + return node; +} +void QueryProfiler::Render(const QueryProfiler::TreeNode &node, std::ostream &ss) const { + TreeRenderer renderer; + if (IsDetailedEnabled()) { + renderer.EnableDetailed(); + } else { + renderer.EnableStandard(); + } + renderer.Render(node, ss); +} +void QueryProfiler::Print() { + Printer::Print(ToString()); +} +vector QueryProfiler::GetOrderedPhaseTimings() const { + vector result; + // first sort the phases alphabetically + vector phases; + for (auto &entry : phase_timings) { + phases.push_back(entry.first); + } + std::sort(phases.begin(), phases.end()); + for (const auto &phase : phases) { + auto entry = phase_timings.find(phase); + D_ASSERT(entry != phase_timings.end()); + result.emplace_back(entry->first, entry->second); + } + return result; +} +void QueryProfiler::Propagate(QueryProfiler &qp) { +} +void ExpressionInfo::ExtractExpressionsRecursive(unique_ptr &state) { + if (state->child_states.empty()) { + return; + } + // extract the children of this node + for (auto &child : state->child_states) { + auto expr_info = make_unique(); + if (child->expr.expression_class == ExpressionClass::BOUND_FUNCTION) { + expr_info->hasfunction = true; + expr_info->function_name = ((BoundFunctionExpression &)child->expr).function.ToString(); + expr_info->function_time = child->profiler.time; + expr_info->sample_tuples_count = child->profiler.sample_tuples_count; + expr_info->tuples_count = child->profiler.tuples_count; + } + expr_info->ExtractExpressionsRecursive(child); + children.push_back(move(expr_info)); + } + return; +} +ExpressionExecutorInfo::ExpressionExecutorInfo(ExpressionExecutor &executor, const string &name, int id) : id(id) { + // Extract Expression Root Information from ExpressionExecutorStats + for (auto &state : executor.GetStates()) { + roots.push_back(make_unique(*state, name)); + } +} +ExpressionRootInfo::ExpressionRootInfo(ExpressionExecutorState &state, string name) + : current_count(state.profiler.current_count), sample_count(state.profiler.sample_count), + 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); + auto expression_info_p = make_unique(); + // Maybe root has a function + if (state.root_state->expr.expression_class == ExpressionClass::BOUND_FUNCTION) { + expression_info_p->hasfunction = true; + expression_info_p->function_name = ((BoundFunctionExpression &)state.root_state->expr).function.name; + expression_info_p->function_time = state.root_state->profiler.time; + expression_info_p->sample_tuples_count = state.root_state->profiler.sample_tuples_count; + expression_info_p->tuples_count = state.root_state->profiler.tuples_count; + } + expression_info_p->ExtractExpressionsRecursive(state.root_state); + root = move(expression_info_p); +} +} // namespace duckdb +#include -namespace duckdb { -class FilterPullup { -public: - explicit FilterPullup(bool pullup = false, bool add_column = false) - : can_pullup(pullup), can_add_column(add_column) { - } - //! Perform filter pullup - unique_ptr Rewrite(unique_ptr op); -private: - vector> filters_expr_pullup; +namespace duckdb { - // only pull up filters when there is a fork - bool can_pullup = false; +BaseQueryResult::BaseQueryResult(QueryResultType type, StatementType statement_type) + : type(type), statement_type(statement_type), success(true) { +} - // identifiy case the branch is a set operation (INTERSECT or EXCEPT) - bool can_add_column = false; +BaseQueryResult::BaseQueryResult(QueryResultType type, StatementType statement_type, vector types_p, + vector names_p) + : type(type), statement_type(statement_type), types(move(types_p)), names(move(names_p)), success(true) { + D_ASSERT(types.size() == names.size()); +} -private: - // Generate logical filters pulled up - unique_ptr GeneratePullupFilter(unique_ptr child, - vector> &expressions); +BaseQueryResult::BaseQueryResult(QueryResultType type, string error) : type(type), success(false), error(move(error)) { +} - //! Pull up a LogicalFilter op - unique_ptr PullupFilter(unique_ptr op); +BaseQueryResult::~BaseQueryResult() { +} - //! Pull up filter in a LogicalProjection op - unique_ptr PullupProjection(unique_ptr op); +bool BaseQueryResult::HasError() { + return !success; +} +const string &BaseQueryResult::GetError() { + return error; +} +idx_t BaseQueryResult::ColumnCount() { + return types.size(); +} - //! Pull up filter in a LogicalCrossProduct op - unique_ptr PullupCrossProduct(unique_ptr op); +QueryResult::QueryResult(QueryResultType type, StatementType statement_type) : BaseQueryResult(type, statement_type) { +} - unique_ptr PullupJoin(unique_ptr op); +QueryResult::QueryResult(QueryResultType type, StatementType statement_type, vector types_p, + vector names_p) + : BaseQueryResult(type, statement_type, move(types_p), move(names_p)) { +} - // PPullup filter in a left join - unique_ptr PullupFromLeft(unique_ptr op); +QueryResult::QueryResult(QueryResultType type, string error) : BaseQueryResult(type, move(error)) { +} - // Pullup filter in a inner join - unique_ptr PullupInnerJoin(unique_ptr op); +QueryResult::~QueryResult() { +} - // Pullup filter in LogicalIntersect or LogicalExcept op - unique_ptr PullupSetOperation(unique_ptr op); +unique_ptr QueryResult::Fetch() { + auto chunk = FetchRaw(); + if (!chunk) { + return nullptr; + } + chunk->Normalify(); + return chunk; +} - unique_ptr PullupBothSide(unique_ptr op); +bool QueryResult::Equals(QueryResult &other) { // LCOV_EXCL_START + // first compare the success state of the results + if (success != other.success) { + return false; + } + if (!success) { + return error == other.error; + } + // compare names + if (names != other.names) { + return false; + } + // compare types + if (types != other.types) { + return false; + } + // now compare the actual values + // fetch chunks + while (true) { + auto lchunk = Fetch(); + auto rchunk = other.Fetch(); + if (!lchunk && !rchunk) { + return true; + } + if (!lchunk || !rchunk) { + return false; + } + if (lchunk->size() == 0 && rchunk->size() == 0) { + return true; + } + if (lchunk->size() != rchunk->size()) { + return false; + } + D_ASSERT(lchunk->ColumnCount() == rchunk->ColumnCount()); + for (idx_t col = 0; col < rchunk->ColumnCount(); col++) { + for (idx_t row = 0; row < rchunk->size(); row++) { + auto lvalue = lchunk->GetValue(col, row); + auto rvalue = rchunk->GetValue(col, row); + if (lvalue != rvalue) { + return false; + } + } + } + } +} // LCOV_EXCL_STOP - // Finish pull up at this operator - unique_ptr FinishPullup(unique_ptr op); +void QueryResult::Print() { + Printer::Print(ToString()); +} - // special treatment for SetOperations and projections - void ProjectSetOperation(LogicalProjection &proj); +string QueryResult::HeaderToString() { + string result; + for (auto &name : names) { + result += name + "\t"; + } + result += "\n"; + for (auto &type : types) { + result += type.ToString() + "\t"; + } + result += "\n"; + return result; +} -}; // end FilterPullup +struct DuckDBArrowSchemaHolder { + // unused in children + vector children; + // unused in children + vector children_ptrs; + //! used for nested structures + std::list> nested_children; + std::list> nested_children_ptr; + //! This holds strings created to represent decimal types + vector> owned_type_names; +}; -} // namespace duckdb +static void ReleaseDuckDBArrowSchema(ArrowSchema *schema) { + if (!schema || !schema->release) { + return; + } + schema->release = nullptr; + auto holder = static_cast(schema->private_data); + delete holder; +} +void InitializeChild(ArrowSchema &child, const string &name = "") { + //! Child is cleaned up by parent + child.private_data = nullptr; + child.release = ReleaseDuckDBArrowSchema; + //! Store the child schema + child.flags = ARROW_FLAG_NULLABLE; + child.name = name.c_str(); + child.n_children = 0; + child.children = nullptr; + child.metadata = nullptr; + child.dictionary = nullptr; +} +void SetArrowFormat(DuckDBArrowSchemaHolder &root_holder, ArrowSchema &child, const LogicalType &type); -namespace duckdb { +void SetArrowMapFormat(DuckDBArrowSchemaHolder &root_holder, ArrowSchema &child, const LogicalType &type) { + child.format = "+m"; + //! Map has one child which is a struct + child.n_children = 1; + root_holder.nested_children.emplace_back(); + root_holder.nested_children.back().resize(1); + root_holder.nested_children_ptr.emplace_back(); + root_holder.nested_children_ptr.back().push_back(&root_holder.nested_children.back()[0]); + 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); +} -unique_ptr FilterPullup::Rewrite(unique_ptr op) { - switch (op->type) { - case LogicalOperatorType::LOGICAL_FILTER: - return PullupFilter(move(op)); - case LogicalOperatorType::LOGICAL_PROJECTION: - return PullupProjection(move(op)); - case LogicalOperatorType::LOGICAL_CROSS_PRODUCT: - return PullupCrossProduct(move(op)); - case LogicalOperatorType::LOGICAL_COMPARISON_JOIN: - case LogicalOperatorType::LOGICAL_ANY_JOIN: - case LogicalOperatorType::LOGICAL_DELIM_JOIN: - return PullupJoin(move(op)); - case LogicalOperatorType::LOGICAL_INTERSECT: - case LogicalOperatorType::LOGICAL_EXCEPT: - return PullupSetOperation(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])); - return op; +void SetArrowFormat(DuckDBArrowSchemaHolder &root_holder, ArrowSchema &child, const LogicalType &type) { + switch (type.id()) { + case LogicalTypeId::BOOLEAN: + child.format = "b"; + break; + case LogicalTypeId::TINYINT: + child.format = "c"; + break; + case LogicalTypeId::SMALLINT: + child.format = "s"; + break; + case LogicalTypeId::INTEGER: + child.format = "i"; + break; + case LogicalTypeId::BIGINT: + child.format = "l"; + break; + case LogicalTypeId::UTINYINT: + child.format = "C"; + break; + case LogicalTypeId::USMALLINT: + child.format = "S"; + break; + case LogicalTypeId::UINTEGER: + child.format = "I"; + break; + case LogicalTypeId::UBIGINT: + child.format = "L"; + break; + case LogicalTypeId::FLOAT: + child.format = "f"; + break; + case LogicalTypeId::HUGEINT: + child.format = "d:38,0"; + break; + case LogicalTypeId::DOUBLE: + child.format = "g"; + break; + case LogicalTypeId::UUID: + case LogicalTypeId::VARCHAR: + child.format = "u"; + break; + case LogicalTypeId::DATE: + child.format = "tdD"; + break; + case LogicalTypeId::TIME: + case LogicalTypeId::TIME_TZ: + child.format = "ttu"; + break; + case LogicalTypeId::TIMESTAMP: + case LogicalTypeId::TIMESTAMP_TZ: + child.format = "tsu:"; + break; + case LogicalTypeId::TIMESTAMP_SEC: + child.format = "tss:"; + break; + case LogicalTypeId::TIMESTAMP_NS: + child.format = "tsn:"; + break; + case LogicalTypeId::TIMESTAMP_MS: + child.format = "tsm:"; + break; + case LogicalTypeId::INTERVAL: + child.format = "tDm"; + break; + case LogicalTypeId::DECIMAL: { + uint8_t width, scale; + type.GetDecimalProperties(width, scale); + string format = "d:" + to_string(width) + "," + to_string(scale); + unique_ptr format_ptr = unique_ptr(new char[format.size() + 1]); + for (size_t i = 0; i < format.size(); i++) { + format_ptr[i] = format[i]; + } + format_ptr[format.size()] = '\0'; + root_holder.owned_type_names.push_back(move(format_ptr)); + child.format = root_holder.owned_type_names.back().get(); + break; } - default: - return FinishPullup(move(op)); + case LogicalTypeId::SQLNULL: { + child.format = "n"; + break; } -} + case LogicalTypeId::BLOB: { + child.format = "z"; + break; + } + case LogicalTypeId::LIST: { + child.format = "+l"; + child.n_children = 1; + root_holder.nested_children.emplace_back(); + root_holder.nested_children.back().resize(1); + root_holder.nested_children_ptr.emplace_back(); + root_holder.nested_children_ptr.back().push_back(&root_holder.nested_children.back()[0]); + InitializeChild(root_holder.nested_children.back()[0]); + child.children = &root_holder.nested_children_ptr.back()[0]; + child.children[0]->name = "l"; + SetArrowFormat(root_holder, **child.children, ListType::GetChildType(type)); + break; + } + case LogicalTypeId::STRUCT: { + child.format = "+s"; + auto &child_types = StructType::GetChildTypes(type); + child.n_children = child_types.size(); + root_holder.nested_children.emplace_back(); + root_holder.nested_children.back().resize(child_types.size()); + root_holder.nested_children_ptr.emplace_back(); + root_holder.nested_children_ptr.back().resize(child_types.size()); + for (idx_t type_idx = 0; type_idx < child_types.size(); type_idx++) { + root_holder.nested_children_ptr.back()[type_idx] = &root_holder.nested_children.back()[type_idx]; + } + child.children = &root_holder.nested_children_ptr.back()[0]; + for (size_t type_idx = 0; type_idx < child_types.size(); type_idx++) { -unique_ptr FilterPullup::PullupJoin(unique_ptr op) { - D_ASSERT(op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN || - op->type == LogicalOperatorType::LOGICAL_ANY_JOIN || op->type == LogicalOperatorType::LOGICAL_DELIM_JOIN); - auto &join = (LogicalJoin &)*op; + InitializeChild(*child.children[type_idx]); - switch (join.join_type) { - case JoinType::INNER: - return PullupInnerJoin(move(op)); - case JoinType::LEFT: - case JoinType::ANTI: - case JoinType::SEMI: { - can_add_column = true; - return PullupFromLeft(move(op)); + auto &struct_col_name = child_types[type_idx].first; + unique_ptr name_ptr = unique_ptr(new char[struct_col_name.size() + 1]); + for (size_t i = 0; i < struct_col_name.size(); i++) { + name_ptr[i] = struct_col_name[i]; + } + name_ptr[struct_col_name.size()] = '\0'; + root_holder.owned_type_names.push_back(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); + } + break; + } + case LogicalTypeId::MAP: { + SetArrowMapFormat(root_holder, child, type); + break; + } + case LogicalTypeId::ENUM: { + switch (EnumType::GetPhysicalType(EnumType::GetSize(type))) { + case PhysicalType::UINT8: + child.format = "C"; + break; + case PhysicalType::UINT16: + child.format = "S"; + break; + case PhysicalType::UINT32: + child.format = "I"; + break; + default: + throw InternalException("Unsupported Enum Internal Type"); + } + root_holder.nested_children.emplace_back(); + root_holder.nested_children.back().resize(1); + root_holder.nested_children_ptr.emplace_back(); + root_holder.nested_children_ptr.back().push_back(&root_holder.nested_children.back()[0]); + InitializeChild(root_holder.nested_children.back()[0]); + child.dictionary = root_holder.nested_children_ptr.back()[0]; + child.dictionary->format = "u"; + break; } default: - // unsupported join type: call children pull up - return FinishPullup(move(op)); + throw InternalException("Unsupported Arrow type " + type.ToString()); } } -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)); -} +void QueryResult::ToArrowSchema(ArrowSchema *out_schema) { + D_ASSERT(out_schema); -unique_ptr FilterPullup::PullupCrossProduct(unique_ptr op) { - D_ASSERT(op->type == LogicalOperatorType::LOGICAL_CROSS_PRODUCT); - return PullupBothSide(move(op)); -} + // Allocate as unique_ptr first to cleanup properly on error + auto root_holder = make_unique(); -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])); + // Allocate the children + root_holder->children.resize(ColumnCount()); + root_holder->children_ptrs.resize(ColumnCount(), nullptr); + for (size_t i = 0; i < ColumnCount(); ++i) { + root_holder->children_ptrs[i] = &root_holder->children[i]; } - expressions.clear(); - filter->children.push_back(move(child)); - return move(filter); -} + out_schema->children = root_holder->children_ptrs.data(); + out_schema->n_children = ColumnCount(); -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])); - } - // now pull up any existing filters - if (filters_expr_pullup.empty()) { - // no filters to pull up - return op; + // Store the schema + out_schema->format = "+s"; // struct apparently + out_schema->flags = 0; + out_schema->metadata = nullptr; + out_schema->name = "duckdb_query_result"; + out_schema->dictionary = nullptr; + + // Configure all child schemas + for (idx_t col_idx = 0; col_idx < ColumnCount(); col_idx++) { + + auto &child = root_holder->children[col_idx]; + InitializeChild(child, names[col_idx]); + SetArrowFormat(*root_holder, child, types[col_idx]); } - return GeneratePullupFilter(move(op), filters_expr_pullup); + + // Release ownership to caller + out_schema->private_data = root_holder.release(); + out_schema->release = ReleaseDuckDBArrowSchema; } } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/optimizer/filter_pushdown.hpp +// duckdb/main/relation/aggregate_relation.hpp // // //===----------------------------------------------------------------------===// @@ -109127,206 +114161,150 @@ unique_ptr FilterPullup::FinishPullup(unique_ptr child, vector> expressions); + AggregateRelation(shared_ptr child, vector> expressions, + vector> groups); + + vector> expressions; + vector> groups; + vector columns; + shared_ptr child; -class FilterPushdown { public: - explicit FilterPushdown(Optimizer &optimizer) : optimizer(optimizer) { - } - //! Perform filter pushdown - unique_ptr Rewrite(unique_ptr op); + unique_ptr GetQueryNode() override; - struct Filter { - unordered_set bindings; - unique_ptr filter; + const vector &Columns() override; + string ToString(idx_t depth) override; + string GetAlias() override; +}; - Filter() { - } - explicit Filter(unique_ptr filter) : filter(move(filter)) { - } +} // namespace duckdb - void ExtractBindings(); - }; -private: - vector> filters; - Optimizer &optimizer; - //! Push down a LogicalAggregate op - unique_ptr PushdownAggregate(unique_ptr op); - //! Push down a LogicalFilter op - unique_ptr PushdownFilter(unique_ptr op); - //! Push down a LogicalCrossProduct op - unique_ptr PushdownCrossProduct(unique_ptr op); - //! Push down a join operator - unique_ptr PushdownJoin(unique_ptr op); - //! Push down a LogicalProjection op - unique_ptr PushdownProjection(unique_ptr op); - //! Push down a LogicalSetOperation op - unique_ptr PushdownSetOperation(unique_ptr op); - //! Push down a LogicalGet op - unique_ptr PushdownGet(unique_ptr op); - // Pushdown an inner join - unique_ptr PushdownInnerJoin(unique_ptr op, unordered_set &left_bindings, - unordered_set &right_bindings); - // Pushdown a left join - unique_ptr PushdownLeftJoin(unique_ptr op, unordered_set &left_bindings, - unordered_set &right_bindings); - // Pushdown a mark join - unique_ptr PushdownMarkJoin(unique_ptr op, unordered_set &left_bindings, - unordered_set &right_bindings); - // Pushdown a single join - unique_ptr PushdownSingleJoin(unique_ptr op, unordered_set &left_bindings, - unordered_set &right_bindings); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/tableref/subqueryref.hpp +// +// +//===----------------------------------------------------------------------===// - // Finish pushing down at this operator, creating a LogicalFilter to store any of the stored filters and recursively - // pushing down into its children (if any) - unique_ptr FinishPushdown(unique_ptr op); - //! Adds a filter to the set of filters. Returns FilterResult::UNSATISFIABLE if the subtree should be stripped, or - //! FilterResult::SUCCESS otherwise - FilterResult AddFilter(unique_ptr expr); - //! Generate filters from the current set of filters stored in the FilterCombiner - void GenerateFilters(); - //! if there are filters in this FilterPushdown node, push them into the combiner - void PushFilters(); - FilterCombiner combiner; -}; -} // namespace duckdb +namespace duckdb { +//! Represents a subquery +class SubqueryRef : public TableRef { +public: + explicit SubqueryRef(unique_ptr subquery, string alias = string()); + + //! The subquery + unique_ptr subquery; + //! Aliases for the column names + vector column_name_alias; + +public: + bool Equals(const TableRef *other_p) const override; + + unique_ptr Copy() override; + //! Serializes a blob into a SubqueryRef + void Serialize(FieldWriter &serializer) const override; + //! Deserializes a blob back into a SubqueryRef + static unique_ptr Deserialize(FieldReader &source); +}; +} // namespace duckdb namespace duckdb { -using Filter = FilterPushdown::Filter; +AggregateRelation::AggregateRelation(shared_ptr child_p, + vector> parsed_expressions) + : Relation(child_p->context, RelationType::AGGREGATE_RELATION), expressions(move(parsed_expressions)), + child(move(child_p)) { + // bind the expressions + context.TryBindRelation(*this, this->columns); +} -unique_ptr FilterPushdown::Rewrite(unique_ptr op) { - D_ASSERT(!combiner.HasFilters()); - switch (op->type) { - case LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY: - return PushdownAggregate(move(op)); - case LogicalOperatorType::LOGICAL_FILTER: - return PushdownFilter(move(op)); - case LogicalOperatorType::LOGICAL_CROSS_PRODUCT: - return PushdownCrossProduct(move(op)); - case LogicalOperatorType::LOGICAL_COMPARISON_JOIN: - case LogicalOperatorType::LOGICAL_ANY_JOIN: - case LogicalOperatorType::LOGICAL_DELIM_JOIN: - return PushdownJoin(move(op)); - case LogicalOperatorType::LOGICAL_PROJECTION: - return PushdownProjection(move(op)); - case LogicalOperatorType::LOGICAL_INTERSECT: - case LogicalOperatorType::LOGICAL_EXCEPT: - case LogicalOperatorType::LOGICAL_UNION: - return PushdownSetOperation(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])); - return op; - } - case LogicalOperatorType::LOGICAL_GET: - return PushdownGet(move(op)); - default: - return FinishPushdown(move(op)); - } +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)) { + // bind the expressions + context.TryBindRelation(*this, this->columns); } -unique_ptr FilterPushdown::PushdownJoin(unique_ptr op) { - D_ASSERT(op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN || - op->type == LogicalOperatorType::LOGICAL_ANY_JOIN || op->type == LogicalOperatorType::LOGICAL_DELIM_JOIN); - auto &join = (LogicalJoin &)*op; - unordered_set left_bindings, right_bindings; - LogicalJoin::GetTableReferences(*op->children[0], left_bindings); - LogicalJoin::GetTableReferences(*op->children[1], right_bindings); - - switch (join.join_type) { - case JoinType::INNER: - return PushdownInnerJoin(move(op), left_bindings, right_bindings); - case JoinType::LEFT: - return PushdownLeftJoin(move(op), left_bindings, right_bindings); - case JoinType::MARK: - return PushdownMarkJoin(move(op), left_bindings, right_bindings); - case JoinType::SINGLE: - return PushdownSingleJoin(move(op), left_bindings, right_bindings); - default: - // unsupported join type: stop pushing down - return FinishPushdown(move(op)); +unique_ptr AggregateRelation::GetQueryNode() { + auto child_ptr = child.get(); + while (child_ptr->InheritsColumnBindings()) { + child_ptr = child_ptr->ChildRelation(); } -} -void FilterPushdown::PushFilters() { - for (auto &f : filters) { - auto result = combiner.AddFilter(move(f->filter)); - D_ASSERT(result == FilterResult::SUCCESS); - (void)result; + unique_ptr result; + if (child_ptr->type == RelationType::JOIN_RELATION) { + // child node is a join: push projection into the child query node + result = child->GetQueryNode(); + } else { + // 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); } - filters.clear(); -} - -FilterResult FilterPushdown::AddFilter(unique_ptr expr) { - PushFilters(); - // split up the filters by AND predicate - vector> expressions; - expressions.push_back(move(expr)); - LogicalFilter::SplitPredicates(expressions); - // push the filters into the combiner - for (auto &child_expr : expressions) { - if (combiner.AddFilter(move(child_expr)) == FilterResult::UNSATISFIABLE) { - return FilterResult::UNSATISFIABLE; + D_ASSERT(result->type == QueryNodeType::SELECT_NODE); + auto &select_node = (SelectNode &)*result; + if (!groups.empty()) { + // explicit groups provided: use standard handling + select_node.aggregate_handling = AggregateHandling::STANDARD_HANDLING; + select_node.groups.group_expressions.clear(); + GroupingSet grouping_set; + for (idx_t i = 0; i < groups.size(); i++) { + select_node.groups.group_expressions.push_back(groups[i]->Copy()); + grouping_set.insert(i); } + select_node.groups.grouping_sets.push_back(move(grouping_set)); + } else { + // no groups provided: automatically figure out groups (if any) + select_node.aggregate_handling = AggregateHandling::FORCE_AGGREGATES; } - return FilterResult::SUCCESS; + select_node.select_list.clear(); + for (auto &expr : expressions) { + select_node.select_list.push_back(expr->Copy()); + } + return result; } -void FilterPushdown::GenerateFilters() { - if (!filters.empty()) { - D_ASSERT(!combiner.HasFilters()); - return; - } - combiner.GenerateFilters([&](unique_ptr filter) { - auto f = make_unique(); - f->filter = move(filter); - f->ExtractBindings(); - filters.push_back(move(f)); - }); +string AggregateRelation::GetAlias() { + return child->GetAlias(); } -unique_ptr FilterPushdown::FinishPushdown(unique_ptr op) { - // unhandled type, first perform filter pushdown in its children - for (auto &child : op->children) { - FilterPushdown pushdown(optimizer); - child = pushdown.Rewrite(move(child)); - } - // now push any existing filters - if (filters.empty()) { - // no filters to push - return op; - } - auto filter = make_unique(); - for (auto &f : filters) { - filter->expressions.push_back(move(f->filter)); - } - filter->children.push_back(move(op)); - return move(filter); +const vector &AggregateRelation::Columns() { + return columns; } -void FilterPushdown::Filter::ExtractBindings() { - bindings.clear(); - LogicalJoin::GetExpressionBindings(*filter, bindings); +string AggregateRelation::ToString(idx_t depth) { + string str = RenderWhitespace(depth) + "Aggregate ["; + for (idx_t i = 0; i < expressions.size(); i++) { + if (i != 0) { + str += ", "; + } + str += expressions[i]->ToString(); + } + str += "]\n"; + return str + child->ToString(depth + 1); } } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/optimizer/in_clause_rewriter.hpp +// duckdb/main/relation/create_table_relation.hpp // // //===----------------------------------------------------------------------===// @@ -109336,140 +114314,98 @@ void FilterPushdown::Filter::ExtractBindings() { namespace duckdb { -class Optimizer; -class InClauseRewriter : public LogicalOperatorVisitor { +class CreateTableRelation : public Relation { public: - explicit InClauseRewriter(Optimizer &optimizer) : optimizer(optimizer) { - } + CreateTableRelation(shared_ptr child, string schema_name, string table_name); - Optimizer &optimizer; - unique_ptr root; + shared_ptr child; + string schema_name; + string table_name; + vector columns; public: - unique_ptr Rewrite(unique_ptr op); - - unique_ptr VisitReplace(BoundOperatorExpression &expr, unique_ptr *expr_ptr) override; + BoundStatement Bind(Binder &binder) override; + const vector &Columns() override; + string ToString(idx_t depth) override; + bool IsReadOnly() override { + return false; + } }; } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/statement/create_statement.hpp +// +// +//===----------------------------------------------------------------------===// + +namespace duckdb { +class CreateStatement : public SQLStatement { +public: + CreateStatement(); + unique_ptr info; +protected: + CreateStatement(const CreateStatement &other); -namespace duckdb { +public: + unique_ptr Copy() const override; +}; -unique_ptr InClauseRewriter::Rewrite(unique_ptr op) { - if (op->children.size() == 1) { - root = move(op->children[0]); - VisitOperatorExpressions(*op); - op->children[0] = move(root); - } +} // namespace duckdb - for (auto &child : op->children) { - child = Rewrite(move(child)); - } - return op; + + + + + +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)) { + context.TryBindRelation(*this, this->columns); } -unique_ptr InClauseRewriter::VisitReplace(BoundOperatorExpression &expr, unique_ptr *expr_ptr) { - if (expr.type != ExpressionType::COMPARE_IN && expr.type != ExpressionType::COMPARE_NOT_IN) { - return nullptr; - } - D_ASSERT(root); - auto in_type = expr.children[0]->return_type; - bool is_regular_in = expr.type == ExpressionType::COMPARE_IN; - bool all_scalar = true; - // IN clause with many children: try to generate a mark join that replaces this IN expression - // we can only do this if the expressions in the expression list are scalar - for (idx_t i = 1; i < expr.children.size(); i++) { - D_ASSERT(expr.children[i]->return_type == in_type); - if (!expr.children[i]->IsFoldable()) { - // non-scalar expression - all_scalar = false; - } - } - if (expr.children.size() == 2) { - // only one child - // IN: turn into X = 1 - // 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])); - } - if (expr.children.size() < 6 || !all_scalar) { - // low amount of children or not all scalar - // IN: turn into (X = 1 OR X = 2 OR X = 3...) - // NOT IN: turn into (X <> 1 AND X <> 2 AND X <> 3 ...) - auto conjunction = make_unique(is_regular_in ? ExpressionType::CONJUNCTION_OR - : ExpressionType::CONJUNCTION_AND); - 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]))); - } - return move(conjunction); - } - // IN clause with many constant children - // generate a mark join that replaces this IN expression - // first generate a ChunkCollection from the set of expressions - vector types = {in_type}; - auto collection = make_unique(); - DataChunk chunk; - chunk.Initialize(types); - for (idx_t i = 1; i < expr.children.size(); i++) { - // resolve this expression to a constant - auto value = ExpressionExecutor::EvaluateScalar(*expr.children[i]); - idx_t index = chunk.size(); - chunk.SetCardinality(chunk.size() + 1); - chunk.SetValue(0, index, value); - if (chunk.size() == STANDARD_VECTOR_SIZE || i + 1 == expr.children.size()) { - // chunk full: append to chunk collection - collection->Append(chunk); - chunk.Reset(); - } - } - // now generate a ChunkGet that scans this collection - auto chunk_index = optimizer.binder.GenerateTableIndex(); - auto chunk_scan = make_unique(chunk_index, types, move(collection)); +BoundStatement CreateTableRelation::Bind(Binder &binder) { + auto select = make_unique(); + select->node = child->GetQueryNode(); - // 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)); - // create the JOIN condition - JoinCondition cond; - cond.left = move(expr.children[0]); + CreateStatement stmt; + auto info = make_unique(); + info->schema = schema_name; + info->table = table_name; + info->query = move(select); + info->on_conflict = OnCreateConflict::ERROR_ON_CONFLICT; + stmt.info = move(info); + return binder.Bind((SQLStatement &)stmt); +} - cond.right = make_unique(in_type, ColumnBinding(chunk_index, 0)); - cond.comparison = ExpressionType::COMPARE_EQUAL; - join->conditions.push_back(move(cond)); - root = move(join); +const vector &CreateTableRelation::Columns() { + return columns; +} - // we replace the original subquery with a BoundColumnRefExpression referring to the mark column - unique_ptr result = - make_unique("IN (...)", LogicalType::BOOLEAN, ColumnBinding(chunk_index, 0)); - 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); - } - return result; +string CreateTableRelation::ToString(idx_t depth) { + string str = RenderWhitespace(depth) + "Create Table\n"; + return str + child->ToString(depth + 1); } } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/optimizer/join_order/join_relation.hpp +// duckdb/main/relation/create_view_relation.hpp // // //===----------------------------------------------------------------------===// @@ -109478,60 +114414,97 @@ unique_ptr InClauseRewriter::VisitReplace(BoundOperatorExpression &e - - namespace duckdb { -class LogicalOperator; -//! Represents a single relation and any metadata accompanying that relation -struct SingleJoinRelation { - LogicalOperator *op; - LogicalOperator *parent; +class CreateViewRelation : public Relation { +public: + CreateViewRelation(shared_ptr child, string view_name, bool replace, bool temporary); - SingleJoinRelation() { - } - SingleJoinRelation(LogicalOperator *op, LogicalOperator *parent) : op(op), parent(parent) { + shared_ptr child; + string view_name; + bool replace; + bool temporary; + vector columns; + +public: + BoundStatement Bind(Binder &binder) override; + const vector &Columns() override; + string ToString(idx_t depth) override; + bool IsReadOnly() override { + return false; } }; -//! Set of relations, used in the join graph. -struct JoinRelationSet { - JoinRelationSet(unique_ptr relations, idx_t count) : relations(move(relations)), count(count) { - } +} // namespace duckdb - 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 { + + +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) { + context.TryBindRelation(*this, this->columns); +} + +BoundStatement CreateViewRelation::Bind(Binder &binder) { + auto select = make_unique(); + select->node = child->GetQueryNode(); + + CreateStatement stmt; + auto info = make_unique(); + info->query = move(select); + info->view_name = view_name; + info->temporary = temporary; + info->schema = ""; + info->on_conflict = replace ? OnCreateConflict::REPLACE_ON_CONFLICT : OnCreateConflict::ERROR_ON_CONFLICT; + stmt.info = move(info); + return binder.Bind((SQLStatement &)stmt); +} + +const vector &CreateViewRelation::Columns() { + return columns; +} + +string CreateViewRelation::ToString(idx_t depth) { + string str = RenderWhitespace(depth) + "Create View\n"; + return str + child->ToString(depth + 1); +} + +} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/relation/cross_product_relation.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +class CrossProductRelation : public Relation { 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; - }; + CrossProductRelation(shared_ptr left, shared_ptr right); + + shared_ptr left; + shared_ptr right; + vector columns; 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); + unique_ptr GetQueryNode() override; -private: - JoinRelationTreeNode root; + const vector &Columns() override; + string ToString(idx_t depth) override; + + unique_ptr GetTableRef() override; }; } // namespace duckdb @@ -109539,152 +114512,82 @@ class JoinRelationSetManager { -#include +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/tableref/crossproductref.hpp +// +// +//===----------------------------------------------------------------------===// -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(); +namespace duckdb { +//! Represents a cross product +class CrossProductRef : public TableRef { +public: + CrossProductRef() : TableRef(TableReferenceType::CROSS_PRODUCT) { } - // 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); + + //! The left hand side of the cross product + unique_ptr left; + //! The right hand side of the cross product + unique_ptr right; + +public: + bool Equals(const TableRef *other_p) const override; + + unique_ptr Copy() override; + + //! Serializes a blob into a CrossProductRef + void Serialize(FieldWriter &serializer) const override; + //! Deserializes a blob back into a CrossProductRef + static unique_ptr Deserialize(FieldReader &source); +}; +} // namespace duckdb + + +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)) { + if (&left->context != &right->context) { + throw Exception("Cannot combine LEFT and RIGHT relations of different connections!"); } - return info->relation.get(); + context.TryBindRelation(*this, this->columns); } -//! 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); +unique_ptr CrossProductRelation::GetQueryNode() { + auto result = make_unique(); + result->select_list.push_back(make_unique()); + result->from_table = GetTableRef(); + return move(result); } -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); +unique_ptr CrossProductRelation::GetTableRef() { + auto cross_product_ref = make_unique(); + cross_product_ref->left = left->GetTableRef(); + cross_product_ref->right = right->GetTableRef(); + return move(cross_product_ref); } -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); +const vector &CrossProductRelation::Columns() { + return this->columns; } -// 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); -// } +string CrossProductRelation::ToString(idx_t depth) { + string str = RenderWhitespace(depth); + str = "Cross Product"; + return str + "\n" + left->ToString(depth + 1) + right->ToString(depth + 1); +} } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/optimizer/join_order/query_graph.hpp +// duckdb/main/relation/delete_relation.hpp // // //===----------------------------------------------------------------------===// @@ -109694,198 +114597,103 @@ JoinRelationSet *JoinRelationSetManager::Union(JoinRelationSet *left, JoinRelati - - - -#include - namespace duckdb { -class Expression; -class LogicalOperator; -struct FilterInfo { - idx_t filter_index; - JoinRelationSet *left_set = nullptr; - JoinRelationSet *right_set = nullptr; - JoinRelationSet *set = nullptr; -}; +class DeleteRelation : public Relation { +public: + DeleteRelation(ClientContext &context, unique_ptr condition, string schema_name, + string table_name); -struct FilterNode { - vector filters; - unordered_map> children; -}; + vector columns; + unique_ptr condition; + string schema_name; + string table_name; -struct NeighborInfo { - JoinRelationSet *neighbor; - vector filters; +public: + BoundStatement Bind(Binder &binder) override; + const vector &Columns() override; + string ToString(idx_t depth) override; + bool IsReadOnly() override { + return false; + } }; -//! The QueryGraph contains edges between relations and allows edges to be created/queried -class QueryGraph { -public: - //! Contains a node with info about neighboring relations and child edge infos - struct QueryEdge { - vector> neighbors; - unordered_map> children; - }; +} // namespace duckdb -public: - string ToString() const; - void Print(); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/statement/delete_statement.hpp +// +// +//===----------------------------------------------------------------------===// - //! Create an edge in the edge_set - void CreateEdge(JoinRelationSet *left, JoinRelationSet *right, FilterInfo *info); - //! Returns a connection if there is an edge that connects these two sets, or nullptr otherwise - NeighborInfo *GetConnection(JoinRelationSet *node, JoinRelationSet *other); - //! Enumerate the neighbors of a specific node that do not belong to any of the exclusion_set. Note that if a - //! neighbor has multiple nodes, this function will return the lowest entry in that set. - vector GetNeighbors(JoinRelationSet *node, unordered_set &exclusion_set); - //! Enumerate all neighbors of a given JoinRelationSet node - void EnumerateNeighbors(JoinRelationSet *node, const std::function &callback); -private: - //! Get the QueryEdge of a specific node - QueryEdge *GetQueryEdge(JoinRelationSet *left); - QueryEdge root; -}; -} // namespace duckdb +namespace duckdb { +class DeleteStatement : public SQLStatement { +public: + DeleteStatement(); + unique_ptr condition; + unique_ptr table; + vector> using_clauses; +protected: + DeleteStatement(const DeleteStatement &other); -namespace duckdb { +public: + unique_ptr Copy() const override; +}; -using QueryEdge = QueryGraph::QueryEdge; +} // namespace duckdb -// 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)); -} +namespace duckdb { -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; - } - } - } - } +DeleteRelation::DeleteRelation(ClientContext &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)) { + context.TryBindRelation(*this, this->columns); } -//! 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(); +BoundStatement DeleteRelation::Bind(Binder &binder) { + auto basetable = make_unique(); + basetable->schema_name = schema_name; + basetable->table_name = table_name; + + DeleteStatement stmt; + stmt.condition = condition ? condition->Copy() : nullptr; + stmt.table = move(basetable); + return binder.Bind((SQLStatement &)stmt); } -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; +const vector &DeleteRelation::Columns() { + return columns; } -NeighborInfo *QueryGraph::GetConnection(JoinRelationSet *node, JoinRelationSet *other) { - NeighborInfo *connection = nullptr; - EnumerateNeighbors(node, [&](NeighborInfo *info) -> bool { - if (JoinRelationSet::IsSubset(other, info->neighbor)) { - connection = info; - return true; - } - return false; - }); - return connection; +string DeleteRelation::ToString(idx_t depth) { + string str = RenderWhitespace(depth) + "DELETE FROM " + table_name; + if (condition) { + str += " WHERE " + condition->ToString(); + } + return str; } } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/optimizer/join_order_optimizer.hpp +// duckdb/main/relation/distinct_relation.hpp // // //===----------------------------------------------------------------------===// @@ -109894,110 +114702,95 @@ NeighborInfo *QueryGraph::GetConnection(JoinRelationSet *node, JoinRelationSet * +namespace duckdb { +class DistinctRelation : public Relation { +public: + explicit DistinctRelation(shared_ptr child); + shared_ptr child; +public: + unique_ptr GetQueryNode() override; + const vector &Columns() override; + string ToString(idx_t depth) override; + string GetAlias() override; +public: + bool InheritsColumnBindings() override { + return true; + } + Relation *ChildRelation() override { + return child.get(); + } +}; -#include +} // namespace duckdb -namespace duckdb { -class JoinOrderOptimizer { -public: - //! Represents a node in the join plan - struct JoinNode { - JoinRelationSet *set; - NeighborInfo *info; - idx_t cardinality; - idx_t cost; - JoinNode *left; - JoinNode *right; - //! Create a leaf node in the join tree - JoinNode(JoinRelationSet *set, idx_t cardinality) - : set(set), info(nullptr), cardinality(cardinality), cost(cardinality), left(nullptr), right(nullptr) { - } - //! Create an intermediate node in the join tree - JoinNode(JoinRelationSet *set, NeighborInfo *info, JoinNode *left, JoinNode *right, idx_t cardinality, - idx_t cost) - : set(set), info(info), cardinality(cardinality), cost(cost), left(left), right(right) { - } - }; -public: - explicit JoinOrderOptimizer(ClientContext &context) : context(context) { - } +namespace duckdb { - //! Perform join reordering inside a plan - unique_ptr Optimize(unique_ptr plan); +DistinctRelation::DistinctRelation(shared_ptr child_p) + : Relation(child_p->context, RelationType::DISTINCT_RELATION), child(move(child_p)) { + vector dummy_columns; + context.TryBindRelation(*this, dummy_columns); +} -private: - ClientContext &context; - //! The total amount of join pairs that have been considered - idx_t pairs = 0; - //! Set of all relations considered in the join optimizer - vector> relations; - //! A mapping of base table index -> index into relations array (relation number) - unordered_map relation_mapping; - //! A structure holding all the created JoinRelationSet objects - JoinRelationSetManager set_manager; - //! The set of edges used in the join optimizer - QueryGraph query_graph; - //! The optimal join plan found for the specific JoinRelationSet* - unordered_map> plans; - //! The set of filters extracted from the query graph - vector> filters; - //! 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} - expression_map_t> equivalence_sets; +unique_ptr DistinctRelation::GetQueryNode() { + auto child_node = child->GetQueryNode(); + child_node->modifiers.push_back(make_unique()); + return child_node; +} - //! Extract the bindings referred to by an Expression - bool ExtractBindings(Expression &expression, unordered_set &bindings); - //! Traverse the query tree to find (1) base relations, (2) existing join conditions and (3) filters that can be - //! rewritten into joins. Returns true if there are joins in the tree that can be reordered, false otherwise. - bool ExtractJoinRelations(LogicalOperator &input_op, vector &filter_operators, - LogicalOperator *parent = nullptr); - //! Emit a pair as a potential join candidate. Returns the best plan found for the (left, right) connection (either - //! the newly created plan, or an existing plan) - JoinNode *EmitPair(JoinRelationSet *left, JoinRelationSet *right, NeighborInfo *info); - //! Tries to emit a potential join candidate pair. Returns false if too many pairs have already been emitted, - //! cancelling the dynamic programming step. - bool TryEmitPair(JoinRelationSet *left, JoinRelationSet *right, NeighborInfo *info); +string DistinctRelation::GetAlias() { + return child->GetAlias(); +} - bool EnumerateCmpRecursive(JoinRelationSet *left, JoinRelationSet *right, unordered_set exclusion_set); - //! Emit a relation set node - bool EmitCSG(JoinRelationSet *node); - //! Enumerate the possible connected subgraphs that can be joined together in the join graph - bool EnumerateCSGRecursive(JoinRelationSet *node, unordered_set &exclusion_set); - //! Rewrite a logical query plan given the join plan - unique_ptr RewritePlan(unique_ptr plan, JoinNode *node); - //! Generate cross product edges inside the side - void GenerateCrossProducts(); - //! Perform the join order solving - void SolveJoinOrder(); - //! Solve the join order exactly using dynamic programming. Returns true if it was completed successfully (i.e. did - //! not time-out) - bool SolveJoinOrderExactly(); - //! Solve the join order approximately using a greedy algorithm - void SolveJoinOrderApproximately(); +const vector &DistinctRelation::Columns() { + return child->Columns(); +} - unique_ptr ResolveJoinConditions(unique_ptr op); - std::pair> - GenerateJoins(vector> &extracted_relations, JoinNode *node); -}; +string DistinctRelation::ToString(idx_t depth) { + string str = RenderWhitespace(depth) + "Distinct\n"; + return str + child->ToString(depth + 1); + ; +} } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/relation/explain_relation.hpp +// +// +//===----------------------------------------------------------------------===// + +namespace duckdb { + +class ExplainRelation : public Relation { +public: + explicit ExplainRelation(shared_ptr child); + + shared_ptr child; + vector columns; +public: + BoundStatement Bind(Binder &binder) override; + const vector &Columns() override; + string ToString(idx_t depth) override; + bool IsReadOnly() override { + return false; + } +}; +} // namespace duckdb @@ -110005,939 +114798,226 @@ class JoinOrderOptimizer { +namespace duckdb { +ExplainRelation::ExplainRelation(shared_ptr child_p) + : Relation(child_p->context, RelationType::EXPLAIN_RELATION), child(move(child_p)) { + context.TryBindRelation(*this, this->columns); +} +BoundStatement ExplainRelation::Bind(Binder &binder) { + auto select = make_unique(); + select->node = child->GetQueryNode(); + ExplainStatement explain(move(select)); + return binder.Bind((SQLStatement &)explain); +} +const vector &ExplainRelation::Columns() { + return columns; +} +string ExplainRelation::ToString(idx_t depth) { + string str = RenderWhitespace(depth) + "Explain\n"; + return str + child->ToString(depth + 1); +} +} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/relation/filter_relation.hpp +// +// +//===----------------------------------------------------------------------===// +namespace duckdb { +class FilterRelation : public Relation { +public: + FilterRelation(shared_ptr child, unique_ptr condition); + unique_ptr condition; + shared_ptr child; +public: + unique_ptr GetQueryNode() override; + const vector &Columns() override; + string ToString(idx_t depth) override; + string GetAlias() override; +public: + bool InheritsColumnBindings() override { + return true; + } + Relation *ChildRelation() override { + return child.get(); + } +}; +} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/query_node/set_operation_node.hpp +// +// +//===----------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/set_operation_type.hpp +// +// +//===----------------------------------------------------------------------===// +namespace duckdb { +enum class SetOperationType : uint8_t { NONE = 0, UNION = 1, EXCEPT = 2, INTERSECT = 3 }; +} -#include namespace duckdb { -using JoinNode = JoinOrderOptimizer::JoinNode; - -//! Returns true if A and B are disjoint, false otherwise -template -static bool Disjoint(unordered_set &a, unordered_set &b) { - for (auto &entry : a) { - if (b.find(entry) != b.end()) { - return false; - } +class SetOperationNode : public QueryNode { +public: + SetOperationNode() : QueryNode(QueryNodeType::SET_OPERATION_NODE) { } - return true; -} -//! Extract the set of relations referred to inside an expression -bool JoinOrderOptimizer::ExtractBindings(Expression &expression, unordered_set &bindings) { - if (expression.type == ExpressionType::BOUND_COLUMN_REF) { - auto &colref = (BoundColumnRefExpression &)expression; - D_ASSERT(colref.depth == 0); - D_ASSERT(colref.binding.table_index != INVALID_INDEX); - // map the base table index to the relation index used by the JoinOrderOptimizer - D_ASSERT(relation_mapping.find(colref.binding.table_index) != relation_mapping.end()); - bindings.insert(relation_mapping[colref.binding.table_index]); - } - if (expression.type == ExpressionType::BOUND_REF) { - // bound expression - bindings.clear(); - return false; - } - D_ASSERT(expression.type != ExpressionType::SUBQUERY); - bool can_reorder = true; - ExpressionIterator::EnumerateChildren(expression, [&](Expression &expr) { - if (!ExtractBindings(expr, bindings)) { - can_reorder = false; - return; - } - }); - return can_reorder; -} - -static unique_ptr PushFilter(unique_ptr node, unique_ptr expr) { - // push an expression into a filter - // first check if we have any filter to push it into - 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); - } - // push the filter into the LogicalFilter - D_ASSERT(node->type == LogicalOperatorType::LOGICAL_FILTER); - auto filter = (LogicalFilter *)node.get(); - filter->expressions.push_back(move(expr)); - return node; -} - -bool JoinOrderOptimizer::ExtractJoinRelations(LogicalOperator &input_op, vector &filter_operators, - LogicalOperator *parent) { - LogicalOperator *op = &input_op; - while (op->children.size() == 1 && (op->type != LogicalOperatorType::LOGICAL_PROJECTION && - op->type != LogicalOperatorType::LOGICAL_EXPRESSION_GET)) { - if (op->type == LogicalOperatorType::LOGICAL_FILTER) { - // extract join conditions from filter - filter_operators.push_back(op); - } - if (op->type == LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY || - 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])); - return false; - } - op = op->children[0].get(); - } - bool non_reorderable_operation = false; - if (op->type == LogicalOperatorType::LOGICAL_UNION || op->type == LogicalOperatorType::LOGICAL_EXCEPT || - op->type == LogicalOperatorType::LOGICAL_INTERSECT || op->type == LogicalOperatorType::LOGICAL_DELIM_JOIN || - op->type == LogicalOperatorType::LOGICAL_ANY_JOIN) { - // set operation, optimize separately in children - non_reorderable_operation = true; - } - - if (op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN) { - auto &join = (LogicalComparisonJoin &)*op; - if (join.join_type == JoinType::INNER) { - // extract join conditions from inner join - filter_operators.push_back(op); - } else { - // non-inner join, not reorderable yet - non_reorderable_operation = true; - if (join.join_type == JoinType::LEFT && join.right_projection_map.empty()) { - // for left joins; if the RHS cardinality is significantly larger than the LHS (2x) - // we convert to doing a RIGHT OUTER JOIN - // FIXME: for now we don't swap if the right_projection_map is not empty - // this can be fixed once we implement the left_projection_map properly... - auto lhs_cardinality = join.children[0]->EstimateCardinality(context); - auto rhs_cardinality = join.children[1]->EstimateCardinality(context); - if (rhs_cardinality > lhs_cardinality * 2) { - join.join_type = JoinType::RIGHT; - std::swap(join.children[0], join.children[1]); - for (auto &cond : join.conditions) { - std::swap(cond.left, cond.right); - cond.comparison = FlipComparisionExpression(cond.comparison); - } - } - } - } - } - if (non_reorderable_operation) { - // we encountered a non-reordable operation (setop or non-inner join) - // we do not reorder non-inner joins yet, however we do want to expand the potential join graph around them - // non-inner joins are also tricky because we can't freely make conditions through them - // e.g. suppose we have (left LEFT OUTER JOIN right WHERE right IS NOT NULL), the join can generate - // new NULL values in the right side, so pushing this condition through the join leads to incorrect results - // for this reason, we just start a new JoinOptimizer pass in each of the children of the join - for (auto &child : op->children) { - JoinOrderOptimizer optimizer(context); - child = optimizer.Optimize(move(child)); - } - // after this we want to treat this node as one "end node" (like e.g. a base relation) - // however the join refers to multiple base relations - // enumerate all base relations obtained from this join and add them to the relation mapping - // also, we have to resolve the join conditions for the joins here - // get the left and right bindings - unordered_set bindings; - LogicalJoin::GetTableReferences(*op, bindings); - // now create the relation that refers to all these bindings - auto relation = make_unique(&input_op, parent); - for (idx_t it : bindings) { - relation_mapping[it] = relations.size(); - } - relations.push_back(move(relation)); - return true; - } - if (op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN || - op->type == 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) { - // base table scan, add to set of relations - auto get = (LogicalGet *)op; - auto relation = make_unique(&input_op, parent); - relation_mapping[get->table_index] = relations.size(); - relations.push_back(move(relation)); - return true; - } else if (op->type == LogicalOperatorType::LOGICAL_EXPRESSION_GET) { - // base table scan, add to set of relations - auto get = (LogicalExpressionGet *)op; - auto relation = make_unique(&input_op, parent); - relation_mapping[get->table_index] = relations.size(); - relations.push_back(move(relation)); - return true; - } else if (op->type == 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)); - return true; - } else if (op->type == 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])); - // 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)); - return true; - } - return false; -} - -//! Update the exclusion set with all entries in the subgraph -static void UpdateExclusionSet(JoinRelationSet *node, unordered_set &exclusion_set) { - for (idx_t i = 0; i < node->count; i++) { - exclusion_set.insert(node->relations[i]); - } -} - -//! Create a new JoinTree node by joining together two previous JoinTree nodes -static unique_ptr CreateJoinTree(JoinRelationSet *set, NeighborInfo *info, JoinNode *left, JoinNode *right) { - // for the hash join we want the right side (build side) to have the smallest cardinality - // also just a heuristic but for now... - // FIXME: we should probably actually benchmark that as well - // FIXME: should consider different join algorithms, should we pick a join algorithm here as well? (probably) - if (left->cardinality < right->cardinality) { - return CreateJoinTree(set, info, right, left); - } - // the expected cardinality is the max of the child cardinalities - // FIXME: we should obviously use better cardinality estimation here - // but for now we just assume foreign key joins only - idx_t expected_cardinality; - if (info->filters.empty()) { - // cross product - expected_cardinality = left->cardinality * right->cardinality; - } else { - // normal join, expect foreign key join - expected_cardinality = MaxValue(left->cardinality, right->cardinality); - } - // cost is expected_cardinality plus the cost of the previous plans - idx_t cost = expected_cardinality; - return make_unique(set, info, left, right, expected_cardinality, cost); -} - -JoinNode *JoinOrderOptimizer::EmitPair(JoinRelationSet *left, JoinRelationSet *right, NeighborInfo *info) { - // get the left and right join plans - auto &left_plan = plans[left]; - auto &right_plan = plans[right]; - auto new_set = set_manager.Union(left, right); - // create the join tree based on combining the two plans - auto new_plan = CreateJoinTree(new_set, info, left_plan.get(), right_plan.get()); - // check if this plan is the optimal plan we found for this set of relations - auto entry = plans.find(new_set); - if (entry == plans.end() || new_plan->cost < entry->second->cost) { - // the plan is the optimal plan, move it into the dynamic programming tree - auto result = new_plan.get(); - plans[new_set] = move(new_plan); - return result; - } - return entry->second.get(); -} + //! The type of set operation + SetOperationType setop_type = SetOperationType::NONE; + //! The left side of the set operation + unique_ptr left; + //! The right side of the set operation + unique_ptr right; -bool JoinOrderOptimizer::TryEmitPair(JoinRelationSet *left, JoinRelationSet *right, NeighborInfo *info) { - pairs++; - if (pairs >= 2000) { - // when the amount of pairs gets too large we exit the dynamic programming and resort to a greedy algorithm - // FIXME: simple heuristic currently - // at 10K pairs stop searching exactly and switch to heuristic - return false; + const vector> &GetSelectList() const override { + return left->GetSelectList(); } - EmitPair(left, right, info); - return true; -} -bool JoinOrderOptimizer::EmitCSG(JoinRelationSet *node) { - // create the exclusion set as everything inside the subgraph AND anything with members BELOW it - unordered_set exclusion_set; - for (idx_t i = 0; i < node->relations[0]; i++) { - exclusion_set.insert(i); - } - UpdateExclusionSet(node, exclusion_set); - // find the neighbors given this exclusion set - auto neighbors = query_graph.GetNeighbors(node, exclusion_set); - if (neighbors.empty()) { - return true; - } - // we iterate over the neighbors ordered by their first node - sort(neighbors.begin(), neighbors.end()); - for (auto neighbor : neighbors) { - // since the GetNeighbors only returns the smallest element in a list, the entry might not be connected to - // (only!) this neighbor, hence we have to do a connectedness check before we can emit it - auto neighbor_relation = set_manager.GetJoinRelation(neighbor); - auto connection = query_graph.GetConnection(node, neighbor_relation); - if (connection) { - if (!TryEmitPair(node, neighbor_relation, connection)) { - return false; - } - } - if (!EnumerateCmpRecursive(node, neighbor_relation, exclusion_set)) { - return false; - } - } - return true; -} +public: + bool Equals(const QueryNode *other) const override; + //! Create a copy of this SelectNode + unique_ptr Copy() const override; -bool JoinOrderOptimizer::EnumerateCmpRecursive(JoinRelationSet *left, JoinRelationSet *right, - unordered_set exclusion_set) { - // get the neighbors of the second relation under the exclusion set - auto neighbors = query_graph.GetNeighbors(right, exclusion_set); - if (neighbors.empty()) { - return true; - } - vector union_sets; - union_sets.resize(neighbors.size()); - for (idx_t i = 0; i < neighbors.size(); i++) { - auto neighbor = set_manager.GetJoinRelation(neighbors[i]); - // emit the combinations of this node and its neighbors - auto combined_set = set_manager.Union(right, neighbor); - if (plans.find(combined_set) != plans.end()) { - auto connection = query_graph.GetConnection(left, combined_set); - if (connection) { - if (!TryEmitPair(left, combined_set, connection)) { - return false; - } - } - } - union_sets[i] = combined_set; - } - // recursively enumerate the sets - for (idx_t i = 0; i < neighbors.size(); i++) { - // updated the set of excluded entries with this neighbor - unordered_set new_exclusion_set = exclusion_set; - new_exclusion_set.insert(neighbors[i]); - if (!EnumerateCmpRecursive(left, union_sets[i], new_exclusion_set)) { - return false; - } - } - return true; -} + //! Serializes a QueryNode to a stand-alone binary blob + void Serialize(FieldWriter &writer) const override; + //! Deserializes a blob back into a QueryNode + static unique_ptr Deserialize(FieldReader &reader); +}; -bool JoinOrderOptimizer::EnumerateCSGRecursive(JoinRelationSet *node, unordered_set &exclusion_set) { - // find neighbors of S under the exlusion set - auto neighbors = query_graph.GetNeighbors(node, exclusion_set); - if (neighbors.empty()) { - return true; - } - // now first emit the connected subgraphs of the neighbors - vector union_sets; - union_sets.resize(neighbors.size()); - for (idx_t i = 0; i < neighbors.size(); i++) { - auto neighbor = set_manager.GetJoinRelation(neighbors[i]); - // emit the combinations of this node and its neighbors - auto new_set = set_manager.Union(node, neighbor); - if (plans.find(new_set) != plans.end()) { - if (!EmitCSG(new_set)) { - return false; - } - } - union_sets[i] = new_set; - } - // recursively enumerate the sets - for (idx_t i = 0; i < neighbors.size(); i++) { - // updated the set of excluded entries with this neighbor - unordered_set new_exclusion_set = exclusion_set; - new_exclusion_set.insert(neighbors[i]); - if (!EnumerateCSGRecursive(union_sets[i], new_exclusion_set)) { - return false; - } - } - return true; -} +} // namespace duckdb -bool JoinOrderOptimizer::SolveJoinOrderExactly() { - // now we perform the actual dynamic programming to compute the final result - // we enumerate over all the possible pairs in the neighborhood - for (idx_t i = relations.size(); i > 0; i--) { - // for every node in the set, we consider it as the start node once - auto start_node = set_manager.GetJoinRelation(i - 1); - // emit the start node - if (!EmitCSG(start_node)) { - return false; - } - // initialize the set of exclusion_set as all the nodes with a number below this - unordered_set exclusion_set; - for (idx_t j = 0; j < i - 1; j++) { - exclusion_set.insert(j); - } - // then we recursively search for neighbors that do not belong to the banned entries - if (!EnumerateCSGRecursive(start_node, exclusion_set)) { - return false; - } - } - return true; -} +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/expression/conjunction_expression.hpp +// +// +//===----------------------------------------------------------------------===// -void JoinOrderOptimizer::SolveJoinOrderApproximately() { - // at this point, we exited the dynamic programming but did not compute the final join order because it took too - // long instead, we use a greedy heuristic to obtain a join ordering now we use Greedy Operator Ordering to - // construct the result tree first we start out with all the base relations (the to-be-joined relations) - vector join_relations; // T in the paper - for (idx_t i = 0; i < relations.size(); i++) { - join_relations.push_back(set_manager.GetJoinRelation(i)); - } - while (join_relations.size() > 1) { - // now in every step of the algorithm, we greedily pick the join between the to-be-joined relations that has the - // smallest cost. This is O(r^2) per step, and every step will reduce the total amount of relations to-be-joined - // by 1, so the total cost is O(r^3) in the amount of relations - idx_t best_left = 0, best_right = 0; - JoinNode *best_connection = nullptr; - for (idx_t i = 0; i < join_relations.size(); i++) { - auto left = join_relations[i]; - for (idx_t j = i + 1; j < join_relations.size(); j++) { - auto right = join_relations[j]; - // check if we can connect these two relations - auto connection = query_graph.GetConnection(left, right); - if (connection) { - // we can! check the cost of this connection - auto node = EmitPair(left, right, connection); - if (!best_connection || node->cost < best_connection->cost) { - // best pair found so far - best_connection = node; - best_left = i; - best_right = j; - } - } - } - } - if (!best_connection) { - // could not find a connection, but we were not done with finding a completed plan - // we have to add a cross product; we add it between the two smallest relations - JoinNode *smallest_plans[2] = {nullptr}; - idx_t smallest_index[2]; - for (idx_t i = 0; i < join_relations.size(); i++) { - // get the plan for this relation - auto current_plan = plans[join_relations[i]].get(); - // check if the cardinality is smaller than the smallest two found so far - for (idx_t j = 0; j < 2; j++) { - if (!smallest_plans[j] || smallest_plans[j]->cardinality > current_plan->cardinality) { - smallest_plans[j] = current_plan; - smallest_index[j] = i; - break; - } - } - } - if (!smallest_plans[0] || !smallest_plans[1]) { - throw InternalException("Internal error in join order optimizer"); - } - D_ASSERT(smallest_plans[0] && smallest_plans[1]); - D_ASSERT(smallest_index[0] != smallest_index[1]); - auto left = smallest_plans[0]->set; - auto right = smallest_plans[1]->set; - // create a cross product edge (i.e. edge with empty filter) between these two sets in the query graph - query_graph.CreateEdge(left, right, nullptr); - // now emit the pair and continue with the algorithm - auto connection = query_graph.GetConnection(left, right); - D_ASSERT(connection); - best_connection = EmitPair(left, right, connection); - best_left = smallest_index[0]; - best_right = smallest_index[1]; - // the code below assumes best_right > best_left - if (best_left > best_right) { - std::swap(best_left, best_right); - } - } - // now update the to-be-checked pairs - // remove left and right, and add the combination - // important to erase the biggest element first - // if we erase the smallest element first the index of the biggest element changes - D_ASSERT(best_right > best_left); - join_relations.erase(join_relations.begin() + best_right); - join_relations.erase(join_relations.begin() + best_left); - join_relations.push_back(best_connection->set); - } -} -void JoinOrderOptimizer::SolveJoinOrder() { - // first try to solve the join order exactly - if (!SolveJoinOrderExactly()) { - // otherwise, if that times out we resort to a greedy algorithm - SolveJoinOrderApproximately(); - } -} -void JoinOrderOptimizer::GenerateCrossProducts() { - // generate a set of cross products to combine the currently available plans into a full join plan - // we create edges between every relation with a high cost - for (idx_t i = 0; i < relations.size(); i++) { - auto left = set_manager.GetJoinRelation(i); - for (idx_t j = 0; j < relations.size(); j++) { - if (i != j) { - auto right = set_manager.GetJoinRelation(j); - query_graph.CreateEdge(left, right, nullptr); - query_graph.CreateEdge(right, left, nullptr); - } - } - } -} -static unique_ptr ExtractJoinRelation(SingleJoinRelation &rel) { - auto &children = rel.parent->children; - 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]); - children.erase(children.begin() + i); - return result; - } - } - throw Exception("Could not find relation in parent node (?)"); -} +namespace duckdb { -pair> -JoinOrderOptimizer::GenerateJoins(vector> &extracted_relations, JoinNode *node) { - JoinRelationSet *left_node = nullptr, *right_node = nullptr; - JoinRelationSet *result_relation; - unique_ptr result_operator; - if (node->left && node->right) { - // generate the left and right children - auto left = GenerateJoins(extracted_relations, node->left); - auto right = GenerateJoins(extracted_relations, node->right); +//! Represents a conjunction (AND/OR) +class ConjunctionExpression : public ParsedExpression { +public: + explicit ConjunctionExpression(ExpressionType type); + ConjunctionExpression(ExpressionType type, vector> children); + ConjunctionExpression(ExpressionType type, unique_ptr left, unique_ptr right); - if (node->info->filters.empty()) { - // no filters, create a cross product - auto join = make_unique(); - join->children.push_back(move(left.second)); - join->children.push_back(move(right.second)); - result_operator = move(join); - } 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)); - // 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]); - // now create the actual join condition - D_ASSERT((JoinRelationSet::IsSubset(left.first, f->left_set) && - JoinRelationSet::IsSubset(right.first, f->right_set)) || - (JoinRelationSet::IsSubset(left.first, f->right_set) && - JoinRelationSet::IsSubset(right.first, f->left_set))); - JoinCondition cond; - D_ASSERT(condition->GetExpressionClass() == ExpressionClass::BOUND_COMPARISON); - 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); - if (condition->type == ExpressionType::COMPARE_NOT_DISTINCT_FROM) { - cond.comparison = ExpressionType::COMPARE_EQUAL; - cond.null_values_are_equal = true; - } else if (condition->type == ExpressionType::COMPARE_DISTINCT_FROM) { - cond.comparison = condition->type; - cond.null_values_are_equal = true; - } else { - 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)); - } - D_ASSERT(!join->conditions.empty()); - result_operator = move(join); - } - left_node = left.first; - right_node = right.first; - result_relation = set_manager.Union(left_node, right_node); - } else { - // base node, get the entry from the list of extracted relations - 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]]); - } - // 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 - for (auto &filter_info : filter_infos) { - // check if the filter has already been extracted - auto info = filter_info.get(); - if (filters[info->filter_index]) { - // 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]); - // 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)); - continue; - } - // the node below us is a join or cross product and the expression is a comparison - // check if the nodes can be split up into left/right - bool found_subset = false; - bool invert = false; - if (JoinRelationSet::IsSubset(left_node, info->left_set) && - JoinRelationSet::IsSubset(right_node, info->right_set)) { - found_subset = true; - } else if (JoinRelationSet::IsSubset(right_node, info->left_set) && - JoinRelationSet::IsSubset(left_node, info->right_set)) { - invert = true; - found_subset = true; - } - if (!found_subset) { - // could not be split up into left/right - result_operator = PushFilter(move(result_operator), move(filter)); - continue; - } - // create the join condition - JoinCondition cond; - 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.comparison = comparison.type; - if (invert) { - // reverse comparison expression if we reverse the order of the children - cond.comparison = FlipComparisionExpression(comparison.type); - } - // now find the join to push it into - auto node = result_operator.get(); - if (node->type == LogicalOperatorType::LOGICAL_FILTER) { - node = node->children[0].get(); - } - 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)); - if (node == result_operator.get()) { - result_operator = move(comp_join); - } else { - D_ASSERT(result_operator->type == LogicalOperatorType::LOGICAL_FILTER); - result_operator->children[0] = move(comp_join); - } - } else { - D_ASSERT(node->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN); - auto &comp_join = (LogicalComparisonJoin &)*node; - comp_join.conditions.push_back(move(cond)); - } - } - } - } - return make_pair(result_relation, move(result_operator)); -} + vector> children; -unique_ptr JoinOrderOptimizer::RewritePlan(unique_ptr plan, JoinNode *node) { - // now we have to rewrite the plan - bool root_is_join = plan->children.size() > 1; +public: + void AddExpression(unique_ptr expr); - // first we will extract all relations from the main plan - vector> extracted_relations; - for (auto &relation : relations) { - extracted_relations.push_back(ExtractJoinRelation(*relation)); - } - // now we generate the actual joins - auto join_tree = GenerateJoins(extracted_relations, node); - // perform the final pushdown of remaining filters - for (auto &filter : filters) { - // check if the filter has already been extracted - if (filter) { - // if not we need to push it - join_tree.second = PushFilter(move(join_tree.second), move(filter)); - } - } + string ToString() const override; - // find the first join in the relation to know where to place this node - if (root_is_join) { - // first node is the join, return it immediately - return move(join_tree.second); - } - D_ASSERT(plan->children.size() == 1); - // have to move up through the relations - auto op = plan.get(); - auto parent = plan.get(); - while (op->type != LogicalOperatorType::LOGICAL_CROSS_PRODUCT && - op->type != LogicalOperatorType::LOGICAL_COMPARISON_JOIN) { - D_ASSERT(op->children.size() == 1); - parent = op; - op = op->children[0].get(); - } - // have to replace at this node - parent->children[0] = move(join_tree.second); - return plan; -} + static bool Equals(const ConjunctionExpression *a, const ConjunctionExpression *b); -// the join ordering is pretty much a straight implementation of the paper "Dynamic Programming Strikes Back" by Guido -// Moerkotte and Thomas Neumannn, see that paper for additional info/documentation bonus slides: -// https://db.in.tum.de/teaching/ws1415/queryopt/chapter3.pdf?lang=de -// FIXME: incorporate cardinality estimation into the plans, possibly by pushing samples? -unique_ptr JoinOrderOptimizer::Optimize(unique_ptr plan) { - D_ASSERT(filters.empty() && relations.empty()); // assert that the JoinOrderOptimizer has not been used before - LogicalOperator *op = plan.get(); - // now we optimize the current plan - // we skip past until we find the first projection, we do this because the HAVING clause inserts a Filter AFTER the - // group by and this filter cannot be reordered - // extract a list of all relations that have to be joined together - // and a list of all conditions that is applied to them - vector filter_operators; - if (!ExtractJoinRelations(*op, filter_operators)) { - // do not support reordering this type of plan - return plan; - } - if (relations.size() <= 1) { - // at most one relation, nothing to reorder - return plan; - } - // now that we know we are going to perform join ordering we actually extract the filters, eliminating duplicate - // filters in the process - expression_set_t filter_set; - for (auto &op : filter_operators) { - if (op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN) { - auto &join = (LogicalComparisonJoin &)*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)); - if (filter_set.find(comparison.get()) == filter_set.end()) { - filter_set.insert(comparison.get()); - filters.push_back(move(comparison)); - } - } - join.conditions.clear(); - } else { - for (auto &expression : op->expressions) { - if (filter_set.find(expression.get()) == filter_set.end()) { - filter_set.insert(expression.get()); - filters.push_back(move(expression)); - } - } - op->expressions.clear(); - } - } - // create potential edges from the comparisons - for (idx_t i = 0; i < filters.size(); i++) { - auto &filter = filters[i]; - auto info = make_unique(); - auto filter_info = info.get(); - filter_infos.push_back(move(info)); - // first extract the relation set for the entire filter - unordered_set bindings; - ExtractBindings(*filter, bindings); - filter_info->set = set_manager.GetJoinRelation(bindings); - filter_info->filter_index = i; - // now check if it can be used as a join predicate - if (filter->GetExpressionClass() == ExpressionClass::BOUND_COMPARISON) { - auto comparison = (BoundComparisonExpression *)filter.get(); - // extract the bindings that are required for the left and right side of the comparison - unordered_set left_bindings, right_bindings; - ExtractBindings(*comparison->left, left_bindings); - ExtractBindings(*comparison->right, right_bindings); - if (!left_bindings.empty() && !right_bindings.empty()) { - // both the left and the right side have bindings - // first create the relation sets, if they do not exist - filter_info->left_set = set_manager.GetJoinRelation(left_bindings); - filter_info->right_set = set_manager.GetJoinRelation(right_bindings); - // we can only create a meaningful edge if the sets are not exactly the same - if (filter_info->left_set != filter_info->right_set) { - // check if the sets are disjoint - if (Disjoint(left_bindings, right_bindings)) { - // they are disjoint, we only need to create one set of edges in the join graph - query_graph.CreateEdge(filter_info->left_set, filter_info->right_set, filter_info); - query_graph.CreateEdge(filter_info->right_set, filter_info->left_set, filter_info); - } else { - continue; - } - continue; - } - } - } - } - // now use dynamic programming to figure out the optimal join order - // First we initialize each of the single-node plans with themselves and with their cardinalities these are the leaf - // nodes of the join tree NOTE: we can just use pointers to JoinRelationSet* here because the GetJoinRelation - // function ensures that a unique combination of relations will have a unique JoinRelationSet object. - for (idx_t i = 0; i < relations.size(); i++) { - auto &rel = *relations[i]; - auto node = set_manager.GetJoinRelation(i); - plans[node] = make_unique(node, rel.op->EstimateCardinality(context)); - } - // now we perform the actual dynamic programming to compute the final result - SolveJoinOrder(); - // now the optimal join path should have been found - // get it from the node - unordered_set bindings; - for (idx_t i = 0; i < relations.size(); i++) { - bindings.insert(i); - } - auto total_relation = set_manager.GetJoinRelation(bindings); - auto final_plan = plans.find(total_relation); - if (final_plan == plans.end()) { - // could not find the final plan - // this should only happen in case the sets are actually disjunct - // in this case we need to generate cross product to connect the disjoint sets - GenerateCrossProducts(); - //! solve the join order again - SolveJoinOrder(); - // now we can obtain the final plan! - final_plan = plans.find(total_relation); - D_ASSERT(final_plan != plans.end()); - } - // now perform the actual reordering - return RewritePlan(move(plan), final_plan->second.get()); -} + unique_ptr Copy() const override; + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(ExpressionType type, FieldReader &source); +}; } // 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); +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)) { + vector dummy_columns; + context.TryBindRelation(*this, dummy_columns); } -bool InClauseExpressionMatcher::Match(Expression *expr_p, vector &bindings) { - if (!ExpressionMatcher::Match(expr_p, bindings)) { - return false; +unique_ptr FilterRelation::GetQueryNode() { + auto child_ptr = child.get(); + while (child_ptr->InheritsColumnBindings()) { + child_ptr = child_ptr->ChildRelation(); } - auto expr = (BoundOperatorExpression *)expr_p; - if (expr->type != ExpressionType::COMPARE_IN || expr->type == ExpressionType::COMPARE_NOT_IN) { - return false; + if (child_ptr->type == RelationType::JOIN_RELATION) { + // child node is a join: push filter into WHERE clause of select node + auto child_node = child->GetQueryNode(); + D_ASSERT(child_node->type == QueryNodeType::SELECT_NODE); + auto &select_node = (SelectNode &)*child_node; + if (!select_node.where_clause) { + select_node.where_clause = condition->Copy(); + } else { + select_node.where_clause = make_unique( + ExpressionType::CONJUNCTION_AND, move(select_node.where_clause), condition->Copy()); + } + return child_node; + } else { + auto result = make_unique(); + result->select_list.push_back(make_unique()); + result->from_table = child->GetTableRef(); + result->where_clause = condition->Copy(); + return move(result); } - 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; +string FilterRelation::GetAlias() { + return child->GetAlias(); } -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; +const vector &FilterRelation::Columns() { + return child->Columns(); } -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; +string FilterRelation::ToString(idx_t depth) { + string str = RenderWhitespace(depth) + "Filter [" + condition->ToString() + "]\n"; + return str + child->ToString(depth + 1); } } // namespace duckdb - - - - - - - - - - - - - //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/optimizer/regex_range_filter.hpp +// duckdb/main/relation/insert_relation.hpp // // //===----------------------------------------------------------------------===// @@ -110948,14 +115028,22 @@ bool FoldableConstantMatcher::Match(Expression *expr, vector &bind namespace duckdb { -class Optimizer; +class InsertRelation : public Relation { +public: + InsertRelation(shared_ptr child, string schema_name, string table_name); + + shared_ptr child; + string schema_name; + string table_name; + vector columns; -class RegexRangeFilter { public: - RegexRangeFilter() { + BoundStatement Bind(Binder &binder) override; + const vector &Columns() override; + string ToString(idx_t depth) override; + bool IsReadOnly() override { + return false; } - //! Perform filter pushdown - unique_ptr Rewrite(unique_ptr op); }; } // namespace duckdb @@ -110963,7 +115051,7 @@ class RegexRangeFilter { //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/optimizer/remove_unused_columns.hpp +// duckdb/parser/statement/insert_statement.hpp // // //===----------------------------------------------------------------------===// @@ -110973,51 +115061,31 @@ class RegexRangeFilter { - namespace duckdb { -class Binder; -class BoundColumnRefExpression; -class ClientContext; -//! The RemoveUnusedColumns optimizer traverses the logical operator tree and removes any columns that are not required -class RemoveUnusedColumns : public LogicalOperatorVisitor { +class InsertStatement : public SQLStatement { public: - RemoveUnusedColumns(Binder &binder, ClientContext &context, bool is_root = false) - : binder(binder), context(context), everything_referenced(is_root) { - } - - void VisitOperator(LogicalOperator &op) override; + InsertStatement(); -protected: - unique_ptr VisitReplace(BoundColumnRefExpression &expr, unique_ptr *expr_ptr) override; - unique_ptr VisitReplace(BoundReferenceExpression &expr, unique_ptr *expr_ptr) override; + //! The select statement to insert from + unique_ptr select_statement; + //! Column names to insert into + vector columns; -private: - Binder &binder; - ClientContext &context; - //! 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 map of column references - column_binding_map_t> column_references; + //! Table name to insert to + string table; + //! Schema name to insert to + string schema; -private: - template - void ClearUnusedExpressions(vector &list, idx_t table_idx); +protected: + InsertStatement(const InsertStatement &other); - //! Perform a replacement of the ColumnBinding, iterating over all the currently found column references and - //! replacing the bindings - void ReplaceBinding(ColumnBinding current_binding, ColumnBinding new_binding); +public: + unique_ptr Copy() const override; }; + } // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/optimizer/rule/arithmetic_simplification.hpp -// -// -//===----------------------------------------------------------------------===// @@ -111025,22 +115093,37 @@ class RemoveUnusedColumns : public LogicalOperatorVisitor { namespace duckdb { -// The Arithmetic Simplification rule applies arithmetic expressions to which the answer is known (e.g. X + 0 => X, X * -// 0 => 0) -class ArithmeticSimplificationRule : public Rule { -public: - explicit ArithmeticSimplificationRule(ExpressionRewriter &rewriter); +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)) { + context.TryBindRelation(*this, this->columns); +} - unique_ptr Apply(LogicalOperator &op, vector &bindings, bool &changes_made, - bool is_root) override; -}; +BoundStatement InsertRelation::Bind(Binder &binder) { + InsertStatement stmt; + auto select = make_unique(); + select->node = child->GetQueryNode(); -} // namespace duckdb + stmt.schema = schema_name; + stmt.table = table_name; + stmt.select_statement = move(select); + return binder.Bind((SQLStatement &)stmt); +} + +const vector &InsertRelation::Columns() { + return columns; +} + +string InsertRelation::ToString(idx_t depth) { + string str = RenderWhitespace(depth) + "Insert\n"; + return str + child->ToString(depth + 1); +} +} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/optimizer/rule/case_simplification.hpp +// duckdb/main/relation/join_relation.hpp // // //===----------------------------------------------------------------------===// @@ -111051,46 +115134,37 @@ class ArithmeticSimplificationRule : public Rule { namespace duckdb { -// The Case Simplification rule rewrites cases with a constant check (i.e. [CASE WHEN 1=1 THEN x ELSE y END] => x) -class CaseSimplificationRule : public Rule { +class JoinRelation : public Relation { public: - explicit CaseSimplificationRule(ExpressionRewriter &rewriter); - - unique_ptr Apply(LogicalOperator &op, vector &bindings, bool &changes_made, - bool is_root) override; -}; - -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/optimizer/rule/comparison_simplification.hpp -// -// -//===----------------------------------------------------------------------===// + JoinRelation(shared_ptr left, shared_ptr right, unique_ptr condition, + JoinType type); + JoinRelation(shared_ptr left, shared_ptr right, vector using_columns, JoinType type); + shared_ptr left; + shared_ptr right; + unique_ptr condition; + vector using_columns; + JoinType join_type; + vector columns; +public: + unique_ptr GetQueryNode() override; + const vector &Columns() override; + string ToString(idx_t depth) override; + unique_ptr GetTableRef() override; +}; -namespace duckdb { +} // namespace duckdb -// The Comparison Simplification rule rewrites comparisons with a constant NULL (i.e. [x = NULL] => [NULL]) -class ComparisonSimplificationRule : public Rule { -public: - explicit ComparisonSimplificationRule(ExpressionRewriter &rewriter); - unique_ptr Apply(LogicalOperator &op, vector &bindings, bool &changes_made, - bool is_root) override; -}; -} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/optimizer/rule/conjunction_simplification.hpp +// duckdb/parser/tableref/joinref.hpp // // //===----------------------------------------------------------------------===// @@ -111099,50 +115173,99 @@ class ComparisonSimplificationRule : public Rule { + + + + 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; -// The Conjunction Simplification rule rewrites conjunctions with a constant -class ConjunctionSimplificationRule : public Rule { public: - explicit ConjunctionSimplificationRule(ExpressionRewriter &rewriter); + bool Equals(const TableRef *other_p) const override; - unique_ptr Apply(LogicalOperator &op, vector &bindings, bool &changes_made, - bool is_root) override; + unique_ptr Copy() override; - unique_ptr RemoveExpression(BoundConjunctionExpression &conj, Expression *expr); + //! 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 -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/optimizer/rule/constant_folding.hpp -// -// -//===----------------------------------------------------------------------===// +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) { + if (&left->context != &right->context) { + throw Exception("Cannot combine LEFT and RIGHT relations of different connections!"); + } + context.TryBindRelation(*this, this->columns); +} +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) { + if (&left->context != &right->context) { + throw Exception("Cannot combine LEFT and RIGHT relations of different connections!"); + } + context.TryBindRelation(*this, this->columns); +} +unique_ptr JoinRelation::GetQueryNode() { + auto result = make_unique(); + result->select_list.push_back(make_unique()); + result->from_table = GetTableRef(); + return move(result); +} -namespace duckdb { +unique_ptr JoinRelation::GetTableRef() { + auto join_ref = make_unique(); + join_ref->left = left->GetTableRef(); + join_ref->right = right->GetTableRef(); + if (condition) { + join_ref->condition = condition->Copy(); + } + join_ref->using_columns = using_columns; + join_ref->type = join_type; + return move(join_ref); +} -// Fold any constant scalar expressions into a single constant (i.e. [2 + 2] => [4], [2 = 2] => [True], etc...) -class ConstantFoldingRule : public Rule { -public: - explicit ConstantFoldingRule(ExpressionRewriter &rewriter); +const vector &JoinRelation::Columns() { + return this->columns; +} - unique_ptr Apply(LogicalOperator &op, vector &bindings, bool &changes_made, - bool is_root) override; -}; +string JoinRelation::ToString(idx_t depth) { + string str = RenderWhitespace(depth); + str = "Join " + JoinTypeToString(join_type); + return str + "\n" + left->ToString(depth + 1) + "\n" + right->ToString(depth + 1); +} } // namespace duckdb - //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/optimizer/rule/date_part_simplification.hpp +// duckdb/main/relation/limit_relation.hpp // // //===----------------------------------------------------------------------===// @@ -111153,26 +115276,32 @@ class ConstantFoldingRule : public Rule { namespace duckdb { -// The DatePart Simplification rule rewrites date_part with a constant specifier into a specialized function (e.g. -// date_part('year', x) => year(x)) -class DatePartSimplificationRule : public Rule { +class LimitRelation : public Relation { public: - explicit DatePartSimplificationRule(ExpressionRewriter &rewriter); + LimitRelation(shared_ptr child, int64_t limit, int64_t offset); - unique_ptr Apply(LogicalOperator &op, vector &bindings, bool &changes_made, - bool is_root) override; + int64_t limit; + int64_t offset; + shared_ptr child; + +public: + unique_ptr GetQueryNode() override; + + const vector &Columns() override; + string ToString(idx_t depth) override; + string GetAlias() override; + +public: + bool InheritsColumnBindings() override { + return true; + } + Relation *ChildRelation() override { + return child.get(); + } }; } // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/optimizer/rule/distributivity.hpp -// -// -//===----------------------------------------------------------------------===// - @@ -111180,25 +115309,47 @@ class DatePartSimplificationRule : public Rule { namespace duckdb { -// (X AND B) OR (X AND C) OR (X AND D) = X AND (B OR C OR D) -class DistributivityRule : public Rule { -public: - explicit DistributivityRule(ExpressionRewriter &rewriter); +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)) { +} - unique_ptr Apply(LogicalOperator &op, vector &bindings, bool &changes_made, - bool is_root) override; +unique_ptr LimitRelation::GetQueryNode() { + auto child_node = child->GetQueryNode(); + auto limit_node = make_unique(); + if (limit >= 0) { + limit_node->limit = make_unique(Value::BIGINT(limit)); + } + if (offset > 0) { + limit_node->offset = make_unique(Value::BIGINT(offset)); + } -private: - void AddExpressionSet(Expression &expr, expression_set_t &set); - unique_ptr ExtractExpression(BoundConjunctionExpression &conj, idx_t idx, Expression &expr); -}; + child_node->modifiers.push_back(move(limit_node)); + return child_node; +} -} // namespace duckdb +string LimitRelation::GetAlias() { + return child->GetAlias(); +} + +const vector &LimitRelation::Columns() { + return child->Columns(); +} + +string LimitRelation::ToString(idx_t depth) { + string str = RenderWhitespace(depth) + "Limit " + to_string(limit); + if (offset > 0) { + str += " Offset " + to_string(offset); + } + str += "\n"; + return str + child->ToString(depth + 1); +} +} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/optimizer/rule/empty_needle_removal.hpp +// duckdb/main/relation/order_relation.hpp // // //===----------------------------------------------------------------------===// @@ -111207,53 +115358,82 @@ class DistributivityRule : public Rule { + + namespace duckdb { -// The Empty_needle_removal Optimization rule folds some foldable ConstantExpression -//(e.g.: PREFIX('xyz', '') is TRUE, PREFIX(NULL, '') is NULL, so rewrite PREFIX(x, '') to (CASE WHEN x IS NOT NULL THEN) -class EmptyNeedleRemovalRule : public Rule { +class OrderRelation : public Relation { public: - explicit EmptyNeedleRemovalRule(ExpressionRewriter &rewriter); + OrderRelation(shared_ptr child, vector orders); - unique_ptr Apply(LogicalOperator &op, vector &bindings, bool &changes_made, - bool is_root) override; -}; + vector orders; + shared_ptr child; -} // namespace duckdb +public: + unique_ptr GetQueryNode() override; -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/optimizer/rule/like_optimizations.hpp -// -// -//===----------------------------------------------------------------------===// + const vector &Columns() override; + string ToString(idx_t depth) override; + string GetAlias() override; +public: + bool InheritsColumnBindings() override { + return true; + } + Relation *ChildRelation() override { + return child.get(); + } +}; +} // namespace duckdb namespace duckdb { -// The Like Optimization rule rewrites LIKE to optimized scalar functions (e.g.: prefix, suffix, and contains) -class LikeOptimizationRule : public Rule { -public: - explicit LikeOptimizationRule(ExpressionRewriter &rewriter); +OrderRelation::OrderRelation(shared_ptr child_p, vector orders) + : Relation(child_p->context, RelationType::ORDER_RELATION), orders(move(orders)), child(move(child_p)) { + // bind the expressions + vector dummy_columns; + context.TryBindRelation(*this, dummy_columns); +} - unique_ptr Apply(LogicalOperator &op, vector &bindings, bool &changes_made, - bool is_root) override; +unique_ptr OrderRelation::GetQueryNode() { + auto child_node = child->GetQueryNode(); + auto order_node = make_unique(); + 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()); + } + child_node->modifiers.push_back(move(order_node)); + return child_node; +} - unique_ptr ApplyRule(BoundFunctionExpression *expr, ScalarFunction function, string pattern, - bool is_not_like); -}; +string OrderRelation::GetAlias() { + return child->GetAlias(); +} -} // namespace duckdb +const vector &OrderRelation::Columns() { + return child->Columns(); +} + +string OrderRelation::ToString(idx_t depth) { + string str = RenderWhitespace(depth) + "Order ["; + for (idx_t i = 0; i < orders.size(); i++) { + if (i != 0) { + str += ", "; + } + str += orders[i].expression->ToString() + (orders[i].type == OrderType::ASCENDING ? " ASC" : " DESC"); + } + str += "]\n"; + return str + child->ToString(depth + 1); +} +} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/optimizer/rule/move_constants.hpp +// duckdb/main/relation/projection_relation.hpp // // //===----------------------------------------------------------------------===// @@ -111262,58 +115442,96 @@ class LikeOptimizationRule : public Rule { + namespace duckdb { -// The MoveConstantsRule moves constants to the same side of an expression, e.g. if we have an expression x + 1 = 5000 -// then this will turn it into x = 4999. -class MoveConstantsRule : public Rule { +class ProjectionRelation : public Relation { public: - explicit MoveConstantsRule(ExpressionRewriter &rewriter); + ProjectionRelation(shared_ptr child, vector> expressions, + vector aliases); - unique_ptr Apply(LogicalOperator &op, vector &bindings, bool &changes_made, - bool is_root) override; + vector> expressions; + vector columns; + shared_ptr child; + +public: + unique_ptr GetQueryNode() override; + + const vector &Columns() override; + string ToString(idx_t depth) override; + string GetAlias() override; }; } // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/optimizer/rule/enum_comparison.hpp -// -// -//===----------------------------------------------------------------------===// - namespace duckdb { -// The Enum Comparison rule rewrites cases where two Enums are compared on an equality check -class EnumComparisonRule : public Rule { -public: - explicit EnumComparisonRule(ExpressionRewriter &rewriter); - - unique_ptr Apply(LogicalOperator &op, vector &bindings, bool &changes_made, - bool is_root) override; -}; - -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/optimizer/statistics_propagator.hpp -// -// -//===----------------------------------------------------------------------===// - +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)) { + if (!aliases.empty()) { + if (aliases.size() != expressions.size()) { + throw ParserException("Aliases list length must match expression list length!"); + } + for (idx_t i = 0; i < aliases.size(); i++) { + expressions[i]->alias = aliases[i]; + } + } + // bind the expressions + context.TryBindRelation(*this, this->columns); +} +unique_ptr ProjectionRelation::GetQueryNode() { + auto child_ptr = child.get(); + while (child_ptr->InheritsColumnBindings()) { + child_ptr = child_ptr->ChildRelation(); + } + unique_ptr result; + if (child_ptr->type == RelationType::JOIN_RELATION) { + // child node is a join: push projection into the child query node + result = child->GetQueryNode(); + } else { + // 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); + } + D_ASSERT(result->type == QueryNodeType::SELECT_NODE); + auto &select_node = (SelectNode &)*result; + select_node.aggregate_handling = AggregateHandling::NO_AGGREGATES_ALLOWED; + select_node.select_list.clear(); + for (auto &expr : expressions) { + select_node.select_list.push_back(expr->Copy()); + } + return result; +} +string ProjectionRelation::GetAlias() { + return child->GetAlias(); +} +const vector &ProjectionRelation::Columns() { + return columns; +} +string ProjectionRelation::ToString(idx_t depth) { + string str = RenderWhitespace(depth) + "Projection ["; + for (idx_t i = 0; i < expressions.size(); i++) { + if (i != 0) { + str += ", "; + } + str += expressions[i]->ToString(); + } + str += "]\n"; + return str + child->ToString(depth + 1); +} +} // namespace duckdb @@ -111321,124 +115539,125 @@ class EnumComparisonRule : public Rule { namespace duckdb { -class ClientContext; -class LogicalOperator; -class TableFilter; -struct BoundOrderByNode; - -class StatisticsPropagator { -public: - explicit StatisticsPropagator(ClientContext &context); - unique_ptr PropagateStatistics(unique_ptr &node_ptr); +QueryRelation::QueryRelation(ClientContext &context, unique_ptr select_stmt_p, string alias_p) + : Relation(context, RelationType::QUERY_RELATION), select_stmt(move(select_stmt_p)), alias(move(alias_p)) { + context.TryBindRelation(*this, this->columns); +} -private: - //! Propagate statistics through an operator - unique_ptr PropagateStatistics(LogicalOperator &node, unique_ptr *node_ptr); +QueryRelation::~QueryRelation() { +} - 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); +unique_ptr QueryRelation::ParseStatement(ClientContext &context, const string &query, + const string &error) { + Parser parser(context.GetParserOptions()); + parser.ParseQuery(query); + if (parser.statements.size() != 1) { + throw ParserException(error); + } + if (parser.statements[0]->type != StatementType::SELECT_STATEMENT) { + throw ParserException(error); + } + return unique_ptr_cast(move(parser.statements[0])); +} - unique_ptr PropagateChildren(LogicalOperator &node, unique_ptr *node_ptr); +unique_ptr QueryRelation::GetSelectStatement() { + return unique_ptr_cast(select_stmt->Copy()); +} - //! 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); +unique_ptr QueryRelation::GetQueryNode() { + auto select = GetSelectStatement(); + return move(select->node); +} - //! 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); +unique_ptr QueryRelation::GetTableRef() { + auto subquery_ref = make_unique(GetSelectStatement(), GetAlias()); + return move(subquery_ref); +} - //! 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); +string QueryRelation::GetAlias() { + return alias; +} - //! 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); +const vector &QueryRelation::Columns() { + return columns; +} - unique_ptr PropagateExpression(unique_ptr &expr); - unique_ptr PropagateExpression(Expression &expr, unique_ptr *expr_ptr); +string QueryRelation::ToString(idx_t depth) { + return RenderWhitespace(depth) + "Subquery"; +} - 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(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); +} // namespace duckdb - 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 -// -// duckdb/optimizer/topn_optimizer.hpp -// -// -//===----------------------------------------------------------------------===// namespace duckdb { -class LogicalOperator; -class Optimizer; -class TopN { -public: - //! Optimize ORDER BY + LIMIT to TopN - unique_ptr Optimize(unique_ptr op); -}; +ReadCSVRelation::ReadCSVRelation(ClientContext &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)) { + if (alias.empty()) { + alias = StringUtil::Split(csv_file, ".")[0]; + } +} -} // namespace duckdb +unique_ptr ReadCSVRelation::GetQueryNode() { + auto result = make_unique(); + result->select_list.push_back(make_unique()); + result->from_table = GetTableRef(); + return move(result); +} + +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)))); + } + table_ref->function = make_unique("read_csv", move(children)); + return move(table_ref); +} +string ReadCSVRelation::GetAlias() { + return alias; +} +const vector &ReadCSVRelation::Columns() { + return columns; +} +string ReadCSVRelation::ToString(idx_t depth) { + return RenderWhitespace(depth) + "Read CSV [" + csv_file + "]"; +} +} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/optimizer/rule/in_clause_simplification.hpp +// duckdb/main/relation/setop_relation.hpp // // //===----------------------------------------------------------------------===// @@ -111447,157 +115666,141 @@ class TopN { + namespace duckdb { -// The in clause simplification rule rewrites cases where left is a column ref with a cast and right are constant values -class InClauseSimplificationRule : public Rule { +class SetOpRelation : public Relation { public: - explicit InClauseSimplificationRule(ExpressionRewriter &rewriter); + SetOpRelation(shared_ptr left, shared_ptr right, SetOperationType setop_type); - unique_ptr Apply(LogicalOperator &op, vector &bindings, bool &changes_made, - bool is_root) override; + shared_ptr left; + shared_ptr right; + SetOperationType setop_type; + +public: + unique_ptr GetQueryNode() override; + + const vector &Columns() override; + string ToString(idx_t depth) override; + string GetAlias() override; }; } // namespace duckdb -namespace duckdb { -Optimizer::Optimizer(Binder &binder, ClientContext &context) : context(context), binder(binder), rewriter(context) { - rewriter.rules.push_back(make_unique(rewriter)); - rewriter.rules.push_back(make_unique(rewriter)); - rewriter.rules.push_back(make_unique(rewriter)); - rewriter.rules.push_back(make_unique(rewriter)); - rewriter.rules.push_back(make_unique(rewriter)); - rewriter.rules.push_back(make_unique(rewriter)); - rewriter.rules.push_back(make_unique(rewriter)); - rewriter.rules.push_back(make_unique(rewriter)); - rewriter.rules.push_back(make_unique(rewriter)); - rewriter.rules.push_back(make_unique(rewriter)); - rewriter.rules.push_back(make_unique(rewriter)); - rewriter.rules.push_back(make_unique(rewriter)); -#ifdef DEBUG - for (auto &rule : rewriter.rules) { - // root not defined in rule - D_ASSERT(rule->root); - } -#endif -} +namespace duckdb { -void Optimizer::RunOptimizer(OptimizerType type, const std::function &callback) { - auto &config = DBConfig::GetConfig(context); - if (config.disabled_optimizers.find(type) != config.disabled_optimizers.end()) { - // optimizer is marked as disabled: skip - return; +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) { + if (&left->context != &right->context) { + throw Exception("Cannot combine LEFT and RIGHT relations of different connections!"); } - context.profiler->StartPhase(OptimizerTypeToString(type)); - callback(); - context.profiler->EndPhase(); + vector dummy_columns; + context.TryBindRelation(*this, dummy_columns); } -unique_ptr Optimizer::Optimize(unique_ptr plan) { - // 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); }); +unique_ptr SetOpRelation::GetQueryNode() { + auto result = make_unique(); + result->left = left->GetQueryNode(); + result->right = right->GetQueryNode(); + result->setop_type = setop_type; + return move(result); +} - // perform filter pullup - RunOptimizer(OptimizerType::FILTER_PULLUP, [&]() { - FilterPullup filter_pullup; - plan = filter_pullup.Rewrite(move(plan)); - }); +string SetOpRelation::GetAlias() { + return left->GetAlias(); +} - // perform filter pushdown - RunOptimizer(OptimizerType::FILTER_PUSHDOWN, [&]() { - FilterPushdown filter_pushdown(*this); - plan = filter_pushdown.Rewrite(move(plan)); - }); +const vector &SetOpRelation::Columns() { + return left->Columns(); +} - RunOptimizer(OptimizerType::REGEX_RANGE, [&]() { - RegexRangeFilter regex_opt; - plan = regex_opt.Rewrite(move(plan)); - }); +string SetOpRelation::ToString(idx_t depth) { + string str = RenderWhitespace(depth); + switch (setop_type) { + case SetOperationType::UNION: + str += "Union"; + break; + case SetOperationType::EXCEPT: + str += "Except"; + break; + case SetOperationType::INTERSECT: + str += "Intersect"; + break; + default: + throw InternalException("Unknown setop type"); + } + return str + "\n" + left->ToString(depth + 1) + right->ToString(depth + 1); +} - RunOptimizer(OptimizerType::IN_CLAUSE, [&]() { - InClauseRewriter rewriter(*this); - plan = rewriter.Rewrite(move(plan)); - }); +} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/relation/subquery_relation.hpp +// +// +//===----------------------------------------------------------------------===// - // 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)); - }); - // removes any redundant DelimGets/DelimJoins - RunOptimizer(OptimizerType::DELIMINATOR, [&]() { - Deliminator deliminator; - plan = deliminator.Optimize(move(plan)); - }); - RunOptimizer(OptimizerType::UNUSED_COLUMNS, [&]() { - RemoveUnusedColumns unused(binder, context, true); - unused.VisitOperator(*plan); - }); - // perform statistics propagation - RunOptimizer(OptimizerType::STATISTICS_PROPAGATION, [&]() { - StatisticsPropagator propagator(context); - propagator.PropagateStatistics(plan); - }); - // then we extract common subexpressions inside the different operators - RunOptimizer(OptimizerType::COMMON_SUBEXPRESSIONS, [&]() { - CommonSubExpressionOptimizer cse_optimizer(binder); - cse_optimizer.VisitOperator(*plan); - }); +namespace duckdb { - RunOptimizer(OptimizerType::COMMON_AGGREGATE, [&]() { - CommonAggregateOptimizer common_aggregate; - common_aggregate.VisitOperator(*plan); - }); +class SubqueryRelation : public Relation { +public: + SubqueryRelation(shared_ptr child, string alias); - RunOptimizer(OptimizerType::COLUMN_LIFETIME, [&]() { - ColumnLifetimeAnalyzer column_lifetime(true); - column_lifetime.VisitOperator(*plan); - }); + shared_ptr child; + string alias; - // transform ORDER BY + LIMIT to TopN - RunOptimizer(OptimizerType::TOP_N, [&]() { - TopN topn; - plan = topn.Optimize(move(plan)); - }); +public: + unique_ptr GetQueryNode() override; - // apply simple expression heuristics to get an initial reordering - RunOptimizer(OptimizerType::REORDER_FILTER, [&]() { - ExpressionHeuristics expression_heuristics(*this); - plan = expression_heuristics.Rewrite(move(plan)); - }); + const vector &Columns() override; + string ToString(idx_t depth) override; + string GetAlias() override; - return plan; -} +public: + bool InheritsColumnBindings() override { + return child->InheritsColumnBindings(); + } + Relation *ChildRelation() override { + return child->ChildRelation(); + } +}; } // namespace duckdb + + 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])); +SubqueryRelation::SubqueryRelation(shared_ptr child_p, string alias_p) + : Relation(child_p->context, RelationType::SUBQUERY_RELATION), child(move(child_p)), alias(move(alias_p)) { + vector dummy_columns; + context.TryBindRelation(*this, dummy_columns); +} - // 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])); - } +unique_ptr SubqueryRelation::GetQueryNode() { + return child->GetQueryNode(); +} - if (!left_pullup.filters_expr_pullup.empty()) { - return GeneratePullupFilter(move(op), left_pullup.filters_expr_pullup); - } - return op; +string SubqueryRelation::GetAlias() { + return alias; +} + +const vector &SubqueryRelation::Columns() { + return child->Columns(); +} + +string SubqueryRelation::ToString(idx_t depth) { + return child->ToString(depth); } } // namespace duckdb @@ -111607,51 +115810,56 @@ unique_ptr FilterPullup::PullupBothSide(unique_ptr FilterPullup::PullupFilter(unique_ptr op) { - D_ASSERT(op->type == LogicalOperatorType::LOGICAL_FILTER); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/expression/subquery_expression.hpp +// +// +//===----------------------------------------------------------------------===// - if (can_pullup) { - unique_ptr child = move(op->children[0]); - child = Rewrite(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])); - } - return child; - } - op->children[0] = Rewrite(move(op->children[0])); - return op; -} -} // namespace duckdb -namespace duckdb { -unique_ptr FilterPullup::PullupFromLeft(unique_ptr op) { - D_ASSERT(op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN || - op->type == LogicalOperatorType::LOGICAL_ANY_JOIN || op->type == LogicalOperatorType::LOGICAL_EXCEPT); +namespace duckdb { - FilterPullup left_pullup(true, can_add_column); - FilterPullup right_pullup(false, can_add_column); +//! Represents a subquery +class SubqueryExpression : public ParsedExpression { +public: + SubqueryExpression(); - op->children[0] = left_pullup.Rewrite(move(op->children[0])); - op->children[1] = right_pullup.Rewrite(move(op->children[1])); + //! The actual subquery + unique_ptr subquery; + //! The subquery type + SubqueryType subquery_type; + //! the child expression to compare with (in case of IN, ANY, ALL operators, empty for EXISTS queries and scalar + //! subquery) + unique_ptr child; + //! The comparison type of the child expression with the subquery (in case of ANY, ALL operators), empty otherwise + ExpressionType comparison_type; - // 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); +public: + bool HasSubquery() const override { + return true; + } + bool IsScalar() const override { + return false; } - return op; -} -} // namespace duckdb + string ToString() const override; + + static bool Equals(const SubqueryExpression *a, const SubqueryExpression *b); + unique_ptr Copy() const override; + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(ExpressionType type, FieldReader &source); +}; +} // namespace duckdb @@ -111659,92 +115867,76 @@ unique_ptr FilterPullup::PullupFromLeft(unique_ptr> &expressions) { - unique_ptr filter = make_unique(); - for (idx_t i = 0; i < expressions.size(); ++i) { - filter->expressions.push_back(move(expressions[i])); - } - expressions.clear(); - filter->children.push_back(move(proj.children[0])); - proj.children[0] = move(filter); +TableFunctionRelation::TableFunctionRelation(ClientContext &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); } +TableFunctionRelation::TableFunctionRelation(ClientContext &context, string name_p, vector parameters_p, -static void ReplaceExpressionBinding(vector> &proj_expressions, Expression &expr, - idx_t proj_table_idx) { - if (expr.type == ExpressionType::BOUND_COLUMN_REF) { - bool found_proj_col = false; - BoundColumnRefExpression &colref = (BoundColumnRefExpression &)expr; - // find the corresponding column index in the projection expressions - for (idx_t proj_idx = 0; proj_idx < proj_expressions.size(); proj_idx++) { - auto proj_expr = proj_expressions[proj_idx].get(); - if (proj_expr->type == ExpressionType::BOUND_COLUMN_REF) { - if (colref.Equals(proj_expr)) { - colref.binding.table_index = proj_table_idx; - colref.binding.column_index = proj_idx; - found_proj_col = true; - break; - } - } - } - if (!found_proj_col) { - // Project a new column - 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)); - } - } - ExpressionIterator::EnumerateChildren( - expr, [&](Expression &child) { return ReplaceExpressionBinding(proj_expressions, child, proj_table_idx); }); + 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 FilterPullup::ProjectSetOperation(LogicalProjection &proj) { - vector> copy_proj_expressions; - // copying the project expressions, it's useful whether we should revert the filter pullup - for (idx_t i = 0; i < proj.expressions.size(); ++i) { - copy_proj_expressions.push_back(proj.expressions[i]->Copy()); - } +unique_ptr TableFunctionRelation::GetQueryNode() { + auto result = make_unique(); + result->select_list.push_back(make_unique()); + result->from_table = GetTableRef(); + return move(result); +} - // Replace filter expression bindings, when need we add new columns into the copied projection expression - vector> changed_filter_expressions; - 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)); +unique_ptr TableFunctionRelation::GetTableRef() { + vector> children; + if (input_relation) { // input relation becomes first parameter if present, always + auto subquery = make_unique(); + subquery->subquery = make_unique(); + subquery->subquery->node = input_relation->GetQueryNode(); + subquery->subquery_type = SubqueryType::SCALAR; + children.push_back(move(subquery)); } - - /// Case new columns were added into the projection - // we must skip filter pullup because adding new columns to these operators will change the result - if (copy_proj_expressions.size() > proj.expressions.size()) { - RevertFilterPullup(proj, filters_expr_pullup); - return; + for (auto ¶meter : parameters) { + children.push_back(make_unique(parameter)); } - // 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]); + for (auto ¶meter : named_parameters) { + // Hackity-hack some comparisons with column refs + // This is all but pretty, basically the named parameter is the column, the table is empty because that's what + // 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 table_function = make_unique(); + auto function = make_unique(name, move(children)); + table_function->function = move(function); + return move(table_function); } -unique_ptr FilterPullup::PullupProjection(unique_ptr op) { - D_ASSERT(op->type == LogicalOperatorType::LOGICAL_PROJECTION); - op->children[0] = Rewrite(move(op->children[0])); - if (!filters_expr_pullup.empty()) { - auto &proj = (LogicalProjection &)*op; - // INTERSECT, EXCEPT, and DISTINCT - if (!can_add_column) { - // special treatment for operators that cannot add columns, e.g., INTERSECT, EXCEPT, and DISTINCT - ProjectSetOperation(proj); - return op; - } +string TableFunctionRelation::GetAlias() { + return name; +} - for (idx_t i = 0; i < filters_expr_pullup.size(); ++i) { - auto &expr = (Expression &)*filters_expr_pullup[i]; - ReplaceExpressionBinding(proj.expressions, expr, proj.table_index); +const vector &TableFunctionRelation::Columns() { + return columns; +} + +string TableFunctionRelation::ToString(idx_t depth) { + string function_call = name + "("; + for (idx_t i = 0; i < parameters.size(); i++) { + if (i > 0) { + function_call += ", "; } + function_call += parameters[i].ToString(); } - return op; + function_call += ")"; + return RenderWhitespace(depth) + function_call; } } // namespace duckdb @@ -111753,289 +115945,321 @@ unique_ptr FilterPullup::PullupProjection(unique_ptr FilterPullup::PullupSetOperation(unique_ptr op) { - D_ASSERT(op->type == LogicalOperatorType::LOGICAL_INTERSECT || op->type == LogicalOperatorType::LOGICAL_EXCEPT); - can_add_column = false; - can_pullup = true; - if (op->type == LogicalOperatorType::LOGICAL_INTERSECT) { - op = PullupBothSide(move(op)); - } else { - // EXCEPT only pull ups from LHS - op = PullupFromLeft(move(op)); - } - if (op->type == LogicalOperatorType::LOGICAL_FILTER) { - auto &filter = (LogicalFilter &)*op; - auto &setop = (LogicalSetOperation &)*filter.children[0]; - for (idx_t i = 0; i < filter.expressions.size(); ++i) { - ReplaceFilterTableIndex(*filter.expressions[i], setop); - } - } - return op; -} -} // namespace duckdb +namespace duckdb { + +class UpdateRelation : public Relation { +public: + UpdateRelation(ClientContext &context, unique_ptr condition, string schema_name, + string table_name, vector update_columns, vector> expressions); + + vector columns; + unique_ptr condition; + string schema_name; + string table_name; + vector update_columns; + vector> expressions; + +public: + BoundStatement Bind(Binder &binder) override; + const vector &Columns() override; + string ToString(idx_t depth) override; + bool IsReadOnly() override { + return false; + } +}; +} // namespace duckdb namespace duckdb { -using Filter = FilterPushdown::Filter; +TableRelation::TableRelation(ClientContext &context, unique_ptr description) + : Relation(context, RelationType::TABLE_RELATION), description(move(description)) { +} -static unique_ptr ReplaceGroupBindings(LogicalAggregate &proj, unique_ptr expr) { - if (expr->type == ExpressionType::BOUND_COLUMN_REF) { - auto &colref = (BoundColumnRefExpression &)*expr; - D_ASSERT(colref.binding.table_index == proj.group_index); - D_ASSERT(colref.binding.column_index < proj.groups.size()); - D_ASSERT(colref.depth == 0); - // replace the binding with a copy to the expression at the referenced index - return proj.groups[colref.binding.column_index]->Copy(); - } - ExpressionIterator::EnumerateChildren( - *expr, [&](unique_ptr &child) { child = ReplaceGroupBindings(proj, move(child)); }); - return expr; +unique_ptr TableRelation::GetQueryNode() { + auto result = make_unique(); + result->select_list.push_back(make_unique()); + result->from_table = GetTableRef(); + return move(result); } -unique_ptr FilterPushdown::PushdownAggregate(unique_ptr op) { - D_ASSERT(op->type == LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY); - auto &aggr = (LogicalAggregate &)*op; +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); +} - // pushdown into AGGREGATE and GROUP BY - // we cannot push expressions that refer to the aggregate - FilterPushdown child_pushdown(optimizer); - for (idx_t i = 0; i < filters.size(); i++) { - auto &f = *filters[i]; - // check if any aggregate or GROUPING functions are in the set - if (f.bindings.find(aggr.aggregate_index) == f.bindings.end() && - f.bindings.find(aggr.groupings_index) == f.bindings.end()) { - // no aggregate! we can push this down - // rewrite any group bindings within the filter - f.filter = ReplaceGroupBindings(aggr, move(f.filter)); - // add the filter to the child node - if (child_pushdown.AddFilter(move(f.filter)) == FilterResult::UNSATISFIABLE) { - // filter statically evaluates to false, strip tree - return make_unique(move(op)); - } - // erase the filter from here - filters.erase(filters.begin() + i); - i--; +string TableRelation::GetAlias() { + return description->table; +} + +const vector &TableRelation::Columns() { + return description->columns; +} + +string TableRelation::ToString(idx_t depth) { + return RenderWhitespace(depth) + "Scan Table [" + description->table + "]"; +} + +static unique_ptr ParseCondition(ClientContext &context, const string &condition) { + if (!condition.empty()) { + auto expression_list = Parser::ParseExpressionList(condition, context.GetParserOptions()); + if (expression_list.size() != 1) { + throw ParserException("Expected a single expression as filter condition"); } + return move(expression_list[0]); + } else { + return nullptr; } - child_pushdown.GenerateFilters(); +} - op->children[0] = child_pushdown.Rewrite(move(op->children[0])); - return FinishPushdown(move(op)); +void TableRelation::Update(const string &update_list, const string &condition) { + vector update_columns; + vector> expressions; + auto cond = ParseCondition(context, condition); + Parser::ParseUpdateList(update_list, update_columns, expressions, context.GetParserOptions()); + auto update = make_shared(context, move(cond), description->schema, description->table, + move(update_columns), move(expressions)); + update->Execute(); +} + +void TableRelation::Delete(const string &condition) { + auto cond = ParseCondition(context, condition); + auto del = make_shared(context, move(cond), description->schema, description->table); + del->Execute(); } } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/statement/update_statement.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + namespace duckdb { -using Filter = FilterPushdown::Filter; +class UpdateStatement : public SQLStatement { +public: + UpdateStatement(); -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; - unordered_set left_bindings, right_bindings; - if (!filters.empty()) { - // check to see into which side we should push the filters - // first get the LHS and RHS bindings - LogicalJoin::GetTableReferences(*op->children[0], left_bindings); - LogicalJoin::GetTableReferences(*op->children[1], right_bindings); - // now check the set of filters - for (auto &f : filters) { - auto side = JoinSide::GetJoinSide(f->bindings, left_bindings, right_bindings); - if (side == JoinSide::LEFT) { - // bindings match left side: push into left - left_pushdown.filters.push_back(move(f)); - } else if (side == JoinSide::RIGHT) { - // bindings match right side: push into right - right_pushdown.filters.push_back(move(f)); - } else { - D_ASSERT(side == JoinSide::BOTH); - // bindings match both: turn into join condition - join_conditions.push_back(move(f->filter)); - } - } - } + unique_ptr condition; + unique_ptr table; + unique_ptr from_table; + vector columns; + vector> expressions; - op->children[0] = left_pushdown.Rewrite(move(op->children[0])); - op->children[1] = right_pushdown.Rewrite(move(op->children[1])); +protected: + UpdateStatement(const UpdateStatement &other); - if (!join_conditions.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); - } else { - // no join conditions found: keep as cross product - return op; - } -} +public: + unique_ptr Copy() const override; +}; } // namespace duckdb -namespace duckdb { -using Filter = FilterPushdown::Filter; +namespace duckdb { -unique_ptr FilterPushdown::PushdownFilter(unique_ptr op) { - D_ASSERT(op->type == LogicalOperatorType::LOGICAL_FILTER); - auto &filter = (LogicalFilter &)*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) { - // filter statically evaluates to false, strip tree - return make_unique(move(op)); - } - } - GenerateFilters(); - return Rewrite(move(filter.children[0])); +UpdateRelation::UpdateRelation(ClientContext &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)) { + D_ASSERT(update_columns.size() == expressions.size()); + context.TryBindRelation(*this, this->columns); } -} // namespace duckdb +BoundStatement UpdateRelation::Bind(Binder &binder) { + auto basetable = make_unique(); + basetable->schema_name = schema_name; + basetable->table_name = table_name; + UpdateStatement stmt; + stmt.condition = condition ? condition->Copy() : nullptr; + stmt.table = move(basetable); + stmt.columns = update_columns; + for (auto &expr : expressions) { + stmt.expressions.push_back(expr->Copy()); + } + return binder.Bind((SQLStatement &)stmt); +} +const vector &UpdateRelation::Columns() { + return columns; +} +string UpdateRelation::ToString(idx_t depth) { + string str = RenderWhitespace(depth) + "UPDATE " + table_name + " SET\n"; + for (idx_t i = 0; i < expressions.size(); i++) { + str += update_columns[i] + " = " + expressions[i]->ToString() + "\n"; + } + if (condition) { + str += "WHERE " + condition->ToString() + "\n"; + } + return str; +} +} // namespace duckdb -namespace duckdb { +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/tableref/expressionlistref.hpp +// +// +//===----------------------------------------------------------------------===// -unique_ptr FilterPushdown::PushdownGet(unique_ptr op) { - D_ASSERT(op->type == LogicalOperatorType::LOGICAL_GET); - auto &get = (LogicalGet &)*op; - if (get.function.pushdown_complex_filter) { - // for the remaining filters, check if we can push any of them into the scan as well - vector> expressions; - for (auto &filter : filters) { - expressions.push_back(move(filter->filter)); - } - filters.clear(); - get.function.pushdown_complex_filter(optimizer.context, get, get.bind_data.get(), expressions); - if (expressions.empty()) { - return op; - } - // re-generate the filters - for (auto &expr : expressions) { - auto f = make_unique(); - f->filter = move(expr); - f->ExtractBindings(); - filters.push_back(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)); - } - PushFilters(); - //! We generate the table filters that will be executed during the table scan - //! Right now this only executes simple AND filters - get.table_filters = combiner.GenerateTableScanFilters(get.column_ids); - // //! For more complex filters if all filters to a column are constants we generate a min max boundary used to - // check - // //! the zonemaps. - // auto zonemap_checks = combiner.GenerateZonemapChecks(get.column_ids, get.table_filters); - // for (auto &f : get.table_filters) { - // f.column_index = get.column_ids[f.column_index]; - // } +namespace duckdb { +//! Represents an expression list as generated by a VALUES statement +class ExpressionListRef : public TableRef { +public: + ExpressionListRef() : TableRef(TableReferenceType::EXPRESSION_LIST) { + } - // //! Use zonemap checks as table filters for pre-processing - // for (auto &zonemap_check : zonemap_checks) { - // if (zonemap_check.column_index != COLUMN_IDENTIFIER_ROW_ID) { - // get.table_filters.push_back(zonemap_check); - // } - // } + //! Value list, only used for VALUES statement + vector>> values; + //! Expected SQL types + vector expected_types; + //! The set of expected names + vector expected_names; - GenerateFilters(); +public: + bool Equals(const TableRef *other_p) const override; - //! Now we try to pushdown the remaining filters to perform zonemap checking - return FinishPushdown(move(op)); -} + unique_ptr Copy() override; + //! Serializes a blob into a ExpressionListRef + void Serialize(FieldWriter &serializer) const override; + //! Deserializes a blob back into a ExpressionListRef + static unique_ptr Deserialize(FieldReader &source); +}; } // namespace duckdb - namespace duckdb { -using Filter = FilterPushdown::Filter; +ValueRelation::ValueRelation(ClientContext &context, const vector> &values, vector names_p, + string alias_p) + : Relation(context, RelationType::VALUE_LIST_RELATION), names(move(names_p)), alias(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]; + vector> expressions; + 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)); + } + context.TryBindRelation(*this, this->columns); +} -unique_ptr FilterPushdown::PushdownInnerJoin(unique_ptr op, - unordered_set &left_bindings, - unordered_set &right_bindings) { - auto &join = (LogicalJoin &)*op; - D_ASSERT(join.join_type == JoinType::INNER); - D_ASSERT(op->type != LogicalOperatorType::LOGICAL_DELIM_JOIN); - // 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) { - // filter statically evaluates to false, strip tree - return make_unique(move(op)); +ValueRelation::ValueRelation(ClientContext &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)) { + this->expressions = Parser::ParseValuesList(values_list, context.GetParserOptions()); + context.TryBindRelation(*this, this->columns); +} + +unique_ptr ValueRelation::GetQueryNode() { + auto result = make_unique(); + result->select_list.push_back(make_unique()); + result->from_table = GetTableRef(); + return move(result); +} + +unique_ptr ValueRelation::GetTableRef() { + auto table_ref = make_unique(); + // set the expected types/names + if (columns.empty()) { + // no columns yet: only set up names + for (idx_t i = 0; i < names.size(); i++) { + table_ref->expected_names.push_back(names[i]); } } else { - // comparison join - D_ASSERT(op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN); - auto &comp_join = (LogicalComparisonJoin &)join; - // turn the conditions into filters - for (auto &i : comp_join.conditions) { - auto condition = JoinCondition::CreateExpression(move(i)); - if (AddFilter(move(condition)) == FilterResult::UNSATISFIABLE) { - // filter statically evaluates to false, strip tree - return make_unique(move(op)); - } + for (idx_t i = 0; i < columns.size(); i++) { + table_ref->expected_names.push_back(columns[i].name); + table_ref->expected_types.push_back(columns[i].type); + D_ASSERT(names.size() == 0 || columns[i].name == names[i]); } } - GenerateFilters(); - - // turn the inner join into a cross product - auto cross_product = make_unique(); - cross_product->children.push_back(move(op->children[0])); - cross_product->children.push_back(move(op->children[1])); - // then push down cross product - return PushdownCrossProduct(move(cross_product)); + // copy the expressions + for (auto &expr_list : expressions) { + vector> copied_list; + copied_list.reserve(expr_list.size()); + for (auto &expr : expr_list) { + copied_list.push_back(expr->Copy()); + } + table_ref->values.push_back(move(copied_list)); + } + table_ref->alias = GetAlias(); + return move(table_ref); } -} // namespace duckdb - +string ValueRelation::GetAlias() { + return alias; +} +const vector &ValueRelation::Columns() { + return columns; +} +string ValueRelation::ToString(idx_t depth) { + string str = RenderWhitespace(depth) + "Values "; + for (idx_t row_idx = 0; row_idx < expressions.size(); row_idx++) { + auto &list = expressions[row_idx]; + str += row_idx > 0 ? ", (" : "("; + for (idx_t col_idx = 0; col_idx < list.size(); col_idx++) { + str += col_idx > 0 ? ", " : ""; + str += list[col_idx]->ToString(); + } + str += ")"; + } + str += "\n"; + return str; +} +} // namespace duckdb @@ -112045,198 +116269,80 @@ unique_ptr FilterPushdown::PushdownInnerJoin(unique_ptrcolumns); +} -static unique_ptr ReplaceColRefWithNull(unique_ptr expr, unordered_set &right_bindings) { - if (expr->type == ExpressionType::BOUND_COLUMN_REF) { - auto &bound_colref = (BoundColumnRefExpression &)*expr; - if (right_bindings.find(bound_colref.binding.table_index) != right_bindings.end()) { - // bound colref belongs to RHS - // replace it with a constant NULL - return make_unique(Value(expr->return_type)); - } - return expr; - } - ExpressionIterator::EnumerateChildren( - *expr, [&](unique_ptr &child) { child = ReplaceColRefWithNull(move(child), right_bindings); }); - return expr; +unique_ptr ViewRelation::GetQueryNode() { + auto result = make_unique(); + result->select_list.push_back(make_unique()); + result->from_table = GetTableRef(); + return move(result); } -static bool FilterRemovesNull(ExpressionRewriter &rewriter, Expression *expr, unordered_set &right_bindings) { - // 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); +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); +} - // attempt to flatten the expression by running the expression rewriter on it - auto filter = make_unique(); - filter->expressions.push_back(move(copy)); - rewriter.VisitOperator(*filter); +string ViewRelation::GetAlias() { + return view_name; +} - // check if all expressions are foldable - for (idx_t i = 0; i < filter->expressions.size(); i++) { - if (!filter->expressions[i]->IsFoldable()) { - return false; - } - // we flattened the result into a scalar, check if it is FALSE or NULL - auto val = ExpressionExecutor::EvaluateScalar(*filter->expressions[i]).CastAs(LogicalType::BOOLEAN); - // if the result of the expression with all expressions replaced with NULL is "NULL" or "false" - // then any extra entries generated by the LEFT OUTER JOIN will be filtered out! - // hence the LEFT OUTER JOIN is equivalent to an inner join - if (val.is_null || !val.value_.boolean) { - return true; - } - } - return false; +const vector &ViewRelation::Columns() { + return columns; } -unique_ptr FilterPushdown::PushdownLeftJoin(unique_ptr op, - unordered_set &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); - 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 - FilterCombiner filter_combiner; - if (op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN) { - // add all comparison conditions - auto &comparison_join = (LogicalComparisonJoin &)*op; - for (auto &cond : comparison_join.conditions) { - filter_combiner.AddFilter( - make_unique(cond.comparison, cond.left->Copy(), cond.right->Copy())); - } - } - // now check the set of filters - for (idx_t i = 0; i < filters.size(); i++) { - auto side = JoinSide::GetJoinSide(filters[i]->bindings, left_bindings, right_bindings); - if (side == JoinSide::LEFT) { - // bindings match left side - // we can push the filter into the left side - if (op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN) { - // we MIGHT be able to push it down the RHS as well, but only if it is a comparison that matches the - // join predicates we use the FilterCombiner to figure this out add the expression to the FilterCombiner - filter_combiner.AddFilter(filters[i]->filter->Copy()); - } - left_pushdown.filters.push_back(move(filters[i])); - // erase the filter from the list of filters - filters.erase(filters.begin() + i); - i--; - } else { - // bindings match right side or both sides: we cannot directly push it into the right - // however, if the filter removes rows with null values from the RHS we can turn the left outer join - // in an inner join, and then push down as we would push down an inner join - if (FilterRemovesNull(optimizer.rewriter, filters[i]->filter.get(), right_bindings)) { - // the filter removes NULL values, turn it into an inner join - join.join_type = JoinType::INNER; - // now we can do more pushdown - // move all filters we added to the left_pushdown back into the filter list - for (auto &left_filter : left_pushdown.filters) { - filters.push_back(move(left_filter)); - } - // now push down the inner join - return PushdownInnerJoin(move(op), left_bindings, right_bindings); - } - } - } - // finally we check the FilterCombiner to see if there are any predicates we can push into the RHS - // we only added (1) predicates that have JoinSide::BOTH from the conditions, and - // (2) predicates that have JoinSide::LEFT from the filters - // we check now if this combination generated any new filters that are only on JoinSide::RIGHT - // this happens if, e.g. a join condition is (i=a) and there is a filter (i=500), we can then push the filter - // (a=500) into the RHS - filter_combiner.GenerateFilters([&](unique_ptr filter) { - if (JoinSide::GetJoinSide(*filter, left_bindings, right_bindings) == JoinSide::RIGHT) { - right_pushdown.AddFilter(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)); +string ViewRelation::ToString(idx_t depth) { + return RenderWhitespace(depth) + "View [" + view_name + "]"; } } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/relation/write_csv_relation.hpp +// +// +//===----------------------------------------------------------------------===// + namespace duckdb { -using Filter = FilterPushdown::Filter; +class WriteCSVRelation : public Relation { +public: + WriteCSVRelation(shared_ptr child, string csv_file); -unique_ptr FilterPushdown::PushdownMarkJoin(unique_ptr op, - unordered_set &left_bindings, - unordered_set &right_bindings) { - auto &join = (LogicalJoin &)*op; - auto &comp_join = (LogicalComparisonJoin &)*op; - D_ASSERT(join.join_type == JoinType::MARK); - D_ASSERT(op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN || - op->type == LogicalOperatorType::LOGICAL_DELIM_JOIN); + shared_ptr child; + string csv_file; + vector columns; - right_bindings.insert(comp_join.mark_index); - FilterPushdown left_pushdown(optimizer), right_pushdown(optimizer); -#ifndef NDEBUG - bool found_mark_reference = false; -#endif - // now check the set of filters - for (idx_t i = 0; i < filters.size(); i++) { - auto side = JoinSide::GetJoinSide(filters[i]->bindings, left_bindings, right_bindings); - if (side == JoinSide::LEFT) { - // bindings match left side: push into left - left_pushdown.filters.push_back(move(filters[i])); - // erase the filter from the list of filters - filters.erase(filters.begin() + i); - i--; - } else if (side == JoinSide::RIGHT) { - // there can only be at most one filter referencing the marker -#ifndef NDEBUG - D_ASSERT(!found_mark_reference); - found_mark_reference = true; -#endif - // this filter references the marker - // we can turn this into a SEMI join if the filter is on only the marker - if (filters[i]->filter->type == ExpressionType::BOUND_COLUMN_REF) { - // filter just references the marker: turn into semi join - join.join_type = JoinType::SEMI; - filters.erase(filters.begin() + i); - i--; - continue; - } - // if the filter is on NOT(marker) AND the join conditions are all set to "null_values_are_equal" we can - // turn this into an ANTI join if all join conditions have null_values_are_equal=true, then the result of - // the MARK join is always TRUE or FALSE, and never NULL this happens in the case of a correlated EXISTS - // clause - if (filters[i]->filter->type == ExpressionType::OPERATOR_NOT) { - auto &op_expr = (BoundOperatorExpression &)*filters[i]->filter; - if (op_expr.children[0]->type == ExpressionType::BOUND_COLUMN_REF) { - // the filter is NOT(marker), check the join conditions - bool all_null_values_are_equal = true; - for (auto &cond : comp_join.conditions) { - if (!cond.null_values_are_equal) { - all_null_values_are_equal = false; - break; - } - } - if (all_null_values_are_equal) { - // all null values are equal, convert to ANTI join - join.join_type = JoinType::ANTI; - filters.erase(filters.begin() + i); - i--; - continue; - } - } - } - } +public: + BoundStatement Bind(Binder &binder) override; + const vector &Columns() override; + string ToString(idx_t depth) override; + bool IsReadOnly() override { + return false; } - op->children[0] = left_pushdown.Rewrite(move(op->children[0])); - op->children[1] = right_pushdown.Rewrite(move(op->children[1])); - return FinishPushdown(move(op)); -} +}; } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/statement/copy_statement.hpp +// +// +//===----------------------------------------------------------------------===// + + @@ -112244,188 +116350,71 @@ unique_ptr FilterPushdown::PushdownMarkJoin(unique_ptr ReplaceProjectionBindings(LogicalProjection &proj, unique_ptr expr) { - if (expr->type == ExpressionType::BOUND_COLUMN_REF) { - auto &colref = (BoundColumnRefExpression &)*expr; - D_ASSERT(colref.binding.table_index == proj.table_index); - D_ASSERT(colref.binding.column_index < proj.expressions.size()); - D_ASSERT(colref.depth == 0); - // replace the binding with a copy to the expression at the referenced index - return proj.expressions[colref.binding.column_index]->Copy(); - } - ExpressionIterator::EnumerateChildren( - *expr, [&](unique_ptr &child) { child = ReplaceProjectionBindings(proj, move(child)); }); - return expr; -} +class CopyStatement : public SQLStatement { +public: + CopyStatement(); -unique_ptr FilterPushdown::PushdownProjection(unique_ptr op) { - D_ASSERT(op->type == LogicalOperatorType::LOGICAL_PROJECTION); - auto &proj = (LogicalProjection &)*op; - // push filter through logical projection - // all the BoundColumnRefExpressions in the filter should refer to the LogicalProjection - // we can rewrite them by replacing those references with the expression of the LogicalProjection node - FilterPushdown child_pushdown(optimizer); - for (auto &filter : filters) { - auto &f = *filter; - D_ASSERT(f.bindings.size() <= 1); - // rewrite the bindings within this subquery - f.filter = ReplaceProjectionBindings(proj, move(f.filter)); - // add the filter to the child pushdown - if (child_pushdown.AddFilter(move(f.filter)) == FilterResult::UNSATISFIABLE) { - // filter statically evaluates to false, strip tree - return make_unique(move(op)); - } - } - child_pushdown.GenerateFilters(); - // now push into children - op->children[0] = child_pushdown.Rewrite(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 op; -} + unique_ptr info; + // The SQL statement used instead of a table when copying data out to a file + unique_ptr select_statement; + +protected: + CopyStatement(const CopyStatement &other); +public: + unique_ptr Copy() const override; +}; } // 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)) { + context.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"; + copy.info = move(info); + return binder.Bind((SQLStatement &)copy); +} +const vector &WriteCSVRelation::Columns() { + return columns; +} -namespace duckdb { +string WriteCSVRelation::ToString(idx_t depth) { + string str = RenderWhitespace(depth) + "Write To CSV [" + csv_file + "]\n"; + return str + child->ToString(depth + 1); +} -using Filter = FilterPushdown::Filter; +} // namespace duckdb -static void ReplaceSetOpBindings(vector &bindings, Filter &filter, Expression &expr, - LogicalSetOperation &setop) { - if (expr.type == ExpressionType::BOUND_COLUMN_REF) { - auto &colref = (BoundColumnRefExpression &)expr; - D_ASSERT(colref.binding.table_index == setop.table_index); - D_ASSERT(colref.depth == 0); - // rewrite the binding by looking into the bound_tables list of the subquery - colref.binding = bindings[colref.binding.column_index]; - filter.bindings.insert(colref.binding.table_index); - return; - } - ExpressionIterator::EnumerateChildren( - expr, [&](Expression &child) { ReplaceSetOpBindings(bindings, filter, child, setop); }); -} -unique_ptr FilterPushdown::PushdownSetOperation(unique_ptr op) { - D_ASSERT(op->type == LogicalOperatorType::LOGICAL_UNION || op->type == LogicalOperatorType::LOGICAL_EXCEPT || - op->type == LogicalOperatorType::LOGICAL_INTERSECT); - auto &setop = (LogicalSetOperation &)*op; - D_ASSERT(op->children.size() == 2); - auto left_bindings = op->children[0]->GetColumnBindings(); - auto right_bindings = op->children[1]->GetColumnBindings(); - // pushdown into set operation, we can duplicate the condition and pushdown the expressions into both sides - FilterPushdown left_pushdown(optimizer), right_pushdown(optimizer); - for (idx_t i = 0; i < filters.size(); i++) { - // first create a copy of the filter - auto right_filter = make_unique(); - right_filter->filter = filters[i]->filter->Copy(); - // in the original filter, rewrite references to the result of the union into references to the left_index - ReplaceSetOpBindings(left_bindings, *filters[i], *filters[i]->filter, setop); - // in the copied filter, rewrite references to the result of the union into references to the right_index - ReplaceSetOpBindings(right_bindings, *right_filter, *right_filter->filter, setop); - // extract bindings again - filters[i]->ExtractBindings(); - right_filter->ExtractBindings(); - // move the filters into the child pushdown nodes - left_pushdown.filters.push_back(move(filters[i])); - right_pushdown.filters.push_back(move(right_filter)); - } - op->children[0] = left_pushdown.Rewrite(move(op->children[0])); - op->children[1] = right_pushdown.Rewrite(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)); - } - if (left_empty) { - // left child is empty result - switch (op->type) { - case LogicalOperatorType::LOGICAL_UNION: - if (op->children[1]->type == LogicalOperatorType::LOGICAL_PROJECTION) { - // union with empty left side: return right child - auto &projection = (LogicalProjection &)*op->children[1]; - projection.table_index = setop.table_index; - return 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)); - default: - throw InternalException("Unsupported set operation"); - } - } else if (right_empty) { - // right child is empty result - switch (op->type) { - case LogicalOperatorType::LOGICAL_UNION: - case LogicalOperatorType::LOGICAL_EXCEPT: - if (op->children[0]->type == LogicalOperatorType::LOGICAL_PROJECTION) { - // union or except with empty right child: return left child - auto &projection = (LogicalProjection &)*op->children[0]; - projection.table_index = setop.table_index; - return move(op->children[0]); - } - break; - case LogicalOperatorType::LOGICAL_INTERSECT: - // intersect: if any child is empty, return empty result itself - return make_unique(move(op)); - default: - throw InternalException("Unsupported set operation"); - } - } - return op; -} -} // namespace duckdb -namespace duckdb { -using Filter = FilterPushdown::Filter; -unique_ptr FilterPushdown::PushdownSingleJoin(unique_ptr op, - unordered_set &left_bindings, - unordered_set &right_bindings) { - D_ASSERT(((LogicalJoin &)*op).join_type == JoinType::SINGLE); - FilterPushdown left_pushdown(optimizer), right_pushdown(optimizer); - // now check the set of filters - for (idx_t i = 0; i < filters.size(); i++) { - auto side = JoinSide::GetJoinSide(filters[i]->bindings, left_bindings, right_bindings); - if (side == JoinSide::LEFT) { - // bindings match left side: push into left - left_pushdown.filters.push_back(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)); -} -} // namespace duckdb @@ -112436,306 +116425,294 @@ unique_ptr FilterPushdown::PushdownSingleJoin(unique_ptr Relation::Project(const string &select_list) { + return Project(select_list, vector()); +} +shared_ptr Relation::Project(const string &expression, const string &alias) { + return Project(expression, vector({alias})); +} +shared_ptr Relation::Project(const string &select_list, const vector &aliases) { + auto expressions = Parser::ParseExpressionList(select_list, context.GetParserOptions()); + return make_shared(shared_from_this(), move(expressions), aliases); +} +shared_ptr Relation::Project(const vector &expressions) { + vector aliases; + return Project(expressions, aliases); +} -namespace duckdb { +static vector> StringListToExpressionList(ClientContext &context, + const vector &expressions) { + if (expressions.empty()) { + throw ParserException("Zero expressions provided"); + } + vector> result_list; + for (auto &expr : expressions) { + auto expression_list = Parser::ParseExpressionList(expr, context.GetParserOptions()); + if (expression_list.size() != 1) { + throw ParserException("Expected a single expression in the expression list"); + } + result_list.push_back(move(expression_list[0])); + } + return result_list; +} -unique_ptr RegexRangeFilter::Rewrite(unique_ptr op) { +shared_ptr Relation::Project(const vector &expressions, const vector &aliases) { + auto result_list = StringListToExpressionList(context, expressions); + return make_shared(shared_from_this(), move(result_list), aliases); +} - for (idx_t child_idx = 0; child_idx < op->children.size(); child_idx++) { - op->children[child_idx] = Rewrite(move(op->children[child_idx])); +shared_ptr Relation::Filter(const string &expression) { + auto expression_list = Parser::ParseExpressionList(expression, context.GetParserOptions()); + if (expression_list.size() != 1) { + throw ParserException("Expected a single expression as filter condition"); } + return make_shared(shared_from_this(), move(expression_list[0])); +} - if (op->type != LogicalOperatorType::LOGICAL_FILTER) { - return op; +shared_ptr Relation::Filter(const vector &expressions) { + // if there are multiple expressions, we AND them together + auto expression_list = StringListToExpressionList(context, expressions); + D_ASSERT(!expression_list.empty()); + + auto expr = 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])); } + return make_shared(shared_from_this(), move(expr)); +} - auto new_filter = make_unique(); +shared_ptr Relation::Limit(int64_t limit, int64_t offset) { + return make_shared(shared_from_this(), limit, offset); +} - for (auto &expr : op->expressions) { - if (expr->type == ExpressionType::BOUND_FUNCTION) { - auto &func = (BoundFunctionExpression &)*expr.get(); - if (func.function.name != "regexp_full_match" || func.children.size() != 2) { - continue; - } - auto &info = (RegexpMatchesBindData &)*func.bind_info; - if (!info.range_success) { - continue; - } - auto filter_left = make_unique( - ExpressionType::COMPARE_GREATERTHANOREQUALTO, func.children[0]->Copy(), - make_unique( - Value::BLOB((const_data_ptr_t)info.range_min.c_str(), info.range_min.size()))); - auto filter_right = make_unique( - ExpressionType::COMPARE_LESSTHANOREQUALTO, func.children[0]->Copy(), - make_unique( - 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)); +shared_ptr Relation::Order(const string &expression) { + auto order_list = Parser::ParseOrderList(expression, context.GetParserOptions()); + return make_shared(shared_from_this(), move(order_list)); +} - new_filter->expressions.push_back(move(filter_expr)); +shared_ptr Relation::Order(const vector &expressions) { + if (expressions.empty()) { + throw ParserException("Zero ORDER BY expressions provided"); + } + vector order_list; + for (auto &expression : expressions) { + auto inner_list = Parser::ParseOrderList(expression, context.GetParserOptions()); + 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])); } + return make_shared(shared_from_this(), move(order_list)); +} - if (!new_filter->expressions.empty()) { - new_filter->children = move(op->children); - op->children.clear(); - op->children.push_back(move(new_filter)); +shared_ptr Relation::Join(const shared_ptr &other, const string &condition, JoinType type) { + auto expression_list = Parser::ParseExpressionList(condition, context.GetParserOptions()); + D_ASSERT(!expression_list.empty()); + + if (expression_list.size() > 1 || expression_list[0]->type == ExpressionType::COLUMN_REF) { + // multiple columns or single column ref: the condition is a USING list + vector using_columns; + for (auto &expr : expression_list) { + if (expr->type != ExpressionType::COLUMN_REF) { + throw ParserException("Expected a single expression as join condition"); + } + auto &colref = (ColumnRefExpression &)*expr; + if (colref.IsQualified()) { + throw ParserException("Expected unqualified column for column in USING clause"); + } + using_columns.push_back(colref.column_names[0]); + } + return make_shared(shared_from_this(), other, 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 op; +shared_ptr Relation::CrossProduct(const shared_ptr &other) { + return make_shared(shared_from_this(), other); } -} // namespace duckdb +shared_ptr Relation::Union(const shared_ptr &other) { + return make_shared(shared_from_this(), other, SetOperationType::UNION); +} +shared_ptr Relation::Except(const shared_ptr &other) { + return make_shared(shared_from_this(), other, SetOperationType::EXCEPT); +} +shared_ptr Relation::Intersect(const shared_ptr &other) { + return make_shared(shared_from_this(), other, SetOperationType::INTERSECT); +} +shared_ptr Relation::Distinct() { + return make_shared(shared_from_this()); +} +shared_ptr Relation::Alias(const string &alias) { + return make_shared(shared_from_this(), alias); +} +shared_ptr Relation::Aggregate(const string &aggregate_list) { + auto expression_list = Parser::ParseExpressionList(aggregate_list, context.GetParserOptions()); + return make_shared(shared_from_this(), move(expression_list)); +} +shared_ptr Relation::Aggregate(const string &aggregate_list, const string &group_list) { + auto expression_list = Parser::ParseExpressionList(aggregate_list, context.GetParserOptions()); + auto groups = Parser::ParseExpressionList(group_list, context.GetParserOptions()); + return make_shared(shared_from_this(), move(expression_list), move(groups)); +} +shared_ptr Relation::Aggregate(const vector &aggregates) { + auto aggregate_list = StringListToExpressionList(context, aggregates); + return make_shared(shared_from_this(), move(aggregate_list)); +} +shared_ptr Relation::Aggregate(const vector &aggregates, const vector &groups) { + auto aggregate_list = StringListToExpressionList(context, aggregates); + auto group_list = StringListToExpressionList(context, groups); + return make_shared(shared_from_this(), move(aggregate_list), move(group_list)); +} +string Relation::GetAlias() { + return "relation"; +} +unique_ptr Relation::GetTableRef() { + auto select = make_unique(); + select->node = GetQueryNode(); + return make_unique(move(select), GetAlias()); +} +unique_ptr Relation::Execute() { + return context.Execute(shared_from_this()); +} +BoundStatement Relation::Bind(Binder &binder) { + SelectStatement stmt; + stmt.node = GetQueryNode(); + return binder.Bind((SQLStatement &)stmt); +} +void Relation::Insert(const string &table_name) { + Insert(DEFAULT_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 res = insert->Execute(); + if (!res->success) { + throw Exception("Failed to insert into table '" + table_name + "': " + res->error); + } +} +void Relation::Insert(const vector> &values) { + vector column_names; + auto rel = make_shared(context, values, move(column_names), "values"); + rel->Insert(GetAlias()); +} -#include +void Relation::Create(const string &table_name) { + Create(DEFAULT_SCHEMA, table_name); +} -namespace duckdb { +void Relation::Create(const string &schema_name, const string &table_name) { + auto create = make_shared(shared_from_this(), schema_name, table_name); + auto res = create->Execute(); + if (!res->success) { + throw Exception("Failed to create table '" + table_name + "': " + res->error); + } +} -void RemoveUnusedColumns::ReplaceBinding(ColumnBinding current_binding, ColumnBinding new_binding) { - auto colrefs = column_references.find(current_binding); - if (colrefs != column_references.end()) { - for (auto &colref : colrefs->second) { - D_ASSERT(colref->binding == current_binding); - colref->binding = new_binding; - } +void Relation::WriteCSV(const string &csv_file) { + auto write_csv = make_shared(shared_from_this(), csv_file); + auto res = write_csv->Execute(); + if (!res->success) { + throw Exception("Failed to write '" + csv_file + "': " + res->error); } } -template -void RemoveUnusedColumns::ClearUnusedExpressions(vector &list, idx_t table_idx) { - idx_t offset = 0; - for (idx_t col_idx = 0; col_idx < list.size(); col_idx++) { - auto current_binding = ColumnBinding(table_idx, col_idx + offset); - auto entry = column_references.find(current_binding); - if (entry == column_references.end()) { - // this entry is not referred to, erase it from the set of expressions - list.erase(list.begin() + col_idx); - offset++; - col_idx--; - } else if (offset > 0) { - // column is used but the ColumnBinding has changed because of removed columns - ReplaceBinding(current_binding, ColumnBinding(table_idx, col_idx)); - } +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(); + if (!res->success) { + throw Exception("Failed to create view '" + name + "': " + res->error); } + return shared_from_this(); } -void RemoveUnusedColumns::VisitOperator(LogicalOperator &op) { - switch (op.type) { - case LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY: { - // aggregate - if (!everything_referenced) { - // FIXME: groups that are not referenced need to stay -> but they don't need to be scanned and output! - auto &aggr = (LogicalAggregate &)op; - ClearUnusedExpressions(aggr.expressions, aggr.aggregate_index); - if (aggr.expressions.empty() && aggr.groups.empty()) { - // removed all expressions from the aggregate: push a COUNT(*) - auto count_star_fun = CountStarFun::GetFunction(); - aggr.expressions.push_back( - AggregateFunction::BindAggregateFunction(context, count_star_fun, {}, nullptr, false)); - } - } +unique_ptr Relation::Query(const string &sql) { + return context.Query(sql, false); +} - // then recurse into the children of the aggregate - RemoveUnusedColumns remove(binder, context); - remove.VisitOperatorExpressions(op); - remove.VisitOperator(*op.children[0]); - return; - } - case LogicalOperatorType::LOGICAL_DELIM_JOIN: - case LogicalOperatorType::LOGICAL_COMPARISON_JOIN: { - if (!everything_referenced) { - auto &comp_join = (LogicalComparisonJoin &)op; +unique_ptr Relation::Query(const string &name, const string &sql) { + CreateView(name); + return Query(sql); +} - if (comp_join.join_type != JoinType::INNER) { - break; - } - // for inner joins with equality predicates in the form of (X=Y) - // we can replace any references to the RHS (Y) to references to the LHS (X) - // this reduces the amount of columns we need to extract from the join hash table - for (auto &cond : comp_join.conditions) { - if (cond.comparison == ExpressionType::COMPARE_EQUAL) { - if (cond.left->expression_class == ExpressionClass::BOUND_COLUMN_REF && - cond.right->expression_class == ExpressionClass::BOUND_COLUMN_REF) { - // comparison join between two bound column refs - // we can replace any reference to the RHS (build-side) with a reference to the LHS (probe-side) - auto &lhs_col = (BoundColumnRefExpression &)*cond.left; - auto &rhs_col = (BoundColumnRefExpression &)*cond.right; - // if there are any columns that refer to the RHS, - auto colrefs = column_references.find(rhs_col.binding); - if (colrefs != column_references.end()) { - for (auto &entry : colrefs->second) { - entry->binding = lhs_col.binding; - column_references[lhs_col.binding].push_back(entry); - } - column_references.erase(rhs_col.binding); - } - } - } - } - } - break; - } - case LogicalOperatorType::LOGICAL_ANY_JOIN: - break; - case LogicalOperatorType::LOGICAL_UNION: - if (!everything_referenced) { - // 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) - // this happens when UNION ALL is used - auto &setop = (LogicalSetOperation &)op; - vector entries; - for (idx_t i = 0; i < setop.column_count; i++) { - entries.push_back(i); - } - ClearUnusedExpressions(entries, setop.table_index); - if (entries.size() < setop.column_count) { - if (entries.empty()) { - // no columns referenced: this happens in the case of a COUNT(*) - // extract the first column - entries.push_back(0); - } - // columns were cleared - setop.column_count = entries.size(); +unique_ptr Relation::Explain() { + auto explain = make_shared(shared_from_this()); + return explain->Execute(); +} - for (idx_t child_idx = 0; child_idx < op.children.size(); child_idx++) { - RemoveUnusedColumns remove(binder, context, true); - auto &child = op.children[child_idx]; +void Relation::Update(const string &update, const string &condition) { + throw Exception("UPDATE can only be used on base tables!"); +} - // we push a projection under this child that references the required columns of the union - child->ResolveOperatorTypes(); - auto bindings = child->GetColumnBindings(); - vector> expressions; - expressions.reserve(entries.size()); - for (auto &column_idx : entries) { - expressions.push_back( - 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); +void Relation::Delete(const string &condition) { + throw Exception("DELETE can only be used on base tables!"); +} - remove.VisitOperator(*op.children[child_idx]); - } - return; - } - } - for (auto &child : op.children) { - RemoveUnusedColumns remove(binder, context, true); - remove.VisitOperator(*child); - } - return; - case LogicalOperatorType::LOGICAL_EXCEPT: - case LogicalOperatorType::LOGICAL_INTERSECT: - // for INTERSECT/EXCEPT operations we can't remove anything, just recursively visit the children - for (auto &child : op.children) { - RemoveUnusedColumns remove(binder, context, true); - remove.VisitOperator(*child); - } - return; - case LogicalOperatorType::LOGICAL_PROJECTION: { - if (!everything_referenced) { - auto &proj = (LogicalProjection &)op; - ClearUnusedExpressions(proj.expressions, proj.table_index); +shared_ptr Relation::TableFunction(const std::string &fname, const vector &values, + const named_parameter_map_t &named_parameters) { + return make_shared(context, fname, values, named_parameters, shared_from_this()); +} - if (proj.expressions.empty()) { - // nothing references the projected expressions - // this happens in the case of e.g. EXISTS(SELECT * FROM ...) - // in this case we only need to project a single constant - proj.expressions.push_back(make_unique(Value::INTEGER(42))); - } - } - // then recurse into the children of this projection - RemoveUnusedColumns remove(binder, context); - remove.VisitOperatorExpressions(op); - remove.VisitOperator(*op.children[0]); - return; - } - case LogicalOperatorType::LOGICAL_GET: - LogicalOperatorVisitor::VisitOperatorExpressions(op); - if (!everything_referenced) { - auto &get = (LogicalGet &)op; - // for every table filter, push a column binding into the column references map to prevent the column from - // being projected out - for (auto &filter : get.table_filters.filters) { - idx_t index = INVALID_INDEX; - for (idx_t i = 0; i < get.column_ids.size(); i++) { - if (get.column_ids[i] == filter.first) { - index = i; - break; - } - } - if (index == INVALID_INDEX) { - throw InternalException("Could not find column index for table filter"); - } - ColumnBinding filter_binding(get.table_index, index); - if (column_references.find(filter_binding) == column_references.end()) { - column_references.insert(make_pair(filter_binding, vector())); - } - } - // table scan: figure out which columns are referenced - ClearUnusedExpressions(get.column_ids, get.table_index); +shared_ptr Relation::TableFunction(const std::string &fname, const vector &values) { + return make_shared(context, fname, values, shared_from_this()); +} - if (get.column_ids.empty()) { - // this generally means we are only interested in whether or not anything exists in the table (e.g. - // EXISTS(SELECT * FROM tbl)) in this case, we just scan the row identifier column as it means we do not - // need to read any of the columns - get.column_ids.push_back(COLUMN_IDENTIFIER_ROW_ID); - } - } - 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_RECURSIVE_CTE: { - everything_referenced = true; - break; - } - case LogicalOperatorType::LOGICAL_CTE_REF: { - everything_referenced = true; - break; - } - default: - break; +string Relation::ToString() { + string str; + str += "---------------------\n"; + str += "-- Expression Tree --\n"; + str += "---------------------\n"; + str += ToString(0); + str += "\n\n"; + str += "---------------------\n"; + str += "-- Result Columns --\n"; + str += "---------------------\n"; + auto &cols = Columns(); + for (idx_t i = 0; i < cols.size(); i++) { + str += "- " + cols[i].name + " (" + cols[i].type.ToString() + ")\n"; } - LogicalOperatorVisitor::VisitOperatorExpressions(op); - LogicalOperatorVisitor::VisitOperatorChildren(op); + return str; } -unique_ptr RemoveUnusedColumns::VisitReplace(BoundColumnRefExpression &expr, - unique_ptr *expr_ptr) { - // add a column reference - column_references[expr.binding].push_back(&expr); - return nullptr; +// LCOV_EXCL_START +unique_ptr Relation::GetQueryNode() { + throw InternalException("Cannot create a query node from this node type"); } -unique_ptr RemoveUnusedColumns::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!"); +void Relation::Head(idx_t limit) { + auto limit_node = Limit(limit); + limit_node->Execute()->Print(); +} +// LCOV_EXCL_STOP + +void Relation::Print() { + Printer::Print(ToString()); +} + +string Relation::RenderWhitespace(idx_t depth) { + return string(depth * 2, ' '); } } // namespace duckdb @@ -112746,394 +116723,539 @@ unique_ptr RemoveUnusedColumns::VisitReplace(BoundReferenceExpressio + + + + + namespace duckdb { -ArithmeticSimplificationRule::ArithmeticSimplificationRule(ExpressionRewriter &rewriter) : Rule(rewriter) { - // match on an OperatorExpression that has a ConstantExpression as child - auto op = make_unique(); - op->matchers.push_back(make_unique()); - op->matchers.push_back(make_unique()); - op->policy = SetMatcher::Policy::SOME; - // we only match on simple arithmetic expressions (+, -, *, /) - op->function = make_unique(unordered_set {"+", "-", "*", "/"}); - // and only with numeric results - op->type = make_unique(); - op->matchers[0]->type = make_unique(); - op->matchers[1]->type = make_unique(); - root = move(op); +//===--------------------------------------------------------------------===// +// Access Mode +//===--------------------------------------------------------------------===// +void AccessModeSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) { + auto parameter = StringUtil::Lower(input.ToString()); + if (parameter == "automatic") { + config.access_mode = AccessMode::AUTOMATIC; + } else if (parameter == "read_only") { + config.access_mode = AccessMode::READ_ONLY; + } else if (parameter == "read_write") { + config.access_mode = AccessMode::READ_WRITE; + } else { + throw InvalidInputException( + "Unrecognized parameter for option ACCESS_MODE \"%s\". Expected READ_ONLY or READ_WRITE.", parameter); + } } -unique_ptr ArithmeticSimplificationRule::Apply(LogicalOperator &op, vector &bindings, - bool &changes_made, bool is_root) { - auto root = (BoundFunctionExpression *)bindings[0]; - auto constant = (BoundConstantExpression *)bindings[1]; - int constant_child = root->children[0].get() == constant ? 0 : 1; - D_ASSERT(root->children.size() == 2); - (void)root; - // any arithmetic operator involving NULL is always NULL - if (constant->value.is_null) { - return make_unique(Value(root->return_type)); - } - auto &func_name = root->function.name; - if (func_name == "+") { - 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]); - } - } 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]); - } - } else if (func_name == "*") { - if (constant->value == 1) { - // multiply with 1, replace with non-constant child - return 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]), - Value::Numeric(root->return_type, 0)); - } - } else { - D_ASSERT(func_name == "/"); - if (constant_child == 1) { - if (constant->value == 1) { - // divide by 1, replace with non-constant child - return move(root->children[1 - constant_child]); - } else if (constant->value == 0) { - // divide by 0, replace with NULL - return make_unique(Value(root->return_type)); - } - } +Value AccessModeSetting::GetSetting(ClientContext &context) { + auto &config = DBConfig::GetConfig(context); + switch (config.access_mode) { + case AccessMode::AUTOMATIC: + return "automatic"; + case AccessMode::READ_ONLY: + return "read_only"; + case AccessMode::READ_WRITE: + return "read_write"; + default: + throw InternalException("Unknown access mode setting"); } - return nullptr; } -} // namespace duckdb +//===--------------------------------------------------------------------===// +// Checkpoint Threshold +//===--------------------------------------------------------------------===// +void CheckpointThresholdSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) { + idx_t new_limit = DBConfig::ParseMemoryLimit(input.ToString()); + config.checkpoint_wal_size = new_limit; +} +Value CheckpointThresholdSetting::GetSetting(ClientContext &context) { + auto &config = DBConfig::GetConfig(context); + return Value(StringUtil::BytesToHumanReadableString(config.checkpoint_wal_size)); +} +//===--------------------------------------------------------------------===// +// Debug Checkpoint Abort +//===--------------------------------------------------------------------===// +void DebugCheckpointAbort::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) { + auto checkpoint_abort = StringUtil::Lower(input.ToString()); + if (checkpoint_abort == "none") { + config.checkpoint_abort = CheckpointAbort::NO_ABORT; + } else if (checkpoint_abort == "before_truncate") { + config.checkpoint_abort = CheckpointAbort::DEBUG_ABORT_BEFORE_TRUNCATE; + } else if (checkpoint_abort == "before_header") { + config.checkpoint_abort = CheckpointAbort::DEBUG_ABORT_BEFORE_HEADER; + } else if (checkpoint_abort == "after_free_list_write") { + config.checkpoint_abort = CheckpointAbort::DEBUG_ABORT_AFTER_FREE_LIST_WRITE; + } else { + throw ParserException( + "Unrecognized option for PRAGMA debug_checkpoint_abort, expected none, before_truncate or before_header"); + } +} +Value DebugCheckpointAbort::GetSetting(ClientContext &context) { + return Value(); +} -namespace duckdb { +//===--------------------------------------------------------------------===// +// Debug Force External +//===--------------------------------------------------------------------===// +void DebugForceExternal::SetLocal(ClientContext &context, const Value &input) { + ClientConfig::GetConfig(context).force_external = input.GetValue(); +} -CaseSimplificationRule::CaseSimplificationRule(ExpressionRewriter &rewriter) : Rule(rewriter) { - // match on a CaseExpression that has a ConstantExpression as a check - auto op = make_unique(); - root = move(op); +Value DebugForceExternal::GetSetting(ClientContext &context) { + return Value::BOOLEAN(ClientConfig::GetConfig(context).force_external); } -unique_ptr CaseSimplificationRule::Apply(LogicalOperator &op, vector &bindings, - bool &changes_made, bool is_root) { - auto root = (BoundCaseExpression *)bindings[0]; - for (idx_t i = 0; i < root->case_checks.size(); i++) { - auto &case_check = root->case_checks[i]; - if (case_check.when_expr->IsFoldable()) { - // the WHEN check is a foldable expression - // use an ExpressionExecutor to execute the expression - auto constant_value = ExpressionExecutor::EvaluateScalar(*case_check.when_expr); +//===--------------------------------------------------------------------===// +// Debug Many Free List blocks +//===--------------------------------------------------------------------===// +void DebugManyFreeListBlocks::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) { + config.debug_many_free_list_blocks = input.GetValue(); +} - // fold based on the constant condition - auto condition = constant_value.CastAs(LogicalType::BOOLEAN); - if (condition.is_null || !condition.value_.boolean) { - // the condition is always false: remove this case check - root->case_checks.erase(root->case_checks.begin() + i); - i--; - } else { - // the condition is always true - // move the THEN clause to the ELSE of the case - root->else_expr = 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; - } - } - } - if (root->case_checks.empty()) { - // no case checks left: return the ELSE expression - return move(root->else_expr); +Value DebugManyFreeListBlocks::GetSetting(ClientContext &context) { + auto &config = DBConfig::GetConfig(context); + return Value::BOOLEAN(config.debug_many_free_list_blocks); +} + +//===--------------------------------------------------------------------===// +// Debug Window Mode +//===--------------------------------------------------------------------===// +void DebugWindowMode::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) { + auto param = StringUtil::Lower(input.ToString()); + if (param == "window") { + config.window_mode = WindowAggregationMode::WINDOW; + } else if (param == "combine") { + config.window_mode = WindowAggregationMode::COMBINE; + } else if (param == "separate") { + config.window_mode = WindowAggregationMode::SEPARATE; + } else { + throw ParserException("Unrecognized option for PRAGMA debug_window_mode, expected window, combine or separate"); } - return nullptr; } -} // namespace duckdb +Value DebugWindowMode::GetSetting(ClientContext &context) { + return Value(); +} +//===--------------------------------------------------------------------===// +// Default Collation +//===--------------------------------------------------------------------===// +void DefaultCollationSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) { + auto parameter = StringUtil::Lower(input.ToString()); + config.collation = parameter; +} +void DefaultCollationSetting::SetLocal(ClientContext &context, const Value &input) { + auto parameter = input.ToString(); + // bind the collation to verify that it exists + ExpressionBinder::TestCollation(context, parameter); + auto &config = DBConfig::GetConfig(context); + config.collation = parameter; +} +Value DefaultCollationSetting::GetSetting(ClientContext &context) { + auto &config = DBConfig::GetConfig(context); + return Value(config.collation); +} +//===--------------------------------------------------------------------===// +// Default Order +//===--------------------------------------------------------------------===// +void DefaultOrderSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) { + auto parameter = StringUtil::Lower(input.ToString()); + if (parameter == "ascending" || parameter == "asc") { + config.default_order_type = OrderType::ASCENDING; + } else if (parameter == "descending" || parameter == "desc") { + config.default_order_type = OrderType::DESCENDING; + } else { + throw InvalidInputException("Unrecognized parameter for option DEFAULT_ORDER \"%s\". Expected ASC or DESC.", + parameter); + } +} +Value DefaultOrderSetting::GetSetting(ClientContext &context) { + auto &config = DBConfig::GetConfig(context); + switch (config.default_order_type) { + case OrderType::ASCENDING: + return "asc"; + case OrderType::DESCENDING: + return "desc"; + default: + throw InternalException("Unknown order type setting"); + } +} -namespace duckdb { +//===--------------------------------------------------------------------===// +// Default Null Order +//===--------------------------------------------------------------------===// +void DefaultNullOrderSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) { + auto parameter = StringUtil::Lower(input.ToString()); -ComparisonSimplificationRule::ComparisonSimplificationRule(ExpressionRewriter &rewriter) : Rule(rewriter) { - // match on a ComparisonExpression that has a ConstantExpression as a check - auto op = make_unique(); - op->matchers.push_back(make_unique()); - op->policy = SetMatcher::Policy::SOME; - root = move(op); + if (parameter == "nulls_first" || parameter == "nulls first" || parameter == "null first" || parameter == "first") { + config.default_null_order = OrderByNullType::NULLS_FIRST; + } else if (parameter == "nulls_last" || parameter == "nulls last" || parameter == "null last" || + parameter == "last") { + config.default_null_order = OrderByNullType::NULLS_LAST; + } else { + throw ParserException( + "Unrecognized parameter for option NULL_ORDER \"%s\", expected either NULLS FIRST or NULLS LAST", + parameter); + } } -unique_ptr ComparisonSimplificationRule::Apply(LogicalOperator &op, vector &bindings, - bool &changes_made, bool is_root) { - D_ASSERT(bindings[0]->expression_class == ExpressionClass::BOUND_COMPARISON); - auto expr = (BoundComparisonExpression *)bindings[0]; - auto constant_expr = bindings[1]; - bool column_ref_left = expr->left.get() != constant_expr; - auto column_ref_expr = !column_ref_left ? expr->right.get() : expr->left.get(); - // the constant_expr is a scalar expression that we have to fold - // use an ExpressionExecutor to execute the expression - D_ASSERT(constant_expr->IsFoldable()); - Value constant_value; - if (!ExpressionExecutor::TryEvaluateScalar(*constant_expr, constant_value)) { - return nullptr; - } - if (constant_value.is_null && !(expr->type == ExpressionType::COMPARE_NOT_DISTINCT_FROM || - expr->type == ExpressionType::COMPARE_DISTINCT_FROM)) { - // comparison with constant NULL, return NULL - return make_unique(Value(LogicalType::BOOLEAN)); +Value DefaultNullOrderSetting::GetSetting(ClientContext &context) { + auto &config = DBConfig::GetConfig(context); + switch (config.default_null_order) { + case OrderByNullType::NULLS_FIRST: + return "nulls_first"; + case OrderByNullType::NULLS_LAST: + return "nulls_last"; + default: + throw InternalException("Unknown null order setting"); } - if (column_ref_expr->expression_class == ExpressionClass::BOUND_CAST) { - //! Here we check if we can apply the expression on the constant side - auto cast_expression = (BoundCastExpression *)column_ref_expr; - auto target_type = cast_expression->source_type(); - if (!BoundCastExpression::CastIsInvertible(target_type, cast_expression->return_type)) { - return nullptr; +} + +//===--------------------------------------------------------------------===// +// Disabled Optimizer +//===--------------------------------------------------------------------===// +void DisabledOptimizersSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) { + auto list = StringUtil::Split(input.ToString(), ","); + set disabled_optimizers; + for (auto &entry : list) { + auto param = StringUtil::Lower(entry); + StringUtil::Trim(param); + if (param.empty()) { + continue; } - auto new_constant = constant_value.TryCastAs(target_type); - if (new_constant) { - auto child_expression = move(cast_expression->child); - auto new_constant_expr = make_unique(constant_value); - //! We can cast, now we change our column_ref_expression from an operator cast to a column reference - if (column_ref_left) { - expr->left = move(child_expression); - expr->right = move(new_constant_expr); - } else { - expr->left = move(new_constant_expr); - expr->right = move(child_expression); - } + disabled_optimizers.insert(OptimizerTypeFromString(param)); + } + config.disabled_optimizers = move(disabled_optimizers); +} + +Value DisabledOptimizersSetting::GetSetting(ClientContext &context) { + auto &config = DBConfig::GetConfig(context); + string result; + for (auto &optimizer : config.disabled_optimizers) { + if (!result.empty()) { + result += ","; } + result += OptimizerTypeToString(optimizer); } - return nullptr; + return Value(result); } -} // namespace duckdb +//===--------------------------------------------------------------------===// +// Enable External Access +//===--------------------------------------------------------------------===// +void EnableExternalAccessSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) { + auto new_value = input.GetValue(); + if (db && new_value) { + throw InvalidInputException("Cannot change enable_external_access setting while database is running"); + } + config.enable_external_access = new_value; +} +Value EnableExternalAccessSetting::GetSetting(ClientContext &context) { + auto &config = DBConfig::GetConfig(context); + return Value::BOOLEAN(config.enable_external_access); +} +//===--------------------------------------------------------------------===// +// Enable Object Cache +//===--------------------------------------------------------------------===// +void EnableObjectCacheSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) { + config.object_cache_enable = input.GetValue(); +} +Value EnableObjectCacheSetting::GetSetting(ClientContext &context) { + auto &config = DBConfig::GetConfig(context); + return Value::BOOLEAN(config.object_cache_enable); +} +//===--------------------------------------------------------------------===// +// Enable Profiling +//===--------------------------------------------------------------------===// +void EnableProfilingSetting::SetLocal(ClientContext &context, const Value &input) { + auto parameter = StringUtil::Lower(input.ToString()); + + auto &config = ClientConfig::GetConfig(context); + if (parameter == "json") { + config.profiler_print_format = ProfilerPrintFormat::JSON; + } else if (parameter == "query_tree") { + config.profiler_print_format = ProfilerPrintFormat::QUERY_TREE; + } else if (parameter == "query_tree_optimizer") { + config.profiler_print_format = ProfilerPrintFormat::QUERY_TREE_OPTIMIZER; + } else { + throw ParserException( + "Unrecognized print format %s, supported formats: [json, query_tree, query_tree_optimizer]", parameter); + } + config.enable_profiler = true; +} +Value EnableProfilingSetting::GetSetting(ClientContext &context) { + auto &config = ClientConfig::GetConfig(context); + if (!config.enable_profiler) { + return Value(); + } + switch (config.profiler_print_format) { + case ProfilerPrintFormat::NONE: + return Value("none"); + case ProfilerPrintFormat::JSON: + return Value("json"); + case ProfilerPrintFormat::QUERY_TREE: + return Value("query_tree"); + case ProfilerPrintFormat::QUERY_TREE_OPTIMIZER: + return Value("query_tree_optimizer"); + default: + throw InternalException("Unsupported profiler print format"); + } +} -namespace duckdb { +//===--------------------------------------------------------------------===// +// Enable Progress Bar +//===--------------------------------------------------------------------===// +void EnableProgressBarSetting::SetLocal(ClientContext &context, const Value &input) { + ClientConfig::GetConfig(context).enable_progress_bar = input.GetValue(); +} -ConjunctionSimplificationRule::ConjunctionSimplificationRule(ExpressionRewriter &rewriter) : Rule(rewriter) { - // match on a ComparisonExpression that has a ConstantExpression as a check - auto op = make_unique(); - op->matchers.push_back(make_unique()); - op->policy = SetMatcher::Policy::SOME; - root = move(op); +Value EnableProgressBarSetting::GetSetting(ClientContext &context) { + return Value::BOOLEAN(ClientConfig::GetConfig(context).enable_progress_bar); } -unique_ptr ConjunctionSimplificationRule::RemoveExpression(BoundConjunctionExpression &conj, - Expression *expr) { - for (idx_t i = 0; i < conj.children.size(); i++) { - if (conj.children[i].get() == expr) { - // erase the expression - conj.children.erase(conj.children.begin() + i); - break; - } - } - if (conj.children.size() == 1) { - // one expression remaining: simply return that expression and erase the conjunction - return move(conj.children[0]); +//===--------------------------------------------------------------------===// +// Explain Output +//===--------------------------------------------------------------------===// +void ExplainOutputSetting::SetLocal(ClientContext &context, const Value &input) { + auto parameter = StringUtil::Lower(input.ToString()); + if (parameter == "all") { + ClientConfig::GetConfig(context).explain_output_type = ExplainOutputType::ALL; + } else if (parameter == "optimized_only") { + ClientConfig::GetConfig(context).explain_output_type = ExplainOutputType::OPTIMIZED_ONLY; + } else if (parameter == "physical_only") { + ClientConfig::GetConfig(context).explain_output_type = ExplainOutputType::PHYSICAL_ONLY; + } else { + throw ParserException("Unrecognized output type \"%s\", expected either ALL, OPTIMIZED_ONLY or PHYSICAL_ONLY", + parameter); } - return nullptr; } -unique_ptr ConjunctionSimplificationRule::Apply(LogicalOperator &op, vector &bindings, - bool &changes_made, bool is_root) { - auto conjunction = (BoundConjunctionExpression *)bindings[0]; - auto constant_expr = bindings[1]; - // the constant_expr is a scalar expression that we have to fold - // use an ExpressionExecutor to execute the expression - D_ASSERT(constant_expr->IsFoldable()); - Value constant_value; - if (!ExpressionExecutor::TryEvaluateScalar(*constant_expr, constant_value)) { - return nullptr; - } - constant_value = constant_value.CastAs(LogicalType::BOOLEAN); - if (constant_value.is_null) { - // we can't simplify conjunctions with a constant NULL - return nullptr; +Value ExplainOutputSetting::GetSetting(ClientContext &context) { + switch (ClientConfig::GetConfig(context).explain_output_type) { + case ExplainOutputType::ALL: + return "all"; + case ExplainOutputType::OPTIMIZED_ONLY: + return "optimized_only"; + case ExplainOutputType::PHYSICAL_ONLY: + return "physical_only"; + default: + throw InternalException("Unrecognized explain output type"); } - if (conjunction->type == ExpressionType::CONJUNCTION_AND) { - if (!constant_value.value_.boolean) { - // FALSE in AND, result of expression is false - return make_unique(Value::BOOLEAN(false)); - } else { - // TRUE in AND, remove the expression from the set - return RemoveExpression(*conjunction, constant_expr); - } +} + +//===--------------------------------------------------------------------===// +// Force Compression +//===--------------------------------------------------------------------===// +void ForceCompressionSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) { + auto compression = StringUtil::Lower(input.ToString()); + if (compression == "none") { + config.force_compression = CompressionType::COMPRESSION_AUTO; } else { - D_ASSERT(conjunction->type == ExpressionType::CONJUNCTION_OR); - if (!constant_value.value_.boolean) { - // FALSE in OR, remove the expression from the set - return RemoveExpression(*conjunction, constant_expr); - } else { - // TRUE in OR, result of expression is true - return make_unique(Value::BOOLEAN(true)); + 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"); } + config.force_compression = compression_type; } } -} // namespace duckdb - - - +Value ForceCompressionSetting::GetSetting(ClientContext &context) { + return Value(); +} +//===--------------------------------------------------------------------===// +// Log Query Path +//===--------------------------------------------------------------------===// +void LogQueryPathSetting::SetLocal(ClientContext &context, const Value &input) { + auto path = input.ToString(); + if (path.empty()) { + // empty path: clean up query writer + context.log_query_writer = nullptr; + } else { + context.log_query_writer = + make_unique(FileSystem::GetFileSystem(context), path, + BufferedFileWriter::DEFAULT_OPEN_FLAGS, context.file_opener.get()); + } +} +Value LogQueryPathSetting::GetSetting(ClientContext &context) { + return context.log_query_writer ? Value(context.log_query_writer->path) : Value(); +} +//===--------------------------------------------------------------------===// +// Maximum Memory +//===--------------------------------------------------------------------===// +void MaximumMemorySetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) { + config.maximum_memory = DBConfig::ParseMemoryLimit(input.ToString()); + if (db) { + BufferManager::GetBufferManager(*db).SetLimit(config.maximum_memory); + } +} -namespace duckdb { +Value MaximumMemorySetting::GetSetting(ClientContext &context) { + auto &config = DBConfig::GetConfig(context); + return Value(StringUtil::BytesToHumanReadableString(config.maximum_memory)); +} -//! The ConstantFoldingExpressionMatcher matches on any scalar expression (i.e. Expression::IsFoldable is true) -class ConstantFoldingExpressionMatcher : public FoldableConstantMatcher { -public: - bool Match(Expression *expr, vector &bindings) override { - // we also do not match on ConstantExpressions, because we cannot fold those any further - if (expr->type == ExpressionType::VALUE_CONSTANT) { - return false; - } - return FoldableConstantMatcher::Match(expr, bindings); +//===--------------------------------------------------------------------===// +// Perfect Hash Threshold +//===--------------------------------------------------------------------===// +void PerfectHashThresholdSetting::SetLocal(ClientContext &context, const Value &input) { + auto bits = input.GetValue(); + if (bits < 0 || bits > 32) { + throw ParserException("Perfect HT threshold out of range: should be within range 0 - 32"); } -}; + ClientConfig::GetConfig(context).perfect_ht_threshold = bits; +} -ConstantFoldingRule::ConstantFoldingRule(ExpressionRewriter &rewriter) : Rule(rewriter) { - auto op = make_unique(); - root = move(op); +Value PerfectHashThresholdSetting::GetSetting(ClientContext &context) { + return Value::BIGINT(ClientConfig::GetConfig(context).perfect_ht_threshold); } -unique_ptr ConstantFoldingRule::Apply(LogicalOperator &op, vector &bindings, - bool &changes_made, bool is_root) { - auto root = bindings[0]; - // the root is a scalar expression that we have to fold - D_ASSERT(root->IsFoldable() && root->type != ExpressionType::VALUE_CONSTANT); +//===--------------------------------------------------------------------===// +// PreserveIdentifierCase +//===--------------------------------------------------------------------===// +void PreserveIdentifierCase::SetLocal(ClientContext &context, const Value &input) { + ClientConfig::GetConfig(context).preserve_identifier_case = input.GetValue(); +} - // use an ExpressionExecutor to execute the expression +Value PreserveIdentifierCase::GetSetting(ClientContext &context) { + return Value::BOOLEAN(ClientConfig::GetConfig(context).preserve_identifier_case); +} - Value result_value; - if (!ExpressionExecutor::TryEvaluateScalar(*root, result_value)) { - return nullptr; +//===--------------------------------------------------------------------===// +// Profiler History Size +//===--------------------------------------------------------------------===// +void ProfilerHistorySize::SetLocal(ClientContext &context, const Value &input) { + auto size = input.GetValue(); + if (size <= 0) { + throw ParserException("Size should be >= 0"); } - D_ASSERT(result_value.type().InternalType() == root->return_type.InternalType()); - // now get the value from the result vector and insert it back into the plan as a constant expression - return make_unique(result_value); + context.query_profiler_history->SetProfilerHistorySize(size); } -} // namespace duckdb +Value ProfilerHistorySize::GetSetting(ClientContext &context) { + return Value(); +} +//===--------------------------------------------------------------------===// +// Profile Output +//===--------------------------------------------------------------------===// +void ProfileOutputSetting::SetLocal(ClientContext &context, const Value &input) { + auto &config = ClientConfig::GetConfig(context); + auto parameter = input.ToString(); + config.profiler_save_location = parameter; +} +Value ProfileOutputSetting::GetSetting(ClientContext &context) { + auto &config = ClientConfig::GetConfig(context); + return Value(config.profiler_save_location); +} +//===--------------------------------------------------------------------===// +// Profiling Mode +//===--------------------------------------------------------------------===// +void ProfilingModeSetting::SetLocal(ClientContext &context, const Value &input) { + auto parameter = StringUtil::Lower(input.ToString()); + auto &config = ClientConfig::GetConfig(context); + if (parameter == "standard") { + config.enable_profiler = true; + config.enable_detailed_profiling = false; + } else if (parameter == "detailed") { + config.enable_profiler = true; + config.enable_detailed_profiling = true; + } else { + throw ParserException("Unrecognized profiling mode \"%s\", supported formats: [standard, detailed]", parameter); + } +} +Value ProfilingModeSetting::GetSetting(ClientContext &context) { + auto &config = ClientConfig::GetConfig(context); + if (!config.enable_profiler) { + return Value(); + } + return Value(config.enable_detailed_profiling ? "detailed" : "standard"); +} +//===--------------------------------------------------------------------===// +// Progress Bar Time +//===--------------------------------------------------------------------===// +void ProgressBarTimeSetting::SetLocal(ClientContext &context, const Value &input) { + ClientConfig::GetConfig(context).wait_time = input.GetValue(); + ClientConfig::GetConfig(context).enable_progress_bar = true; +} +Value ProgressBarTimeSetting::GetSetting(ClientContext &context) { + return Value::BIGINT(ClientConfig::GetConfig(context).wait_time); +} +//===--------------------------------------------------------------------===// +// Schema +//===--------------------------------------------------------------------===// +void SchemaSetting::SetLocal(ClientContext &context, const Value &input) { + auto parameter = input.ToString(); + context.catalog_search_path->Set(parameter, true); +} +Value SchemaSetting::GetSetting(ClientContext &context) { + return SearchPathSetting::GetSetting(context); +} +//===--------------------------------------------------------------------===// +// Search Path +//===--------------------------------------------------------------------===// +void SearchPathSetting::SetLocal(ClientContext &context, const Value &input) { + auto parameter = input.ToString(); + context.catalog_search_path->Set(parameter, false); +} -namespace duckdb { +Value SearchPathSetting::GetSetting(ClientContext &context) { + return Value(StringUtil::Join(context.catalog_search_path->GetSetPaths(), ",")); +} -DatePartSimplificationRule::DatePartSimplificationRule(ExpressionRewriter &rewriter) : Rule(rewriter) { - auto func = make_unique(); - func->function = make_unique("date_part"); - func->matchers.push_back(make_unique()); - func->matchers.push_back(make_unique()); - func->policy = SetMatcher::Policy::ORDERED; - root = move(func); +//===--------------------------------------------------------------------===// +// Temp Directory +//===--------------------------------------------------------------------===// +void TempDirectorySetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) { + config.temporary_directory = input.ToString(); + config.use_temporary_directory = !config.temporary_directory.empty(); + if (db) { + auto &buffer_manager = BufferManager::GetBufferManager(*db); + buffer_manager.SetTemporaryDirectory(config.temporary_directory); + } } -unique_ptr DatePartSimplificationRule::Apply(LogicalOperator &op, vector &bindings, - bool &changes_made, bool is_root) { - auto &date_part = (BoundFunctionExpression &)*bindings[0]; - auto &constant_expr = (BoundConstantExpression &)*bindings[1]; - auto &constant = constant_expr.value; +Value TempDirectorySetting::GetSetting(ClientContext &context) { + auto &buffer_manager = BufferManager::GetBufferManager(context); + return Value(buffer_manager.GetTemporaryDirectory()); +} - if (constant.is_null) { - // NULL specifier: return constant NULL - return make_unique(Value(date_part.return_type)); - } - // otherwise check the specifier - auto specifier = GetDatePartSpecifier(constant.str_value); - string new_function_name; - switch (specifier) { - case DatePartSpecifier::YEAR: - new_function_name = "year"; - break; - case DatePartSpecifier::MONTH: - new_function_name = "month"; - break; - case DatePartSpecifier::DAY: - new_function_name = "day"; - break; - case DatePartSpecifier::DECADE: - new_function_name = "decade"; - break; - case DatePartSpecifier::CENTURY: - new_function_name = "century"; - break; - case DatePartSpecifier::MILLENNIUM: - new_function_name = "millenium"; - break; - case DatePartSpecifier::QUARTER: - new_function_name = "quarter"; - break; - case DatePartSpecifier::WEEK: - new_function_name = "week"; - break; - case DatePartSpecifier::YEARWEEK: - new_function_name = "yearweek"; - break; - case DatePartSpecifier::DOW: - new_function_name = "dayofweek"; - break; - case DatePartSpecifier::ISODOW: - new_function_name = "isodow"; - break; - case DatePartSpecifier::DOY: - new_function_name = "dayofyear"; - break; - case DatePartSpecifier::EPOCH: - new_function_name = "epoch"; - break; - case DatePartSpecifier::MICROSECONDS: - new_function_name = "microsecond"; - break; - case DatePartSpecifier::MILLISECONDS: - new_function_name = "millisecond"; - break; - case DatePartSpecifier::SECOND: - new_function_name = "second"; - break; - case DatePartSpecifier::MINUTE: - new_function_name = "minute"; - break; - case DatePartSpecifier::HOUR: - new_function_name = "hour"; - break; - default: - return nullptr; +//===--------------------------------------------------------------------===// +// Threads Setting +//===--------------------------------------------------------------------===// +void ThreadsSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) { + config.maximum_threads = input.GetValue(); + if (db) { + TaskScheduler::GetScheduler(*db).SetThreads(config.maximum_threads); } - // found a replacement function: bind it - vector> children; - children.push_back(move(date_part.children[1])); +} - string error; - auto function = ScalarFunction::BindScalarFunction(rewriter.context, DEFAULT_SCHEMA, new_function_name, - move(children), error, false); - if (!function) { - throw BinderException(error); - } - return move(function); +Value ThreadsSetting::GetSetting(ClientContext &context) { + auto &config = DBConfig::GetConfig(context); + return Value::BIGINT(config.maximum_threads); } } // namespace duckdb @@ -113142,200 +117264,99 @@ unique_ptr DatePartSimplificationRule::Apply(LogicalOperator &op, ve - - - namespace duckdb { -DistributivityRule::DistributivityRule(ExpressionRewriter &rewriter) : Rule(rewriter) { - // we match on an OR expression within a LogicalFilter node - root = make_unique(); - root->expr_type = make_unique(ExpressionType::CONJUNCTION_OR); +StreamQueryResult::StreamQueryResult(StatementType statement_type, shared_ptr context, + vector types, vector names) + : QueryResult(QueryResultType::STREAM_RESULT, statement_type, move(types), move(names)), context(move(context)) { } -void DistributivityRule::AddExpressionSet(Expression &expr, expression_set_t &set) { - if (expr.type == ExpressionType::CONJUNCTION_AND) { - auto &and_expr = (BoundConjunctionExpression &)expr; - for (auto &child : and_expr.children) { - set.insert(child.get()); - } - } else { - set.insert(&expr); - } +StreamQueryResult::~StreamQueryResult() { } -unique_ptr DistributivityRule::ExtractExpression(BoundConjunctionExpression &conj, idx_t idx, - Expression &expr) { - auto &child = conj.children[idx]; - unique_ptr result; - if (child->type == ExpressionType::CONJUNCTION_AND) { - // AND, remove expression from the list - 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]); - and_expr.children.erase(and_expr.children.begin() + i); - break; - } - } - if (and_expr.children.size() == 1) { - conj.children[idx] = move(and_expr.children[0]); - } +string StreamQueryResult::ToString() { + string result; + if (success) { + result = HeaderToString(); + result += "[[STREAM RESULT]]"; } 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); - conj.children[idx] = nullptr; + result = error + "\n"; } - D_ASSERT(result); return result; } -unique_ptr DistributivityRule::Apply(LogicalOperator &op, vector &bindings, - bool &changes_made, bool is_root) { - auto initial_or = (BoundConjunctionExpression *)bindings[0]; - - // we want to find expressions that occur in each of the children of the OR - // i.e. (X AND A) OR (X AND B) => X occurs in all branches - // first, for the initial child, we create an expression set of which expressions occur - // this is our initial candidate set (in the example: [X, A]) - expression_set_t candidate_set; - AddExpressionSet(*initial_or->children[0], candidate_set); - // now for each of the remaining children, we create a set again and intersect them - // in our example: the second set would be [X, B] - // the intersection would leave [X] - for (idx_t i = 1; i < initial_or->children.size(); i++) { - expression_set_t next_set; - AddExpressionSet(*initial_or->children[i], next_set); - expression_set_t intersect_result; - for (auto &expr : candidate_set) { - if (next_set.find(expr) != next_set.end()) { - intersect_result.insert(expr); - } - } - candidate_set = intersect_result; +unique_ptr StreamQueryResult::LockContext() { + if (!context) { + throw InvalidInputException("Attempting to execute an unsuccessful or closed pending query result\nError: %s", + error); } - if (candidate_set.empty()) { - // nothing found: abort - return nullptr; + return context->LockContext(); +} + +void StreamQueryResult::CheckExecutableInternal(ClientContextLock &lock) { + if (!IsOpenInternal(lock)) { + throw InvalidInputException("Attempting to execute an unsuccessful or closed pending query result\nError: %s", + error); } - // now for each of the remaining expressions in the candidate set we know that it is contained in all branches of - // the OR - auto new_root = make_unique(ExpressionType::CONJUNCTION_AND); - for (auto &expr : candidate_set) { - D_ASSERT(initial_or->children.size() > 0); +} - // extract the expression from the first child of the OR - auto result = ExtractExpression(*initial_or, 0, (Expression &)*expr); - // now for the subsequent expressions, simply remove the expression - for (idx_t i = 1; i < initial_or->children.size(); i++) { - ExtractExpression(*initial_or, i, *result); - } - // now we add the expression to the new root - new_root->children.push_back(move(result)); +unique_ptr StreamQueryResult::FetchRaw() { + unique_ptr chunk; + { + auto lock = LockContext(); + CheckExecutableInternal(*lock); + chunk = context->Fetch(*lock, *this); + } + if (!chunk || chunk->ColumnCount() == 0 || chunk->size() == 0) { + Close(); + return nullptr; } + return chunk; +} - // check if we completely erased one of the children of the OR - // this happens if we have an OR in the form of "X OR (X AND A)" - // the left child will be completely empty, as it only contains common expressions - // in this case, any other children are not useful: - // X OR (X AND A) is the same as "X" - // since (1) only tuples that do not qualify "X" will not pass this predicate - // and (2) all tuples that qualify "X" will pass this predicate - for (idx_t i = 0; i < initial_or->children.size(); i++) { - if (!initial_or->children[i]) { - if (new_root->children.size() <= 1) { - return move(new_root->children[0]); - } else { - return move(new_root); - } - } +unique_ptr StreamQueryResult::Materialize() { + if (!success) { + return make_unique(error); } - // 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])); - } 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)); + auto result = make_unique(statement_type, types, names); + while (true) { + auto chunk = Fetch(); + if (!chunk || chunk->size() == 0) { + break; } - new_root->children.push_back(move(new_or)); + result->collection.Append(*chunk); } - // finally return the new root - if (new_root->children.size() == 1) { - return move(new_root->children[0]); + if (!success) { + return make_unique(error); } - return move(new_root); -} - -} // namespace duckdb - - - - - - - - - -namespace duckdb { - -EmptyNeedleRemovalRule::EmptyNeedleRemovalRule(ExpressionRewriter &rewriter) : Rule(rewriter) { - // match on a FunctionExpression that has a foldable ConstantExpression - auto func = make_unique(); - func->matchers.push_back(make_unique()); - func->matchers.push_back(make_unique()); - func->policy = SetMatcher::Policy::SOME; - - unordered_set functions = {"prefix", "contains", "suffix"}; - func->function = make_unique(functions); - root = move(func); + return result; } -unique_ptr EmptyNeedleRemovalRule::Apply(LogicalOperator &op, vector &bindings, - bool &changes_made, bool is_root) { - auto root = (BoundFunctionExpression *)bindings[0]; - D_ASSERT(root->children.size() == 2); - (void)root; - auto prefix_expr = bindings[2]; - - // the constant_expr is a scalar expression that we have to fold - if (!prefix_expr->IsFoldable()) { - return nullptr; +bool StreamQueryResult::IsOpenInternal(ClientContextLock &lock) { + bool invalidated = !success || !context; + if (!invalidated) { + invalidated = !context->IsActiveResult(lock, this); } - D_ASSERT(root->return_type.id() == LogicalTypeId::BOOLEAN); - - auto prefix_value = ExpressionExecutor::EvaluateScalar(*prefix_expr); + return !invalidated; +} - if (prefix_value.is_null) { - return make_unique(Value(LogicalType::BOOLEAN)); +bool StreamQueryResult::IsOpen() { + if (!success || !context) { + return false; } + auto lock = LockContext(); + return IsOpenInternal(*lock); +} - D_ASSERT(prefix_value.type() == prefix_expr->return_type); - auto needle_string = prefix_value.str_value; - - // PREFIX('xyz', '') is TRUE - // 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 nullptr; +void StreamQueryResult::Close() { + context.reset(); } } // namespace duckdb - - - - - //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/optimizer/matcher/type_matcher_id.hpp +// duckdb/optimizer/column_lifetime_optimizer.hpp // // //===----------------------------------------------------------------------===// @@ -113344,308 +117365,197 @@ unique_ptr EmptyNeedleRemovalRule::Apply(LogicalOperator &op, vector + + namespace duckdb { +class BoundColumnRefExpression; -//! The TypeMatcherId class contains a set of matchers that can be used to pattern match TypeIds for Rules -class TypeMatcherId : public TypeMatcher { +//! 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 TypeMatcherId(LogicalTypeId type_id_p) : type_id(type_id_p) { + explicit ColumnLifetimeAnalyzer(bool is_root = false) : everything_referenced(is_root) { } - bool Match(const LogicalType &type) override { - return type.id() == this->type_id; - } + 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: - LogicalTypeId type_id; -}; + //! 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 { -EnumComparisonRule::EnumComparisonRule(ExpressionRewriter &rewriter) : Rule(rewriter) { - // match on a ComparisonExpression that is an Equality and has a VARCHAR and ENUM as its children - auto op = make_unique(); - // Enum requires expression to be root - op->expr_type = make_unique(ExpressionType::COMPARE_EQUAL); - for (idx_t i = 0; i < 2; i++) { - auto child = make_unique(); - child->type = make_unique(LogicalTypeId::VARCHAR); - child->matcher = make_unique(); - child->matcher->type = make_unique(LogicalTypeId::ENUM); - op->matchers.push_back(move(child)); +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]); + } } - root = move(op); } -bool AreMatchesPossible(LogicalType &left, LogicalType &right) { - LogicalType *small_enum, *big_enum; - if (EnumType::GetSize(left) < EnumType::GetSize(right)) { - small_enum = &left; - big_enum = &right; - } else { - small_enum = &right; - big_enum = &left; +void ColumnLifetimeAnalyzer::GenerateProjectionMap(vector bindings, + column_binding_set_t &unused_bindings, + vector &projection_map) { + if (unused_bindings.empty()) { + return; } - auto string_vec = EnumType::GetValuesInsertOrder(*small_enum); - for (auto &key : string_vec) { - if (EnumType::GetPos(*big_enum, key) != -1) { - return true; + // 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); } } - return false; -} -unique_ptr EnumComparisonRule::Apply(LogicalOperator &op, vector &bindings, - bool &changes_made, bool is_root) { - - auto root = (BoundComparisonExpression *)bindings[0]; - auto left_child = (BoundCastExpression *)bindings[1]; - auto right_child = (BoundCastExpression *)bindings[3]; - - if (!AreMatchesPossible(left_child->child->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)); - } - - if (!is_root || op.type != LogicalOperatorType::LOGICAL_FILTER) { - return nullptr; + if (projection_map.size() == bindings.size()) { + projection_map.clear(); } - - auto cast_left_to_right = - make_unique(move(left_child->child), right_child->child->return_type); - - return make_unique(root->type, move(cast_left_to_right), move(right_child->child)); } -} // namespace duckdb - - - - - -namespace duckdb { - -InClauseSimplificationRule::InClauseSimplificationRule(ExpressionRewriter &rewriter) : Rule(rewriter) { - // match on InClauseExpression that has a ConstantExpression as a check - auto op = make_unique(); - op->policy = SetMatcher::Policy::SOME; - root = move(op); +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); } -unique_ptr InClauseSimplificationRule::Apply(LogicalOperator &op, vector &bindings, - bool &changes_made, bool is_root) { - D_ASSERT(bindings[0]->expression_class == ExpressionClass::BOUND_OPERATOR); - auto expr = (BoundOperatorExpression *)bindings[0]; - if (expr->children[0]->expression_class != ExpressionClass::BOUND_CAST) { - return nullptr; - } - auto cast_expression = (BoundCastExpression *)expr->children[0].get(); - if (cast_expression->child->expression_class != ExpressionClass::BOUND_COLUMN_REF) { - return nullptr; - } - //! Here we check if we can apply the expression on the constant side - auto target_type = cast_expression->source_type(); - if (!BoundCastExpression::CastIsInvertible(target_type, cast_expression->return_type)) { - return nullptr; - } - vector> cast_list; - //! First check if we can cast all children - for (size_t i = 1; i < expr->children.size(); i++) { - if (expr->children[i]->expression_class != ExpressionClass::BOUND_CONSTANT) { - return nullptr; - } - D_ASSERT(expr->children[i]->IsFoldable()); - auto constant_value = ExpressionExecutor::EvaluateScalar(*expr->children[i]); - auto new_constant = constant_value.TryCastAs(target_type); - if (!new_constant) { - return nullptr; - } else { - auto new_constant_expr = make_unique(constant_value); - cast_list.push_back(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] = move(new_constant_expr); - } - //! We can cast the full list, so we move the column - expr->children[0] = move(cast_expression->child); - return nullptr; -} - -} // namespace duckdb - - - - - - - - -namespace duckdb { - -LikeOptimizationRule::LikeOptimizationRule(ExpressionRewriter &rewriter) : Rule(rewriter) { - // match on a FunctionExpression that has a foldable ConstantExpression - auto func = make_unique(); - func->matchers.push_back(make_unique()); - func->matchers.push_back(make_unique()); - func->policy = SetMatcher::Policy::ORDERED; - // we match on LIKE ("~~") and NOT LIKE ("!~~") - func->function = make_unique(unordered_set {"!~~", "~~"}); - root = move(func); -} - -static bool PatternIsConstant(const string &pattern) { - for (idx_t i = 0; i < pattern.size(); i++) { - if (pattern[i] == '%' || pattern[i] == '_') { - return false; - } +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; } - return true; -} - -static bool PatternIsPrefix(const string &pattern) { - idx_t i; - for (i = pattern.size(); i > 0; i--) { - if (pattern[i - 1] != '%') { + case LogicalOperatorType::LOGICAL_DELIM_JOIN: + case LogicalOperatorType::LOGICAL_COMPARISON_JOIN: { + if (everything_referenced) { break; } - } - if (i == pattern.size()) { - // no trailing % - // cannot be a prefix - return false; - } - // continue to look in the string - // if there is a % or _ in the string (besides at the very end) this is not a prefix match - for (; i > 0; i--) { - if (pattern[i - 1] == '%' || pattern[i - 1] == '_') { - return false; - } - } - return true; -} - -static bool PatternIsSuffix(const string &pattern) { - idx_t i; - for (i = 0; i < pattern.size(); i++) { - if (pattern[i] != '%') { + 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; } - } - if (i == 0) { - // no leading % - // cannot be a suffix - return false; - } - // continue to look in the string - // if there is a % or _ in the string (besides at the beginning) this is not a suffix match - for (; i < pattern.size(); i++) { - if (pattern[i] == '%' || pattern[i] == '_') { - return false; + // 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; + } } - } - return true; -} - -static bool PatternIsContains(const string &pattern) { - idx_t start; - idx_t end; - for (start = 0; start < pattern.size(); start++) { - if (pattern[start] != '%') { + 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; } - for (end = pattern.size(); end > 0; end--) { - if (pattern[end - 1] != '%') { - break; + 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; } - if (start == 0 || end == pattern.size()) { - // contains requires both a leading AND a trailing % - return false; + 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; } - // check if there are any other special characters in the string - // if there is a % or _ in the string (besides at the beginning/end) this is not a contains match - for (idx_t i = start; i < end; i++) { - if (pattern[i] == '%' || pattern[i] == '_') { - return false; + case LogicalOperatorType::LOGICAL_FILTER: { + auto &filter = (LogicalFilter &)op; + if (everything_referenced) { + break; } - } - return true; -} + // filter, figure out which columns are not needed after the filter + column_binding_set_t unused_bindings; + ExtractUnusedColumnBindings(op.children[0]->GetColumnBindings(), unused_bindings); -unique_ptr LikeOptimizationRule::Apply(LogicalOperator &op, vector &bindings, - bool &changes_made, bool is_root) { - auto root = (BoundFunctionExpression *)bindings[0]; - auto constant_expr = (BoundConstantExpression *)bindings[2]; - D_ASSERT(root->children.size() == 2); + // now recurse into the filter and its children + StandardVisitOperator(op); - if (constant_expr->value.is_null) { - return make_unique(Value(root->return_type)); + // then generate the projection map + GenerateProjectionMap(op.children[0]->GetColumnBindings(), unused_bindings, filter.projection_map); + return; } - - // the constant_expr is a scalar expression that we have to fold - if (!constant_expr->IsFoldable()) { - return nullptr; + default: + break; } + StandardVisitOperator(op); +} - auto constant_value = ExpressionExecutor::EvaluateScalar(*constant_expr); - D_ASSERT(constant_value.type() == constant_expr->return_type); - auto patt_str = constant_value.str_value; - - bool is_not_like = root->function.name == "!~~"; - if (PatternIsConstant(patt_str)) { - // Pattern is constant - return make_unique(is_not_like ? ExpressionType::COMPARE_NOTEQUAL - : ExpressionType::COMPARE_EQUAL, - move(root->children[0]), move(root->children[1])); - } else if (PatternIsPrefix(patt_str)) { - // Prefix LIKE pattern : [^%_]*[%]+, ignoring underscore - return ApplyRule(root, PrefixFun::GetFunction(), patt_str, is_not_like); - } else if (PatternIsSuffix(patt_str)) { - // Suffix LIKE pattern: [%]+[^%_]*, ignoring underscore - return ApplyRule(root, SuffixFun::GetFunction(), patt_str, is_not_like); - } else if (PatternIsContains(patt_str)) { - // Contains LIKE pattern: [%]+[^%_]*[%]+, ignoring underscore - return ApplyRule(root, ContainsFun::GetFunction(), patt_str, is_not_like); - } +unique_ptr ColumnLifetimeAnalyzer::VisitReplace(BoundColumnRefExpression &expr, + unique_ptr *expr_ptr) { + column_references.insert(expr.binding); return nullptr; } -unique_ptr LikeOptimizationRule::ApplyRule(BoundFunctionExpression *expr, ScalarFunction function, - 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); - - // removing "%" from the pattern - pattern.erase(std::remove(pattern.begin(), pattern.end(), '%'), pattern.end()); - - new_function->children[1] = make_unique(Value(move(pattern))); - - result = 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); - } - - return result; +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 +// +// +//===----------------------------------------------------------------------===// @@ -113653,121 +117563,31 @@ unique_ptr LikeOptimizationRule::ApplyRule(BoundFunctionExpression * namespace duckdb { +//! The CommonAggregateOptimizer optimizer eliminates duplicate aggregates from aggregate nodes +class CommonAggregateOptimizer : public LogicalOperatorVisitor { +public: + void VisitOperator(LogicalOperator &op) override; -MoveConstantsRule::MoveConstantsRule(ExpressionRewriter &rewriter) : Rule(rewriter) { - auto op = make_unique(); - op->matchers.push_back(make_unique()); - op->policy = SetMatcher::Policy::UNORDERED; - - auto arithmetic = make_unique(); - // we handle multiplication, addition and subtraction because those are "easy" - // integer division makes the division case difficult - // e.g. [x / 2 = 3] means [x = 6 OR x = 7] because of truncation -> no clean rewrite rules - arithmetic->function = make_unique(unordered_set {"+", "-", "*"}); - // we match only on integral numeric types - arithmetic->type = make_unique(); - 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); -} - -unique_ptr MoveConstantsRule::Apply(LogicalOperator &op, vector &bindings, bool &changes_made, - bool is_root) { - auto comparison = (BoundComparisonExpression *)bindings[0]; - auto outer_constant = (BoundConstantExpression *)bindings[1]; - auto arithmetic = (BoundFunctionExpression *)bindings[2]; - auto inner_constant = (BoundConstantExpression *)bindings[3]; - if (!arithmetic->return_type.IsNumeric()) { - return nullptr; - } - if (inner_constant->value.is_null || outer_constant->value.is_null) { - return make_unique(Value(comparison->return_type)); - } +private: + unique_ptr VisitReplace(BoundColumnRefExpression &expr, unique_ptr *expr_ptr) override; - int arithmetic_child_index = arithmetic->children[0].get() == inner_constant ? 1 : 0; - auto &op_type = arithmetic->function.name; - if (op_type == "+") { - // [x + 1 COMP 10] OR [1 + x COMP 10] - // order does not matter in addition: - // simply change right side to 10-1 (outer_constant - inner_constant) - outer_constant->value = outer_constant->value - inner_constant->value; - } else if (op_type == "-") { - // [x - 1 COMP 10] O R [1 - x COMP 10] - // order matters in subtraction: - if (arithmetic_child_index == 0) { - // [x - 1 COMP 10] - // change right side to 10+1 (outer_constant + inner_constant) - outer_constant->value = outer_constant->value + inner_constant->value; - } else { - // [1 - x COMP 10] - // change right side to 1-10=-9 - outer_constant->value = inner_constant->value - outer_constant->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); - } - } else { - D_ASSERT(op_type == "*"); - // [x * 2 COMP 10] OR [2 * x COMP 10] - // order does not matter in multiplication: - // change right side to 10/2 (outer_constant / inner_constant) - // but ONLY if outer_constant is cleanly divisible by the inner_constant - if (inner_constant->value == 0) { - // x * 0, the result is either 0 or NULL - // thus the final result will be either [TRUE, FALSE] or [NULL], depending - // on if 0 matches the comparison criteria with the RHS - // for now we don't fold, but we can fold to "ConstantOrNull" - return nullptr; - } - if (ValueOperations::Modulo(outer_constant->value, inner_constant->value) != 0) { - // not cleanly divisible, the result will be either FALSE or NULL - // for now, we don't do anything - return nullptr; - } - if (inner_constant->value < 0) { - // multiply by negative value, need to flip expression - comparison->type = FlipComparisionExpression(comparison->type); - } - // else divide the RHS by the LHS - outer_constant->value = outer_constant->value / inner_constant->value; - } - // replace left side with x - // first extract x from the arithmetic expression - auto arithmetic_child = move(arithmetic->children[arithmetic_child_index]); - // then place in the comparison - if (comparison->left.get() == outer_constant) { - comparison->right = move(arithmetic_child); - } else { - comparison->left = move(arithmetic_child); - } - changes_made = true; - return nullptr; -} + void ExtractCommonAggregates(LogicalAggregate &aggr); +private: + column_binding_map_t aggregate_map; +}; } // namespace duckdb -namespace duckdb { - -unique_ptr StatisticsPropagator::PropagateExpression(BoundAggregateExpression &aggr, - unique_ptr *expr_ptr) { - vector> stats; - stats.reserve(aggr.children.size()); - for (auto &child : aggr.children) { - stats.push_back(PropagateExpression(child)); - } - if (!aggr.function.statistics) { - return nullptr; - } - return aggr.function.statistics(context, aggr, aggr.bind_info.get(), stats, node_stats.get()); -} - -} // namespace duckdb - +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/expression_map.hpp +// +// +//===----------------------------------------------------------------------===// @@ -113776,137 +117596,90 @@ unique_ptr StatisticsPropagator::PropagateExpression(BoundAggreg namespace duckdb { +class Expression; -unique_ptr CastHugeintToSmallestType(unique_ptr expr, NumericStatistics &num_stats) { - // Compute range - if (num_stats.min.is_null || num_stats.max.is_null) { - return expr; - } - - auto min_val = num_stats.min.GetValue(); - auto max_val = num_stats.max.GetValue(); - if (max_val < min_val) { - return expr; - } - - // Prevent overflow - if (min_val < NumericLimits().Minimum() && max_val > NumericLimits().Maximum()) { - return expr; +struct ExpressionHashFunction { + uint64_t operator()(const BaseExpression *const &expr) const { + return (uint64_t)expr->Hash(); } +}; - // Compute range - auto range = max_val - min_val; - - // Check if this range fits in a smaller type - LogicalType cast_type; - if (range < NumericLimits().Maximum()) { - cast_type = LogicalType::UTINYINT; - } else if (range < NumericLimits().Maximum()) { - cast_type = LogicalType::USMALLINT; - } else if (range < NumericLimits().Maximum()) { - cast_type = LogicalType::UINTEGER; - } else if (range < NumericLimits().Maximum()) { - cast_type = LogicalTypeId::UBIGINT; - } else { - return expr; +struct ExpressionEquality { + bool operator()(const BaseExpression *const &a, const BaseExpression *const &b) const { + return a->Equals(b); } +}; - // Create expression to map to a smaller range - auto input_type = expr->return_type; - auto minimum_expr = make_unique(Value::CreateValue(min_val)); - vector> arguments; - arguments.push_back(move(expr)); - arguments.push_back(move(minimum_expr)); - auto minus_expr = make_unique(input_type, SubtractFun::GetFunction(input_type, input_type), - move(arguments), nullptr, true); +template +using expression_map_t = unordered_map; - // Cast to smaller type - return make_unique(move(minus_expr), cast_type); -} +using expression_set_t = unordered_set; -template -unique_ptr TemplatedCastToSmallestType(unique_ptr expr, NumericStatistics &num_stats) { - // Compute range - if (num_stats.min.is_null || num_stats.max.is_null) { - return expr; - } +} // namespace duckdb - auto signed_min_val = num_stats.min.GetValue(); - auto signed_max_val = num_stats.max.GetValue(); - if (signed_max_val < signed_min_val) { - return expr; - } - // Prevent signed integer overflow - we can't range map these - if (std::is_signed() && signed_min_val < -((T)1 << (sizeof(T) * 8 - 2)) && - signed_max_val > ((T)1 << (sizeof(T) * 8 - 2))) { - return expr; - } - // Compute range, cast to unsigned to prevent comparing signed with unsigned - auto signed_range = signed_max_val - signed_min_val; - auto range = static_cast::type>(signed_range); +namespace duckdb { - // Check if this range fits in a smaller type - LogicalType cast_type; - if (range < NumericLimits().Maximum()) { - cast_type = LogicalType::UTINYINT; - } else if (sizeof(T) > sizeof(uint16_t) && range < NumericLimits().Maximum()) { - cast_type = LogicalType::USMALLINT; - } else if (sizeof(T) > sizeof(uint32_t) && range < NumericLimits().Maximum()) { - cast_type = LogicalType::UINTEGER; - } else { - return expr; +void CommonAggregateOptimizer::VisitOperator(LogicalOperator &op) { + LogicalOperatorVisitor::VisitOperator(op); + switch (op.type) { + case LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY: + ExtractCommonAggregates((LogicalAggregate &)op); + break; + default: + break; } - - // Create expression to map to a smaller range - 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)); - auto minus_expr = make_unique(input_type, SubtractFun::GetFunction(input_type, input_type), - move(arguments), nullptr, true); - - // Cast to smaller type - return make_unique(move(minus_expr), cast_type); } -unique_ptr CastToSmallestType(unique_ptr expr, NumericStatistics &num_stats) { - auto physical_type = expr->return_type.InternalType(); - switch (physical_type) { - case PhysicalType::UINT8: - case PhysicalType::INT8: - return expr; - case PhysicalType::UINT16: - return TemplatedCastToSmallestType(move(expr), num_stats); - case PhysicalType::INT16: - return TemplatedCastToSmallestType(move(expr), num_stats); - case PhysicalType::UINT32: - return TemplatedCastToSmallestType(move(expr), num_stats); - case PhysicalType::INT32: - return TemplatedCastToSmallestType(move(expr), num_stats); - case PhysicalType::UINT64: - return TemplatedCastToSmallestType(move(expr), num_stats); - case PhysicalType::INT64: - return TemplatedCastToSmallestType(move(expr), num_stats); - case PhysicalType::INT128: - return CastHugeintToSmallestType(move(expr), num_stats); - default: - throw NotImplementedException("Unknown integer type!"); +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 StatisticsPropagator::PropagateAndCompress(unique_ptr &expr, unique_ptr &stats) { - stats = PropagateExpression(expr); - if (stats) { - if (expr->return_type.IsIntegral()) { - expr = CastToSmallestType(move(expr), (NumericStatistics &)*stats); +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 +// +// +//===----------------------------------------------------------------------===// + @@ -113914,290 +117687,194 @@ void StatisticsPropagator::PropagateAndCompress(unique_ptr &expr, un namespace duckdb { +class Binder; +struct CSEReplacementState; -unique_ptr StatisticsPropagator::PropagateExpression(BoundBetweenExpression &between, - unique_ptr *expr_ptr) { - // propagate in all the children - auto input_stats = PropagateExpression(between.input); - auto lower_stats = PropagateExpression(between.lower); - auto upper_stats = PropagateExpression(between.upper); - if (!input_stats) { - return nullptr; - } - auto lower_comparison = between.LowerComparisonType(); - auto upper_comparison = between.UpperComparisonType(); - // propagate the comparisons - auto lower_prune = FilterPropagateResult::NO_PRUNING_POSSIBLE; - auto upper_prune = FilterPropagateResult::NO_PRUNING_POSSIBLE; - if (lower_stats) { - lower_prune = PropagateComparison(*input_stats, *lower_stats, lower_comparison); - } - if (upper_stats) { - upper_prune = PropagateComparison(*input_stats, *upper_stats, upper_comparison); - } - if (lower_prune == FilterPropagateResult::FILTER_ALWAYS_TRUE && - upper_prune == FilterPropagateResult::FILTER_ALWAYS_TRUE) { - // both filters are always true: replace the between expression with a constant true - *expr_ptr = make_unique(Value::BOOLEAN(true)); - } else if (lower_prune == FilterPropagateResult::FILTER_ALWAYS_FALSE || - upper_prune == FilterPropagateResult::FILTER_ALWAYS_FALSE) { - // either one of the filters is always false: replace the between expression with a constant false - *expr_ptr = make_unique(Value::BOOLEAN(false)); - } else if (lower_prune == FilterPropagateResult::FILTER_FALSE_OR_NULL || - 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)); - } 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)); - } 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)); - } 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)); +//! 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) { } - return nullptr; -} +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 { -unique_ptr StatisticsPropagator::PropagateExpression(BoundCaseExpression &bound_case, - unique_ptr *expr_ptr) { - // propagate in all the children - auto result_stats = PropagateExpression(bound_case.else_expr); - for (auto &case_check : bound_case.case_checks) { - PropagateExpression(case_check.when_expr); - auto then_stats = PropagateExpression(case_check.then_expr); - if (!then_stats) { - result_stats.reset(); - } else if (result_stats) { - result_stats->Merge(*then_stats); - } - } - return result_stats; -} -} // namespace duckdb namespace duckdb { -static unique_ptr StatisticsOperationsNumericNumericCast(const BaseStatistics *input_p, - const LogicalType &target) { - auto &input = (NumericStatistics &)*input_p; +//! 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; - Value min = input.min, max = input.max; - if (!min.TryCastAs(target) || !max.TryCastAs(target)) { - // overflow in cast: bailout - return nullptr; - } - auto stats = make_unique(target, move(min), move(max)); - if (input.validity_stats) { - stats->validity_stats = input.validity_stats->Copy(); + CSENode() : count(1), column_index(DConstants::INVALID_INDEX) { } - return move(stats); -} +}; -static unique_ptr StatisticsNumericCastSwitch(const BaseStatistics *input, const LogicalType &target) { - switch (target.InternalType()) { - case PhysicalType::INT8: - case PhysicalType::INT16: - case PhysicalType::INT32: - case PhysicalType::INT64: - case PhysicalType::INT128: - case PhysicalType::FLOAT: - case PhysicalType::DOUBLE: - return StatisticsOperationsNumericNumericCast(input, target); - default: - return nullptr; - } -} +//! 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; +}; -unique_ptr StatisticsPropagator::PropagateExpression(BoundCastExpression &cast, - unique_ptr *expr_ptr) { - auto child_stats = PropagateExpression(cast.child); - if (!child_stats) { - return nullptr; - } - unique_ptr result_stats; - switch (cast.child->return_type.InternalType()) { - case PhysicalType::INT8: - case PhysicalType::INT16: - case PhysicalType::INT32: - case PhysicalType::INT64: - case PhysicalType::INT128: - case PhysicalType::FLOAT: - case PhysicalType::DOUBLE: - result_stats = StatisticsNumericCastSwitch(child_stats.get(), cast.return_type); +void CommonSubExpressionOptimizer::VisitOperator(LogicalOperator &op) { + switch (op.type) { + case LogicalOperatorType::LOGICAL_PROJECTION: + case LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY: + ExtractCommonSubExpresions(op); break; default: - return nullptr; - } - if (cast.try_cast && result_stats) { - result_stats->validity_stats = make_unique(true, true); - } - return result_stats; -} - -} // namespace duckdb - - - -namespace duckdb { - -unique_ptr StatisticsPropagator::PropagateExpression(BoundColumnRefExpression &colref, - unique_ptr *expr_ptr) { - auto stats = statistics_map.find(colref.binding); - if (stats == statistics_map.end()) { - return nullptr; + break; } - return stats->second->Copy(); + LogicalOperatorVisitor::VisitOperator(op); } -} // namespace duckdb - - - - - - -namespace duckdb { - -FilterPropagateResult StatisticsPropagator::PropagateComparison(BaseStatistics &left, BaseStatistics &right, - ExpressionType comparison) { - // only handle numerics for now - switch (left.type.InternalType()) { - case PhysicalType::BOOL: - case PhysicalType::INT8: - case PhysicalType::INT16: - case PhysicalType::INT32: - case PhysicalType::INT64: - case PhysicalType::INT128: - case PhysicalType::FLOAT: - case PhysicalType::DOUBLE: - break; +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: - return FilterPropagateResult::NO_PRUNING_POSSIBLE; - } - auto &lstats = (NumericStatistics &)left; - auto &rstats = (NumericStatistics &)right; - if (lstats.min.is_null || lstats.max.is_null || rstats.min.is_null || rstats.max.is_null) { - // no stats available: nothing to prune - return FilterPropagateResult::NO_PRUNING_POSSIBLE; + break; } - // the result of the propagation depend on whether or not either side has null values - // if there are null values present, we cannot say whether or not - bool has_null = lstats.CanHaveNull() || rstats.CanHaveNull(); - switch (comparison) { - case ExpressionType::COMPARE_EQUAL: - // l = r, if l.min > r.max or r.min > l.max equality is not possible - if (lstats.min > rstats.max || rstats.min > lstats.max) { - return has_null ? FilterPropagateResult::FILTER_FALSE_OR_NULL : FilterPropagateResult::FILTER_ALWAYS_FALSE; + 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 { - return FilterPropagateResult::NO_PRUNING_POSSIBLE; - } - case ExpressionType::COMPARE_GREATERTHAN: - // l > r - if (lstats.min > rstats.max) { - // if l.min > r.max, it is always true ONLY if neither side contains nulls - return has_null ? FilterPropagateResult::FILTER_TRUE_OR_NULL : FilterPropagateResult::FILTER_ALWAYS_TRUE; - } - // if r.min is bigger or equal to l.max, the filter is always false - if (rstats.min >= lstats.max) { - return has_null ? FilterPropagateResult::FILTER_FALSE_OR_NULL : FilterPropagateResult::FILTER_ALWAYS_FALSE; - } - return FilterPropagateResult::NO_PRUNING_POSSIBLE; - case ExpressionType::COMPARE_GREATERTHANOREQUALTO: - // l >= r - if (lstats.min >= rstats.max) { - // if l.min >= r.max, it is always true ONLY if neither side contains nulls - return has_null ? FilterPropagateResult::FILTER_TRUE_OR_NULL : FilterPropagateResult::FILTER_ALWAYS_TRUE; - } - // if r.min > l.max, the filter is always false - if (rstats.min > lstats.max) { - return has_null ? FilterPropagateResult::FILTER_FALSE_OR_NULL : FilterPropagateResult::FILTER_ALWAYS_FALSE; - } - return FilterPropagateResult::NO_PRUNING_POSSIBLE; - case ExpressionType::COMPARE_LESSTHAN: - // l < r - if (lstats.max < rstats.min) { - // if l.max < r.min, it is always true ONLY if neither side contains nulls - return has_null ? FilterPropagateResult::FILTER_TRUE_OR_NULL : FilterPropagateResult::FILTER_ALWAYS_TRUE; - } - // if l.min >= rstats.max, the filter is always false - if (lstats.min >= rstats.max) { - return has_null ? FilterPropagateResult::FILTER_FALSE_OR_NULL : FilterPropagateResult::FILTER_ALWAYS_FALSE; - } - return FilterPropagateResult::NO_PRUNING_POSSIBLE; - case ExpressionType::COMPARE_LESSTHANOREQUALTO: - // l <= r - if (lstats.max <= rstats.min) { - // if l.max <= r.min, it is always true ONLY if neither side contains nulls - return has_null ? FilterPropagateResult::FILTER_TRUE_OR_NULL : FilterPropagateResult::FILTER_ALWAYS_TRUE; - } - // if l.min > rstats.max, the filter is always false - if (lstats.min > rstats.max) { - return has_null ? FilterPropagateResult::FILTER_FALSE_OR_NULL : FilterPropagateResult::FILTER_ALWAYS_FALSE; + // we encountered this expression before, increment the occurrence count + node->second.count++; } - return FilterPropagateResult::NO_PRUNING_POSSIBLE; - default: - return FilterPropagateResult::NO_PRUNING_POSSIBLE; } + // recursively count the children + ExpressionIterator::EnumerateChildren(expr, [&](Expression &child) { CountExpressions(child, state); }); } -unique_ptr StatisticsPropagator::PropagateExpression(BoundComparisonExpression &expr, - unique_ptr *expr_ptr) { - auto left_stats = PropagateExpression(expr.left); - auto right_stats = PropagateExpression(expr.right); - if (!left_stats || !right_stats) { - return nullptr; +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; } - // propagate the statistics of the comparison operator - auto propagate_result = PropagateComparison(*left_stats, *right_stats, expr.type); - switch (propagate_result) { - case FilterPropagateResult::FILTER_ALWAYS_TRUE: - *expr_ptr = make_unique(Value::BOOLEAN(true)); - return PropagateExpression(*expr_ptr); - case FilterPropagateResult::FILTER_ALWAYS_FALSE: - *expr_ptr = make_unique(Value::BOOLEAN(false)); - 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)); - return nullptr; + // 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; + } } - 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)); - return nullptr; + // 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; + } } - default: - // FIXME: we can propagate nulls here, i.e. this expression will have nulls only if left and right has nulls - return nullptr; + 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 +// +// +//===----------------------------------------------------------------------===// @@ -114208,476 +117885,620 @@ unique_ptr StatisticsPropagator::PropagateExpression(BoundCompar namespace duckdb { -unique_ptr StatisticsPropagator::StatisticsFromValue(const Value &input) { - switch (input.type().InternalType()) { - case PhysicalType::BOOL: - case PhysicalType::INT8: - case PhysicalType::INT16: - case PhysicalType::INT32: - case PhysicalType::INT64: - case PhysicalType::INT128: - case PhysicalType::FLOAT: - case PhysicalType::DOUBLE: { - auto result = make_unique(input.type(), input, input); - result->validity_stats = make_unique(input.is_null, !input.is_null); - return move(result); - } - case PhysicalType::VARCHAR: { - auto result = make_unique(input.type()); - result->validity_stats = make_unique(input.is_null, !input.is_null); - if (!input.is_null) { - string_t str(input.str_value.c_str(), input.str_value.size()); - result->Update(str); - } - return move(result); - } - case PhysicalType::STRUCT: { - auto result = make_unique(input.type()); - result->validity_stats = make_unique(input.is_null, !input.is_null); - if (input.is_null) { - for (auto &child_stat : result->child_stats) { - child_stat.reset(); - } - } else { - D_ASSERT(result->child_stats.size() == input.struct_value.size()); - for (idx_t i = 0; i < result->child_stats.size(); i++) { - result->child_stats[i] = StatisticsFromValue(input.struct_value[i]); - } - } - return move(result); - } - case PhysicalType::LIST: { - auto result = make_unique(input.type()); - result->validity_stats = make_unique(input.is_null, !input.is_null); - if (input.is_null) { - result->child_stats.reset(); - } else { - for (auto &child_element : input.list_value) { - auto child_element_stats = StatisticsFromValue(child_element); - if (child_element_stats) { - result->child_stats->Merge(*child_element_stats); - } else { - result->child_stats.reset(); - } - } - } - return move(result); - } - default: - return nullptr; +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); -unique_ptr StatisticsPropagator::PropagateExpression(BoundConstantExpression &constant, - unique_ptr *expr_ptr) { - return StatisticsFromValue(constant.value); -} +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 *op_ptr, DeliminatorPlanUpdater &updater); + //! Replace references to a removed DelimGet, remove DelimJoins if all their DelimGets are gone + void UpdatePlan(LogicalOperator &op, expression_map_t &expr_map, + column_binding_map_t &projection_map); + //! Whether the operator has one or more children of type DELIM_GET + bool HasChildDelimGet(LogicalOperator &op); +}; } // namespace duckdb -namespace duckdb { -unique_ptr StatisticsPropagator::PropagateExpression(BoundFunctionExpression &func, - unique_ptr *expr_ptr) { - vector> stats; - stats.reserve(func.children.size()); - for (idx_t i = 0; i < func.children.size(); i++) { - stats.push_back(PropagateExpression(func.children[i])); - } - if (!func.function.statistics) { - return nullptr; - } - return func.function.statistics(context, func, func.bind_info.get(), stats); -} -} // namespace duckdb + namespace duckdb { -unique_ptr StatisticsPropagator::PropagateExpression(BoundOperatorExpression &expr, - unique_ptr *expr_ptr) { - bool all_have_stats = true; - vector> child_stats; - child_stats.reserve(expr.children.size()); - for (auto &child : expr.children) { - auto stats = PropagateExpression(child); - if (!stats) { - all_have_stats = false; - } - child_stats.push_back(move(stats)); +class DeliminatorPlanUpdater : LogicalOperatorVisitor { +public: + DeliminatorPlanUpdater() { } - if (!all_have_stats) { - return nullptr; - } - switch (expr.type) { - case ExpressionType::OPERATOR_COALESCE: - // COALESCE, merge stats of all children - for (idx_t i = 0; i < expr.children.size(); i++) { - D_ASSERT(child_stats[i]); - if (!child_stats[i]->CanHaveNoNull()) { - // this child is always NULL, we can remove it from the coalesce - // UNLESS there is only one node remaining - if (expr.children.size() > 1) { - expr.children.erase(expr.children.begin() + i); - child_stats.erase(child_stats.begin() + i); - i--; - } - } else if (!child_stats[i]->CanHaveNull()) { - // coalesce child cannot have NULL entries - // this is the last coalesce node that influences the result - // we can erase any children after this node - if (i + 1 < expr.children.size()) { - expr.children.erase(expr.children.begin() + i + 1, expr.children.end()); - child_stats.erase(child_stats.begin() + i + 1, child_stats.end()); - } - break; + //! Update the plan after a DelimGet has been removed + void VisitOperator(LogicalOperator &op) override; + void VisitExpression(unique_ptr *expression) override; + //! Whether the operator has one or more children of type DELIM_GET + bool HasChildDelimGet(LogicalOperator &op); + + expression_map_t expr_map; + column_binding_map_t projection_map; + unique_ptr temp_ptr; +}; + +void DeliminatorPlanUpdater::VisitOperator(LogicalOperator &op) { + VisitOperatorChildren(op); + VisitOperatorExpressions(op); + // now check if this is a delim join that can be removed + if (op.type == LogicalOperatorType::LOGICAL_DELIM_JOIN && !HasChildDelimGet(op)) { + auto &delim_join = (LogicalDelimJoin &)op; + auto decs = &delim_join.duplicate_eliminated_columns; + for (auto &cond : delim_join.conditions) { + if (cond.comparison != ExpressionType::COMPARE_EQUAL) { + continue; } - } - D_ASSERT(!expr.children.empty()); - 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]); - } else { - // coalesce of multiple entries - // merge the stats - for (idx_t i = 1; i < expr.children.size(); i++) { - child_stats[0]->Merge(*child_stats[i]); + auto &colref = (BoundColumnRefExpression &)*cond.right; + 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.null_values_are_equal = true; // projection_map[colref.binding]; } } - return 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 - *expr_ptr = make_unique(Value::BOOLEAN(false)); - return PropagateExpression(*expr_ptr); - } - return nullptr; - case ExpressionType::OPERATOR_IS_NOT_NULL: - if (!child_stats[0]->CanHaveNull()) { - // child has no null values: x IS NOT NULL will always be true - *expr_ptr = make_unique(Value::BOOLEAN(true)); - return PropagateExpression(*expr_ptr); + // change type if there are no more duplicate-eliminated columns + if (decs->empty()) { + delim_join.type = LogicalOperatorType::LOGICAL_COMPARISON_JOIN; } - return nullptr; - default: - return nullptr; } } -} // namespace duckdb +void DeliminatorPlanUpdater::VisitExpression(unique_ptr *expression) { + if (expr_map.find(expression->get()) != expr_map.end()) { + *expression = expr_map[expression->get()]->Copy(); + } else { + VisitExpressionChildren(**expression); + } +} +bool DeliminatorPlanUpdater::HasChildDelimGet(LogicalOperator &op) { + if (op.type == LogicalOperatorType::LOGICAL_DELIM_GET) { + return true; + } + for (auto &child : op.children) { + if (HasChildDelimGet(*child)) { + return true; + } + } + return false; +} +unique_ptr Deliminator::Optimize(unique_ptr op) { + vector *> candidates; + FindCandidates(&op, candidates); + for (auto candidate : candidates) { + DeliminatorPlanUpdater updater; + if (RemoveCandidate(candidate, updater)) { + updater.VisitOperator(*op); + } + } + return op; +} -namespace duckdb { +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; + } +} -unique_ptr StatisticsPropagator::PropagateStatistics(LogicalAggregate &aggr, - unique_ptr *node_ptr) { - // first propagate statistics in the child node - node_stats = PropagateStatistics(aggr.children[0]); +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; +} - // handle the groups: simply propagate statistics and assign the stats to the group binding - aggr.group_stats.resize(aggr.groups.size()); - for (idx_t group_idx = 0; group_idx < aggr.groups.size(); group_idx++) { - auto stats = PropagateExpression(aggr.groups[group_idx]); - aggr.group_stats[group_idx] = stats ? stats->Copy() : nullptr; - if (!stats) { - continue; +bool Deliminator::RemoveCandidate(unique_ptr *op_ptr, DeliminatorPlanUpdater &updater) { + auto &proj_or_agg = **op_ptr; + auto &join = (LogicalComparisonJoin &)*proj_or_agg.children[0]; + if (join.join_type != JoinType::INNER && join.join_type != JoinType::SEMI) { + 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 + vector nulls_are_not_equal_exprs; + for (auto &cond : join.conditions) { + if (cond.comparison != ExpressionType::COMPARE_EQUAL) { + // non-equality join condition + return false; } - if (aggr.grouping_sets.size() > 1) { - // aggregates with multiple grouping sets can introduce NULL values to certain groups - // FIXME: actually figure out WHICH groups can have null values introduced - stats->validity_stats = make_unique(true, true); - continue; + 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.null_values_are_equal) { + nulls_are_not_equal_exprs.push_back(other_side); } - ColumnBinding group_binding(aggr.group_index, group_idx); - statistics_map[group_binding] = move(stats); } - // propagate statistics in the aggregates - for (idx_t aggregate_idx = 0; aggregate_idx < aggr.expressions.size(); aggregate_idx++) { - auto stats = PropagateExpression(aggr.expressions[aggregate_idx]); - if (!stats) { - continue; + // 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; + 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; + for (auto &cb : agg.GetColumnBindings()) { + updater.projection_map[cb] = true; + 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; + } + } } - ColumnBinding aggregate_binding(aggr.aggregate_index, aggregate_idx); - statistics_map[aggregate_binding] = 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); + // 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; } } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/expression_heuristics.hpp +// +// +//===----------------------------------------------------------------------===// -namespace duckdb { -unique_ptr StatisticsPropagator::PropagateStatistics(LogicalCrossProduct &cp, - unique_ptr *node_ptr) { - // first propagate statistics in the child node - auto left_stats = PropagateStatistics(cp.children[0]); - auto right_stats = PropagateStatistics(cp.children[1]); - if (!left_stats || !right_stats) { - return nullptr; - } - MultiplyCardinalities(left_stats, *right_stats); - return left_stats; -} -} // namespace duckdb +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 { -bool StatisticsPropagator::ExpressionIsConstant(Expression &expr, const Value &val) { - if (expr.GetExpressionClass() != ExpressionClass::BOUND_CONSTANT) { - return false; - } - auto &bound_constant = (BoundConstantExpression &)expr; - D_ASSERT(bound_constant.value.type() == val.type()); - return bound_constant.value == val; +unique_ptr ExpressionHeuristics::Rewrite(unique_ptr op) { + VisitOperator(*op); + return op; } -bool StatisticsPropagator::ExpressionIsConstantOrNull(Expression &expr, const Value &val) { - if (expr.GetExpressionClass() != ExpressionClass::BOUND_FUNCTION) { - return false; +void ExpressionHeuristics::VisitOperator(LogicalOperator &op) { + if (op.type == LogicalOperatorType::LOGICAL_FILTER) { + // reorder all filter expressions + if (op.expressions.size() > 1) { + ReorderExpressions(op.expressions); + } } - auto &bound_function = (BoundFunctionExpression &)expr; - return ConstantOrNull::IsConstantOrNull(bound_function, val); + + // traverse recursively through the operator tree + VisitOperatorChildren(op); + VisitOperatorExpressions(op); } -void StatisticsPropagator::SetStatisticsNotNull(ColumnBinding binding) { - auto entry = statistics_map.find(binding); - if (entry == statistics_map.end()) { - return; - } - entry->second->validity_stats = make_unique(false); +unique_ptr ExpressionHeuristics::VisitReplace(BoundConjunctionExpression &expr, + unique_ptr *expr_ptr) { + ReorderExpressions(expr.children); + return nullptr; } -void StatisticsPropagator::UpdateFilterStatistics(BaseStatistics &stats, ExpressionType comparison_type, - const Value &constant) { - // any comparison filter removes all null values - stats.validity_stats = make_unique(false); - if (!stats.type.IsNumeric()) { - // don't handle non-numeric columns here (yet) - return; - } - auto &numeric_stats = (NumericStatistics &)stats; - if (numeric_stats.min.is_null || numeric_stats.max.is_null) { - // no stats available: skip this - return; +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}); } - switch (comparison_type) { - case ExpressionType::COMPARE_LESSTHAN: - case ExpressionType::COMPARE_LESSTHANOREQUALTO: - // X < constant OR X <= constant - // max becomes the constant - numeric_stats.max = constant; - break; - case ExpressionType::COMPARE_GREATERTHAN: - case ExpressionType::COMPARE_GREATERTHANOREQUALTO: - // X > constant OR X >= constant - // min becomes the constant - numeric_stats.min = constant; - break; - case ExpressionType::COMPARE_EQUAL: - // X = constant - // both min and max become the constant - numeric_stats.min = constant; - numeric_stats.max = constant; - break; - default: - break; + + // 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); } } -void StatisticsPropagator::UpdateFilterStatistics(BaseStatistics &lstats, BaseStatistics &rstats, - ExpressionType comparison_type) { - // any comparison filter removes all null values - lstats.validity_stats = make_unique(false); - rstats.validity_stats = make_unique(false); - D_ASSERT(lstats.type == rstats.type); - if (!lstats.type.IsNumeric()) { - // don't handle non-numeric columns here (yet) - return; - } - auto &left_stats = (NumericStatistics &)lstats; - auto &right_stats = (NumericStatistics &)rstats; - if (left_stats.min.is_null || left_stats.max.is_null || right_stats.min.is_null || right_stats.max.is_null) { - // no stats available: skip this - return; - } - switch (comparison_type) { - case ExpressionType::COMPARE_LESSTHAN: - case ExpressionType::COMPARE_LESSTHANOREQUALTO: - // LEFT < RIGHT OR LEFT <= RIGHT - // we know that every value of left is smaller (or equal to) every value in right - // i.e. if we have left = [-50, 250] and right = [-100, 100] +idx_t ExpressionHeuristics::ExpressionCost(BoundBetweenExpression &expr) { + return Cost(*expr.input) + Cost(*expr.lower) + Cost(*expr.upper) + 10; +} - // we know that left.max is AT MOST equal to right.max - // because any value in left that is BIGGER than right.max will not pass the filter - if (left_stats.max > right_stats.max) { - left_stats.max = right_stats.max; - } +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; +} - // we also know that right.min is AT MOST equal to left.min - // because any value in right that is SMALLER than left.min will not pass the filter - if (right_stats.min < left_stats.min) { - right_stats.min = left_stats.min; - } - // so in our example, the bounds get updated as follows: - // left: [-50, 100], right: [-50, 100] - break; - case ExpressionType::COMPARE_GREATERTHAN: - case ExpressionType::COMPARE_GREATERTHANOREQUALTO: - // LEFT > RIGHT OR LEFT >= RIGHT - // we know that every value of left is bigger (or equal to) every value in right - // this is essentially the inverse of the less than (or equal to) scenario - if (right_stats.max > left_stats.max) { - right_stats.max = left_stats.max; - } - if (left_stats.min < right_stats.min) { - left_stats.min = right_stats.min; - } - break; - case ExpressionType::COMPARE_EQUAL: - // LEFT = RIGHT - // only the tightest bounds pass - // so if we have e.g. left = [-50, 250] and right = [-100, 100] - // the tighest bounds are [-50, 100] - // select the highest min - if (left_stats.min > right_stats.min) { - right_stats.min = left_stats.min; - } else { - left_stats.min = right_stats.min; - } - // select the lowest max - if (left_stats.max < right_stats.max) { - right_stats.max = left_stats.max; +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 { - left_stats.max = right_stats.max; + cast_cost = 5; } - break; - default: - break; } + return Cost(*expr.child) + cast_cost; } -void StatisticsPropagator::UpdateFilterStatistics(Expression &left, Expression &right, ExpressionType comparison_type) { - // first check if either side is a bound column ref - // any column ref involved in a comparison will not be null after the comparison - if (left.type == ExpressionType::BOUND_COLUMN_REF) { - SetStatisticsNotNull(((BoundColumnRefExpression &)left).binding); +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); } - if (right.type == ExpressionType::BOUND_COLUMN_REF) { - SetStatisticsNotNull(((BoundColumnRefExpression &)right).binding); + return cost; +} + +idx_t ExpressionHeuristics::ExpressionCost(BoundFunctionExpression &expr) { + idx_t cost_children = 0; + for (auto &child : expr.children) { + cost_children += Cost(*child); } - // check if this is a comparison between a constant and a column ref - BoundConstantExpression *constant = nullptr; - BoundColumnRefExpression *columnref = nullptr; - if (left.type == ExpressionType::VALUE_CONSTANT && right.type == ExpressionType::BOUND_COLUMN_REF) { - constant = (BoundConstantExpression *)&left; - columnref = (BoundColumnRefExpression *)&right; - comparison_type = FlipComparisionExpression(comparison_type); - } else if (left.type == ExpressionType::BOUND_COLUMN_REF && right.type == ExpressionType::VALUE_CONSTANT) { - columnref = (BoundColumnRefExpression *)&left; - constant = (BoundConstantExpression *)&right; - } else if (left.type == ExpressionType::BOUND_COLUMN_REF && right.type == ExpressionType::BOUND_COLUMN_REF) { - // comparison between two column refs - auto &left_column_ref = (BoundColumnRefExpression &)left; - auto &right_column_ref = (BoundColumnRefExpression &)right; - auto lentry = statistics_map.find(left_column_ref.binding); - auto rentry = statistics_map.find(right_column_ref.binding); - if (lentry == statistics_map.end() || rentry == statistics_map.end()) { - return; - } - UpdateFilterStatistics(*lentry->second, *rentry->second, comparison_type); + + auto cost_function = function_costs.find(expr.function.name); + if (cost_function != function_costs.end()) { + return cost_children + cost_function->second; } else { - // unsupported filter - return; + return cost_children + 1000; } - if (constant && columnref) { - // comparison between columnref - auto entry = statistics_map.find(columnref->binding); - if (entry == statistics_map.end()) { - return; - } - UpdateFilterStatistics(*entry->second, comparison_type, constant->value); +} + +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; } } -void StatisticsPropagator::UpdateFilterStatistics(Expression &condition) { - // in filters, we check for constant comparisons with bound columns - // if we find a comparison in the form of e.g. "i=3", we can update our statistics for that column - switch (condition.GetExpressionClass()) { +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 = (BoundBetweenExpression &)condition; - UpdateFilterStatistics(*between.input, *between.lower, between.LowerComparisonType()); - UpdateFilterStatistics(*between.input, *between.upper, between.UpperComparisonType()); - break; + 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 &comparison = (BoundComparisonExpression &)condition; - UpdateFilterStatistics(*comparison.left, *comparison.right, comparison.type); - break; + auto &comp_expr = (BoundComparisonExpression &)expr; + return ExpressionCost(comp_expr); } - default: + 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; } -unique_ptr StatisticsPropagator::PropagateStatistics(LogicalFilter &filter, - unique_ptr *node_ptr) { - // first propagate to the child - node_stats = PropagateStatistics(filter.children[0]); - if (filter.children[0]->type == LogicalOperatorType::LOGICAL_EMPTY_RESULT) { - ReplaceWithEmptyResult(*node_ptr); - return make_unique(0, 0); - } +} // namespace duckdb - // then propagate to each of the expressions - for (idx_t i = 0; i < filter.expressions.size(); i++) { - auto &condition = filter.expressions[i]; - PropagateExpression(condition); - if (ExpressionIsConstant(*condition, Value::BOOLEAN(true))) { - // filter is always true; it is useless to execute it - // erase this condition - filter.expressions.erase(filter.expressions.begin() + i); - i--; - if (filter.expressions.empty()) { - // all conditions have been erased: remove the entire filter - *node_ptr = move(filter.children[0]); - break; + + + + + + +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 if (ExpressionIsConstant(*condition, Value::BOOLEAN(false)) || - ExpressionIsConstantOrNull(*condition, Value::BOOLEAN(false))) { - // filter is always false or null; this entire filter should be replaced by an empty result block - ReplaceWithEmptyResult(*node_ptr); - return make_unique(0, 0); - } else { - // cannot prune this filter: propagate statistics from the filter - UpdateFilterStatistics(*condition); + // else nothing changed, continue to the next rule + continue; } } - // the max cardinality of a filter is the cardinality of the input (i.e. no tuples get filtered) - return move(node_stats); + // 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(move(child)); + return ConstantOrNull(move(children), move(value)); +} + +unique_ptr ExpressionRewriter::ConstantOrNull(vector> children, Value value) { + auto type = value.type(); + 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); } } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/filter_combiner.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + //===----------------------------------------------------------------------===// // DuckDB @@ -114693,27 +118514,40 @@ unique_ptr StatisticsPropagator::PropagateStatistics(LogicalFilt namespace duckdb { - -class ConjunctionOrFilter : public TableFilter { +class ConjunctionFilter : public TableFilter { public: - ConjunctionOrFilter(); + ConjunctionFilter(TableFilterType filter_type_p) : TableFilter(filter_type_p) { + } + + virtual ~ConjunctionFilter() { + } - //! The filters to OR together + //! The filters of this conjunction vector> child_filters; +public: + virtual FilterPropagateResult CheckStatistics(BaseStatistics &stats) = 0; + virtual string ToString(const string &column_name) = 0; + + virtual bool Equals(const TableFilter &other) const { + return TableFilter::Equals(other); + } +}; + +class ConjunctionOrFilter : public ConjunctionFilter { +public: + ConjunctionOrFilter(); + public: FilterPropagateResult CheckStatistics(BaseStatistics &stats) override; string ToString(const string &column_name) override; bool Equals(const TableFilter &other) const override; }; -class ConjunctionAndFilter : public TableFilter { +class ConjunctionAndFilter : public ConjunctionFilter { public: ConjunctionAndFilter(); - //! The filters to OR together - vector> child_filters; - public: FilterPropagateResult CheckStatistics(BaseStatistics &stats) override; string ToString(const string &column_name) override; @@ -114722,101 +118556,140 @@ class ConjunctionAndFilter : public TableFilter { } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/filter/constant_filter.hpp +// +// +//===----------------------------------------------------------------------===// + + + namespace duckdb { -FilterPropagateResult StatisticsPropagator::PropagateTableFilter(BaseStatistics &stats, TableFilter &filter) { - return filter.CheckStatistics(stats); -} +class ConstantFilter : public TableFilter { +public: + ConstantFilter(ExpressionType comparison_type, Value constant); -void StatisticsPropagator::UpdateFilterStatistics(BaseStatistics &input, TableFilter &filter) { - // FIXME: update stats... - switch (filter.filter_type) { - case TableFilterType::CONJUNCTION_AND: { - auto &conjunction_and = (ConjunctionAndFilter &)filter; - for (auto &child_filter : conjunction_and.child_filters) { - UpdateFilterStatistics(input, *child_filter); - } - break; - } - case TableFilterType::CONSTANT_COMPARISON: { - auto &constant_filter = (ConstantFilter &)filter; - UpdateFilterStatistics(input, constant_filter.comparison_type, constant_filter.constant); - break; - } - default: - break; - } -} + //! The comparison type (e.g. COMPARE_EQUAL, COMPARE_GREATERTHAN, COMPARE_LESSTHAN, ...) + ExpressionType comparison_type; + //! The constant value to filter on + Value constant; -unique_ptr StatisticsPropagator::PropagateStatistics(LogicalGet &get, - unique_ptr *node_ptr) { - if (get.function.cardinality) { - node_stats = get.function.cardinality(context, get.bind_data.get()); - } - if (!get.function.statistics) { - // no column statistics to get - return move(node_stats); +public: + FilterPropagateResult CheckStatistics(BaseStatistics &stats) override; + string ToString(const string &column_name) override; + bool Equals(const TableFilter &other) const override; +}; + +} // namespace duckdb + + + +#include +#include + +namespace duckdb { + +enum class ValueComparisonResult { PRUNE_LEFT, PRUNE_RIGHT, UNSATISFIABLE_CONDITION, PRUNE_NOTHING }; +enum class FilterResult { UNSATISFIABLE, SUCCESS, UNSUPPORTED }; + +//! The FilterCombiner combines several filters and generates a logically equivalent set that is more efficient +//! Amongst others: +//! (1) it prunes obsolete filter conditions: i.e. [X > 5 and X > 7] => [X > 7] +//! (2) it generates new filters for expressions in the same equivalence set: i.e. [X = Y and X = 500] => [Y = 500] +//! (3) it prunes branches that have unsatisfiable filters: i.e. [X = 5 AND X > 6] => FALSE, prune branch +class FilterCombiner { +public: + struct ExpressionValueInformation { + Value constant; + ExpressionType comparison_type; + }; + + FilterResult AddFilter(unique_ptr expr); + + void GenerateFilters(const std::function filter)> &callback); + bool HasFilters(); + TableFilterSet GenerateTableScanFilters(vector &column_ids); + // vector> GenerateZonemapChecks(vector &column_ids, vector> + // &pushed_filters); + +private: + FilterResult AddFilter(Expression *expr); + FilterResult AddBoundComparisonFilter(Expression *expr); + FilterResult AddTransitiveFilters(BoundComparisonExpression &comparison); + unique_ptr FindTransitiveFilter(Expression *expr); + // unordered_map> + // FindZonemapChecks(vector &column_ids, unordered_set ¬_constants, Expression *filter); + Expression *GetNode(Expression *expr); + idx_t GetEquivalenceSet(Expression *expr); + FilterResult AddConstantComparison(vector &info_list, ExpressionValueInformation info); + + //! Functions used to push and generate OR Filters + void LookUpConjunctions(Expression *expr); + bool BFSLookUpConjunctions(BoundConjunctionExpression *conjunction); + void VerifyOrsToPush(Expression &expr); + + bool UpdateConjunctionFilter(BoundComparisonExpression *comparison_expr); + bool UpdateFilterByColumn(BoundColumnRefExpression *column_ref, BoundComparisonExpression *comparison_expr); + void GenerateORFilters(TableFilterSet &table_filter, vector &column_ids); + + template + 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 = conj_filter_ptr; } - 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))); + + template + unique_ptr NextConjunctionFilter(BoundConjunctionExpression *conjunction) { + unique_ptr conj_filter = make_unique(); + for (auto &expr : conjunction->children) { + auto comp_expr = (BoundComparisonExpression *)expr.get(); + auto &const_expr = + (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)); } - } - // push table filters into the statistics - vector column_indexes; - column_indexes.reserve(get.table_filters.filters.size()); - for (auto &kv : get.table_filters.filters) { - column_indexes.push_back(kv.first); + return move(conj_filter); } - for (auto &table_filter_column : column_indexes) { - idx_t column_index; - for (column_index = 0; column_index < get.column_ids.size(); column_index++) { - if (get.column_ids[column_index] == table_filter_column) { - break; - } - } - D_ASSERT(column_index < get.column_ids.size()); - D_ASSERT(get.column_ids[column_index] == table_filter_column); +private: + vector> remaining_filters; - // find the stats - ColumnBinding stats_binding(get.table_index, column_index); - auto entry = statistics_map.find(stats_binding); - if (entry == statistics_map.end()) { - // no stats for this entry - continue; - } - auto &stats = *entry->second; + expression_map_t> stored_expressions; + unordered_map equivalence_set_map; + unordered_map> constant_values; + unordered_map> equivalence_map; + idx_t set_index = 0; - // fetch the table filter - D_ASSERT(get.table_filters.filters.count(table_filter_column) > 0); - auto &filter = get.table_filters.filters[table_filter_column]; - auto propagate_result = PropagateTableFilter(stats, *filter); - switch (propagate_result) { - case FilterPropagateResult::FILTER_ALWAYS_TRUE: - // filter is always true; it is useless to execute it - // erase this condition - get.table_filters.filters.erase(table_filter_column); - break; - case FilterPropagateResult::FILTER_FALSE_OR_NULL: - case FilterPropagateResult::FILTER_ALWAYS_FALSE: - // filter is always false; this entire filter should be replaced by an empty result block - ReplaceWithEmptyResult(*node_ptr); - return make_unique(0, 0); - default: - // general case: filter can be true or false, update this columns' statistics - UpdateFilterStatistics(stats, *filter); - break; - } - } - return move(node_stats); -} + //! Structures used for OR Filters + + struct ConjunctionsToPush { + BoundConjunctionExpression *root_or; + + // only preserve AND if there is a single column in the expression + bool preserve_and = true; + + // conjunction chain for this column + vector> conjunctions; + }; + + expression_map_t>> map_col_conjunctions; + vector vec_colref_insertion_order; + + BoundConjunctionExpression *cur_root_or; + BoundConjunctionExpression *cur_conjunction; + + BoundColumnRefExpression *cur_colref_to_push; +}; } // namespace duckdb @@ -114828,725 +118701,1355 @@ unique_ptr StatisticsPropagator::PropagateStatistics(LogicalGet + + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/filter/null_filter.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + namespace duckdb { -void StatisticsPropagator::PropagateStatistics(LogicalComparisonJoin &join, unique_ptr *node_ptr) { - for (idx_t i = 0; i < join.conditions.size(); i++) { - auto &condition = join.conditions[i]; - auto stats_left = PropagateExpression(condition.left); - auto stats_right = PropagateExpression(condition.right); - if (stats_left && stats_right) { - if (condition.null_values_are_equal && stats_left->CanHaveNull() && stats_right->CanHaveNull()) { - // null values are equal in this join, and both sides can have null values - // nothing to do here - continue; - } - 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)); - switch (prune_result) { - case FilterPropagateResult::FILTER_FALSE_OR_NULL: - case FilterPropagateResult::FILTER_ALWAYS_FALSE: - // filter is always false or null, none of the join conditions matter - switch (join.join_type) { - case JoinType::SEMI: - case JoinType::INNER: - // semi or inner join on false; entire node can be pruned - ReplaceWithEmptyResult(*node_ptr); - return; - case JoinType::ANTI: - // anti join: replace entire join with LHS - *node_ptr = move(join.children[0]); - return; - case JoinType::LEFT: - // anti/left outer join: replace right side with empty node - ReplaceWithEmptyResult(join.children[1]); - return; - case JoinType::RIGHT: - // right outer join: replace left side with empty node - ReplaceWithEmptyResult(join.children[0]); - return; - default: - // other join types: can't do much meaningful with this information - // full outer join requires both sides anyway; we can skip the execution of the actual join, but eh - // mark/single join requires knowing if the rhs has null values or not - break; - } - break; - case FilterPropagateResult::FILTER_ALWAYS_TRUE: - // filter is always true - if (join.conditions.size() > 1) { - // there are multiple conditions: erase this condition - join.conditions.erase(join.conditions.begin() + i); - i--; - continue; - } else { - // this is the only condition and it is always true: all conditions are true - switch (join.join_type) { - case JoinType::SEMI: - // semi join on true: replace entire join with LHS - *node_ptr = move(join.children[0]); - return; - case JoinType::INNER: - case JoinType::LEFT: - case JoinType::RIGHT: - case JoinType::OUTER: { - // 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 = make_unique(); - cross_product->children = move(join.children); - *node_ptr = move(cross_product); - return; - } - case JoinType::ANTI: - // anti join on true: empty result - ReplaceWithEmptyResult(*node_ptr); - return; - default: - // we don't handle mark/single join here yet - break; - } - } - break; - default: - break; - } - } - // after we have propagated, we can update the statistics on both sides - // note that it is fine to do this now, even if the same column is used again later - // e.g. if we have i=j AND i=k, and the stats for j and k are disjoint, we know there are no results - // so if we have e.g. i: [0, 100], j: [0, 25], k: [75, 100] - // we can set i: [0, 25] after the first comparison, and statically determine that the second comparison is fals - - // note that we can't update statistics the same for all join types - // mark and single joins don't filter any tuples -> so there is no propagation possible - // anti joins have inverse statistics propagation - // (i.e. if we have an anti join on i: [0, 100] and j: [0, 25], the resulting stats are i:[25,100]) - // for now we don't handle anti joins - if (condition.null_values_are_equal) { - // skip update when null values are equal (for now?) - continue; - } - switch (join.join_type) { - case JoinType::INNER: - case JoinType::SEMI: { - UpdateFilterStatistics(*condition.left, *condition.right, condition.comparison); - auto stats_left = PropagateExpression(condition.left); - 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); - } - break; - } - default: - break; - } - } -} - -void StatisticsPropagator::PropagateStatistics(LogicalAnyJoin &join, unique_ptr *node_ptr) { - // propagate the expression into the join condition - PropagateExpression(join.condition); -} - -void StatisticsPropagator::MultiplyCardinalities(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); - auto new_max = Hugeint::Multiply(stats->max_cardinality, new_stats.max_cardinality); - if (new_max < NumericLimits::Maximum()) { - int64_t result; - if (!Hugeint::TryCast(new_max, result)) { - throw InternalException("Overflow in cast in statistics propagation"); - } - D_ASSERT(result >= 0); - stats->max_cardinality = idx_t(result); - } else { - stats = nullptr; - } -} - -unique_ptr StatisticsPropagator::PropagateStatistics(LogicalJoin &join, - unique_ptr *node_ptr) { - // 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) { - MultiplyCardinalities(node_stats, *child_stats); - } - } +class IsNullFilter : public TableFilter { +public: + IsNullFilter(); - auto join_type = join.join_type; - vector left_bindings, right_bindings; - if (IsRightOuterJoin(join_type)) { - left_bindings = join.children[0]->GetColumnBindings(); - } - if (IsLeftOuterJoin(join_type)) { - right_bindings = join.children[1]->GetColumnBindings(); - } +public: + FilterPropagateResult CheckStatistics(BaseStatistics &stats) override; + string ToString(const string &column_name) override; +}; - // then propagate into the join conditions - switch (join.type) { - case LogicalOperatorType::LOGICAL_COMPARISON_JOIN: - PropagateStatistics((LogicalComparisonJoin &)join, node_ptr); - break; - case LogicalOperatorType::LOGICAL_ANY_JOIN: - PropagateStatistics((LogicalAnyJoin &)join, node_ptr); - break; - default: - break; - } +class IsNotNullFilter : public TableFilter { +public: + IsNotNullFilter(); - // now depending on the join type, we might need to alter the statistics - // LEFT, FULL and RIGHT OUTER joins can introduce null values - // this requires us to alter the statistics after this point in the query plan - if (IsLeftOuterJoin(join_type)) { - // left or full outer join: set is_null to true for all rhs statistics - for (auto &binding : right_bindings) { - auto stats = statistics_map.find(binding); - if (stats != statistics_map.end()) { - stats->second->validity_stats = make_unique(true); - } - } - } - if (IsRightOuterJoin(join_type)) { - // right or full outer join: set is_null to true for all lhs statistics - for (auto &binding : left_bindings) { - auto stats = statistics_map.find(binding); - if (stats != statistics_map.end()) { - stats->second->validity_stats = make_unique(true); - } - } - } - return move(node_stats); -} +public: + FilterPropagateResult CheckStatistics(BaseStatistics &stats) override; + string ToString(const string &column_name) override; +}; } // namespace duckdb -namespace duckdb { - -unique_ptr StatisticsPropagator::PropagateStatistics(LogicalLimit &limit, - unique_ptr *node_ptr) { - // propagate statistics in the child node - PropagateStatistics(limit.children[0]); - // return the node stats, with as expected cardinality the amount specified in the limit - return make_unique(limit.limit_val, limit.limit_val); -} - -} // namespace duckdb - - namespace duckdb { -unique_ptr StatisticsPropagator::PropagateStatistics(LogicalOrder &order, - unique_ptr *node_ptr) { - // first propagate to the child - node_stats = PropagateStatistics(order.children[0]); - - // then propagate to each of the order expressions - for (auto &bound_order : order.orders) { - PropagateAndCompress(bound_order.expression, bound_order.stats); - } - return move(node_stats); -} - -} // namespace duckdb - - - -namespace duckdb { +using ExpressionValueInformation = FilterCombiner::ExpressionValueInformation; -unique_ptr StatisticsPropagator::PropagateStatistics(LogicalProjection &proj, - unique_ptr *node_ptr) { - // first propagate to the child - node_stats = PropagateStatistics(proj.children[0]); +ValueComparisonResult CompareValueInformation(ExpressionValueInformation &left, ExpressionValueInformation &right); - // then propagate to each of the expressions - for (idx_t i = 0; i < proj.expressions.size(); i++) { - auto stats = PropagateExpression(proj.expressions[i]); - if (stats) { - ColumnBinding binding(proj.table_index, i); - statistics_map.insert(make_pair(binding, move(stats))); - } +Expression *FilterCombiner::GetNode(Expression *expr) { + auto entry = stored_expressions.find(expr); + if (entry != stored_expressions.end()) { + // expression already exists: return a reference to the stored expression + return entry->second.get(); } - return move(node_stats); + // expression does not exist yet: create a copy and store it + 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))); + return pointer_copy; } -} // namespace duckdb - - - -namespace duckdb { - -void StatisticsPropagator::AddCardinalities(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 += new_stats.estimated_cardinality; - auto new_max = Hugeint::Add(stats->max_cardinality, new_stats.max_cardinality); - if (new_max < NumericLimits::Maximum()) { - int64_t result; - if (!Hugeint::TryCast(new_max, result)) { - throw InternalException("Overflow in cast in statistics propagation"); - } - D_ASSERT(result >= 0); - stats->max_cardinality = idx_t(result); +idx_t FilterCombiner::GetEquivalenceSet(Expression *expr) { + D_ASSERT(stored_expressions.find(expr) != stored_expressions.end()); + D_ASSERT(stored_expressions.find(expr)->second.get() == expr); + auto entry = equivalence_set_map.find(expr); + if (entry == equivalence_set_map.end()) { + idx_t index = set_index++; + equivalence_set_map[expr] = index; + equivalence_map[index].push_back(expr); + constant_values.insert(make_pair(index, vector())); + return index; } else { - stats = nullptr; + return entry->second; } } -unique_ptr StatisticsPropagator::PropagateStatistics(LogicalSetOperation &setop, - unique_ptr *node_ptr) { - // first propagate statistics in the child nodes - auto left_stats = PropagateStatistics(setop.children[0]); - auto right_stats = PropagateStatistics(setop.children[1]); - - // now fetch the column bindings on both sides - auto left_bindings = setop.children[0]->GetColumnBindings(); - auto right_bindings = setop.children[1]->GetColumnBindings(); - - D_ASSERT(left_bindings.size() == right_bindings.size()); - D_ASSERT(left_bindings.size() == setop.column_count); - for (idx_t i = 0; i < setop.column_count; i++) { - // for each column binding, we fetch the statistics from both the lhs and the rhs - auto left_entry = statistics_map.find(left_bindings[i]); - auto right_entry = statistics_map.find(right_bindings[i]); - if (left_entry == statistics_map.end() || right_entry == statistics_map.end()) { - // no statistics on one of the sides: can't propagate stats - continue; - } - unique_ptr new_stats; - switch (setop.type) { - case LogicalOperatorType::LOGICAL_UNION: - // union: merge the stats of the LHS and RHS together - new_stats = left_entry->second->Copy(); - new_stats->Merge(*right_entry->second); - break; - case LogicalOperatorType::LOGICAL_EXCEPT: - // except: use the stats of the LHS - new_stats = left_entry->second->Copy(); - break; - case LogicalOperatorType::LOGICAL_INTERSECT: - // intersect: intersect the two stats - // FIXME: for now we just use the stats of the LHS, as this is correct - // however, the stats can be further refined to the minimal subset of the LHS and RHS - new_stats = left_entry->second->Copy(); +FilterResult FilterCombiner::AddConstantComparison(vector &info_list, + ExpressionValueInformation info) { + for (idx_t i = 0; i < info_list.size(); i++) { + auto comparison = CompareValueInformation(info_list[i], info); + switch (comparison) { + case ValueComparisonResult::PRUNE_LEFT: + // prune the entry from the info list + info_list.erase(info_list.begin() + i); + i--; break; + case ValueComparisonResult::PRUNE_RIGHT: + // prune the current info + return FilterResult::SUCCESS; + case ValueComparisonResult::UNSATISFIABLE_CONDITION: + // combination of filters is unsatisfiable: prune the entire branch + return FilterResult::UNSATISFIABLE; default: - throw InternalException("Unsupported setop type"); + // prune nothing, move to the next condition + break; } - ColumnBinding binding(setop.table_index, i); - statistics_map[binding] = move(new_stats); } - if (!left_stats || !right_stats) { - return nullptr; - } - if (setop.type == LogicalOperatorType::LOGICAL_UNION) { - AddCardinalities(left_stats, *right_stats); - } - return left_stats; + // finally add the entry to the list + info_list.push_back(info); + return FilterResult::SUCCESS; } -} // namespace duckdb - - - - -namespace duckdb { - -unique_ptr StatisticsPropagator::PropagateStatistics(LogicalWindow &window, - unique_ptr *node_ptr) { - // first propagate to the child - node_stats = PropagateStatistics(window.children[0]); +FilterResult FilterCombiner::AddFilter(unique_ptr expr) { + LookUpConjunctions(expr.get()); + // try to push the filter into the combiner + auto result = AddFilter(expr.get()); + if (result == FilterResult::UNSUPPORTED) { + // unsupported filter, push into remaining filters + remaining_filters.push_back(move(expr)); + return FilterResult::SUCCESS; + } + return result; +} - // then propagate to each of the order expressions - for (auto &window_expr : window.expressions) { - auto over_expr = reinterpret_cast(window_expr.get()); - for (auto &expr : over_expr->partitions) { - over_expr->partitions_stats.push_back(PropagateExpression(expr)); - } - for (auto &bound_order : over_expr->orders) { - bound_order.stats = PropagateExpression(bound_order.expression); +void FilterCombiner::GenerateFilters(const std::function filter)> &callback) { + // first loop over the remaining filters + for (auto &filter : remaining_filters) { + callback(move(filter)); + } + remaining_filters.clear(); + // now loop over the equivalence sets + for (auto &entry : equivalence_map) { + auto equivalence_set = entry.first; + auto &entries = entry.second; + auto &constant_list = constant_values.find(equivalence_set)->second; + // for each entry generate an equality expression comparing to each other + for (idx_t i = 0; i < entries.size(); i++) { + for (idx_t k = i + 1; k < entries.size(); k++) { + auto comparison = make_unique(ExpressionType::COMPARE_EQUAL, + entries[i]->Copy(), entries[k]->Copy()); + callback(move(comparison)); + } + // for each entry also create a comparison with each constant + int lower_index = -1, upper_index = -1; + bool lower_inclusive, upper_inclusive; + for (idx_t k = 0; k < constant_list.size(); k++) { + auto &info = constant_list[k]; + if (info.comparison_type == ExpressionType::COMPARE_GREATERTHAN || + info.comparison_type == ExpressionType::COMPARE_GREATERTHANOREQUALTO) { + lower_index = k; + lower_inclusive = info.comparison_type == ExpressionType::COMPARE_GREATERTHANOREQUALTO; + } else if (info.comparison_type == ExpressionType::COMPARE_LESSTHAN || + info.comparison_type == ExpressionType::COMPARE_LESSTHANOREQUALTO) { + upper_index = k; + upper_inclusive = info.comparison_type == ExpressionType::COMPARE_LESSTHANOREQUALTO; + } else { + auto constant = make_unique(info.constant); + auto comparison = make_unique(info.comparison_type, entries[i]->Copy(), + move(constant)); + callback(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)); + } 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)); + } 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)); + } } } - return move(node_stats); + stored_expressions.clear(); + equivalence_set_map.clear(); + constant_values.clear(); + equivalence_map.clear(); } -} // namespace duckdb +bool FilterCombiner::HasFilters() { + bool has_filters = false; + GenerateFilters([&](unique_ptr child) { has_filters = true; }); + return has_filters; +} + +// unordered_map> MergeAnd(unordered_map> &f_1, +// unordered_map> &f_2) { +// unordered_map> result; +// for (auto &f : f_1) { +// auto it = f_2.find(f.first); +// if (it == f_2.end()) { +// result[f.first] = f.second; +// } else { +// Value *min = nullptr, *max = nullptr; +// if (it->second.first && f.second.first) { +// if (*f.second.first > *it->second.first) { +// min = f.second.first; +// } else { +// min = it->second.first; +// } + +// } else if (it->second.first) { +// min = it->second.first; +// } else if (f.second.first) { +// min = f.second.first; +// } else { +// min = nullptr; +// } +// if (it->second.second && f.second.second) { +// if (*f.second.second < *it->second.second) { +// max = f.second.second; +// } else { +// max = it->second.second; +// } +// } else if (it->second.second) { +// max = it->second.second; +// } else if (f.second.second) { +// max = f.second.second; +// } else { +// max = nullptr; +// } +// result[f.first] = {min, max}; +// f_2.erase(f.first); +// } +// } +// for (auto &f : f_2) { +// result[f.first] = f.second; +// } +// return result; +// } +// unordered_map> MergeOr(unordered_map> &f_1, +// unordered_map> &f_2) { +// unordered_map> result; +// for (auto &f : f_1) { +// auto it = f_2.find(f.first); +// if (it != f_2.end()) { +// Value *min = nullptr, *max = nullptr; +// if (it->second.first && f.second.first) { +// if (*f.second.first < *it->second.first) { +// min = f.second.first; +// } else { +// min = it->second.first; +// } +// } +// if (it->second.second && f.second.second) { +// if (*f.second.second > *it->second.second) { +// max = f.second.second; +// } else { +// max = it->second.second; +// } +// } +// result[f.first] = {min, max}; +// f_2.erase(f.first); +// } +// } +// return result; +// } +// unordered_map> +// FilterCombiner::FindZonemapChecks(vector &column_ids, unordered_set ¬_constants, Expression *filter) +// { unordered_map> checks; switch (filter->type) { case +// ExpressionType::CONJUNCTION_OR: { +// //! For a filter to +// auto &or_exp = (BoundConjunctionExpression &)*filter; +// checks = FindZonemapChecks(column_ids, not_constants, or_exp.children[0].get()); +// for (size_t i = 1; i < or_exp.children.size(); ++i) { +// auto child_check = FindZonemapChecks(column_ids, not_constants, or_exp.children[i].get()); +// checks = MergeOr(checks, child_check); +// } +// return checks; +// } +// case ExpressionType::CONJUNCTION_AND: { +// auto &and_exp = (BoundConjunctionExpression &)*filter; +// checks = FindZonemapChecks(column_ids, not_constants, and_exp.children[0].get()); +// for (size_t i = 1; i < and_exp.children.size(); ++i) { +// auto child_check = FindZonemapChecks(column_ids, not_constants, and_exp.children[i].get()); +// checks = MergeAnd(checks, child_check); +// } +// return checks; +// } +// case ExpressionType::COMPARE_IN: { +// auto &comp_in_exp = (BoundOperatorExpression &)*filter; +// if (comp_in_exp.children[0]->type == ExpressionType::BOUND_COLUMN_REF) { +// Value *min = nullptr, *max = nullptr; +// auto &column_ref = (BoundColumnRefExpression &)*comp_in_exp.children[0].get(); +// for (size_t i {1}; i < comp_in_exp.children.size(); i++) { +// if (comp_in_exp.children[i]->type != ExpressionType::VALUE_CONSTANT) { +// //! This indicates the column has a comparison that is not with a constant +// not_constants.insert(column_ids[column_ref.binding.column_index]); +// break; +// } else { +// auto &const_value_expr = (BoundConstantExpression &)*comp_in_exp.children[i].get(); +// if (const_value_expr.value.IsNull()) { +// return checks; +// } +// if (!min && !max) { +// min = &const_value_expr.value; +// max = min; +// } else { +// if (*min > const_value_expr.value) { +// min = &const_value_expr.value; +// } +// if (*max < const_value_expr.value) { +// max = &const_value_expr.value; +// } +// } +// } +// } +// checks[column_ids[column_ref.binding.column_index]] = {min, max}; +// } +// return checks; +// } +// case ExpressionType::COMPARE_EQUAL: { +// auto &comp_exp = (BoundComparisonExpression &)*filter; +// if ((comp_exp.left->expression_class == ExpressionClass::BOUND_COLUMN_REF && +// comp_exp.right->expression_class == ExpressionClass::BOUND_CONSTANT)) { +// auto &column_ref = (BoundColumnRefExpression &)*comp_exp.left; +// auto &constant_value_expr = (BoundConstantExpression &)*comp_exp.right; +// checks[column_ids[column_ref.binding.column_index]] = {&constant_value_expr.value, +// &constant_value_expr.value}; +// } +// if ((comp_exp.left->expression_class == ExpressionClass::BOUND_CONSTANT && +// comp_exp.right->expression_class == ExpressionClass::BOUND_COLUMN_REF)) { +// auto &column_ref = (BoundColumnRefExpression &)*comp_exp.right; +// auto &constant_value_expr = (BoundConstantExpression &)*comp_exp.left; +// checks[column_ids[column_ref.binding.column_index]] = {&constant_value_expr.value, +// &constant_value_expr.value}; +// } +// return checks; +// } +// case ExpressionType::COMPARE_LESSTHAN: +// case ExpressionType::COMPARE_LESSTHANOREQUALTO: { +// auto &comp_exp = (BoundComparisonExpression &)*filter; +// if ((comp_exp.left->expression_class == ExpressionClass::BOUND_COLUMN_REF && +// comp_exp.right->expression_class == ExpressionClass::BOUND_CONSTANT)) { +// auto &column_ref = (BoundColumnRefExpression &)*comp_exp.left; +// auto &constant_value_expr = (BoundConstantExpression &)*comp_exp.right; +// checks[column_ids[column_ref.binding.column_index]] = {nullptr, &constant_value_expr.value}; +// } +// if ((comp_exp.left->expression_class == ExpressionClass::BOUND_CONSTANT && +// comp_exp.right->expression_class == ExpressionClass::BOUND_COLUMN_REF)) { +// auto &column_ref = (BoundColumnRefExpression &)*comp_exp.right; +// auto &constant_value_expr = (BoundConstantExpression &)*comp_exp.left; +// checks[column_ids[column_ref.binding.column_index]] = {&constant_value_expr.value, nullptr}; +// } +// return checks; +// } +// case ExpressionType::COMPARE_GREATERTHANOREQUALTO: +// case ExpressionType::COMPARE_GREATERTHAN: { +// auto &comp_exp = (BoundComparisonExpression &)*filter; +// if ((comp_exp.left->expression_class == ExpressionClass::BOUND_COLUMN_REF && +// comp_exp.right->expression_class == ExpressionClass::BOUND_CONSTANT)) { +// auto &column_ref = (BoundColumnRefExpression &)*comp_exp.left; +// auto &constant_value_expr = (BoundConstantExpression &)*comp_exp.right; +// checks[column_ids[column_ref.binding.column_index]] = {&constant_value_expr.value, nullptr}; +// } +// if ((comp_exp.left->expression_class == ExpressionClass::BOUND_CONSTANT && +// comp_exp.right->expression_class == ExpressionClass::BOUND_COLUMN_REF)) { +// auto &column_ref = (BoundColumnRefExpression &)*comp_exp.right; +// auto &constant_value_expr = (BoundConstantExpression &)*comp_exp.left; +// checks[column_ids[column_ref.binding.column_index]] = {nullptr, &constant_value_expr.value}; +// } +// return checks; +// } +// default: +// return checks; +// } +// } +// vector FilterCombiner::GenerateZonemapChecks(vector &column_ids, +// vector &pushed_filters) { +// vector zonemap_checks; +// unordered_set not_constants; +// //! We go through the remaining filters and capture their min max +// if (remaining_filters.empty()) { +// return zonemap_checks; +// } +// auto checks = FindZonemapChecks(column_ids, not_constants, remaining_filters[0].get()); +// for (size_t i = 1; i < remaining_filters.size(); ++i) { +// auto child_check = FindZonemapChecks(column_ids, not_constants, remaining_filters[i].get()); +// checks = MergeAnd(checks, child_check); +// } +// //! We construct the equivalent filters +// for (auto not_constant : not_constants) { +// checks.erase(not_constant); +// } +// for (const auto &pushed_filter : pushed_filters) { +// checks.erase(column_ids[pushed_filter.column_index]); +// } +// for (const auto &check : checks) { +// if (check.second.first) { +// zonemap_checks.emplace_back(check.second.first->Copy(), ExpressionType::COMPARE_GREATERTHANOREQUALTO, +// check.first); +// } +// if (check.second.second) { +// zonemap_checks.emplace_back(check.second.second->Copy(), ExpressionType::COMPARE_LESSTHANOREQUALTO, +// check.first); +// } +// } +// return zonemap_checks; +// } +TableFilterSet FilterCombiner::GenerateTableScanFilters(vector &column_ids) { + TableFilterSet table_filters; + //! First, we figure the filters that have constant expressions that we can push down to the table scan + for (auto &constant_value : constant_values) { + if (!constant_value.second.empty()) { + auto filter_exp = equivalence_map.end(); + if ((constant_value.second[0].comparison_type == ExpressionType::COMPARE_EQUAL || + constant_value.second[0].comparison_type == ExpressionType::COMPARE_GREATERTHAN || + constant_value.second[0].comparison_type == ExpressionType::COMPARE_GREATERTHANOREQUALTO || + constant_value.second[0].comparison_type == ExpressionType::COMPARE_LESSTHAN || + constant_value.second[0].comparison_type == ExpressionType::COMPARE_LESSTHANOREQUALTO) && + (TypeIsNumeric(constant_value.second[0].constant.type().InternalType()) || + constant_value.second[0].constant.type().InternalType() == PhysicalType::VARCHAR || + constant_value.second[0].constant.type().InternalType() == PhysicalType::BOOL)) { + //! Here we check if these filters are column references + filter_exp = equivalence_map.find(constant_value.first); + if (filter_exp->second.size() == 1 && filter_exp->second[0]->type == ExpressionType::BOUND_COLUMN_REF) { + auto filter_col_exp = static_cast(filter_exp->second[0]); + auto column_index = column_ids[filter_col_exp->binding.column_index]; + if (column_index == COLUMN_IDENTIFIER_ROW_ID) { + break; + } + auto equivalence_set = filter_exp->first; + auto &entries = filter_exp->second; + auto &constant_list = constant_values.find(equivalence_set)->second; + // for each entry generate an equality expression comparing to each other + for (idx_t i = 0; i < entries.size(); i++) { + // for each entry also create a comparison with each constant + 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, make_unique()); + } + equivalence_map.erase(filter_exp); + } + } + } + } + //! Here we look for LIKE or IN filters + for (idx_t rem_fil_idx = 0; rem_fil_idx < remaining_filters.size(); rem_fil_idx++) { + auto &remaining_filter = remaining_filters[rem_fil_idx]; + if (remaining_filter->expression_class == ExpressionClass::BOUND_FUNCTION) { + auto &func = (BoundFunctionExpression &)*remaining_filter; + if (func.function.name == "prefix" && + func.children[0]->expression_class == ExpressionClass::BOUND_COLUMN_REF && + func.children[1]->type == ExpressionType::VALUE_CONSTANT) { + //! This is a like function. + auto &column_ref = (BoundColumnRefExpression &)*func.children[0].get(); + auto &constant_value_expr = (BoundConstantExpression &)*func.children[1].get(); + auto like_string = StringValue::Get(constant_value_expr.value); + if (like_string.empty()) { + continue; + } + auto column_index = column_ids[column_ref.binding.column_index]; + //! Here the like must be transformed to a BOUND COMPARISON geq le + auto lower_bound = + 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, make_unique()); + } + if (func.function.name == "~~" && func.children[0]->expression_class == ExpressionClass::BOUND_COLUMN_REF && + func.children[1]->type == ExpressionType::VALUE_CONSTANT) { + //! This is a like function. + auto &column_ref = (BoundColumnRefExpression &)*func.children[0].get(); + auto &constant_value_expr = (BoundConstantExpression &)*func.children[1].get(); + auto &like_string = StringValue::Get(constant_value_expr.value); + if (like_string[0] == '%' || like_string[0] == '_') { + //! We have no prefix so nothing to pushdown + break; + } + string prefix; + bool equality = true; + for (char const &c : like_string) { + if (c == '%' || c == '_') { + equality = false; + break; + } + prefix += c; + } + auto column_index = column_ids[column_ref.binding.column_index]; + 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, make_unique()); + } else { + //! Here the like must be transformed to a BOUND COMPARISON geq le + auto lower_bound = + 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, make_unique()); + } + } + } else if (remaining_filter->type == ExpressionType::COMPARE_IN) { + auto &func = (BoundOperatorExpression &)*remaining_filter; + vector in_values; + D_ASSERT(func.children.size() > 1); + if (func.children[0]->expression_class != ExpressionClass::BOUND_COLUMN_REF) { + continue; + } + auto &column_ref = (BoundColumnRefExpression &)*func.children[0].get(); + auto column_index = column_ids[column_ref.binding.column_index]; + if (column_index == COLUMN_IDENTIFIER_ROW_ID) { + break; + } + //! check if all children are const expr + bool children_constant = true; + for (size_t i {1}; i < func.children.size(); i++) { + if (func.children[i]->type != ExpressionType::VALUE_CONSTANT) { + children_constant = false; + } + } + if (!children_constant) { + continue; + } + auto &fst_const_value_expr = (BoundConstantExpression &)*func.children[1].get(); + auto &type = fst_const_value_expr.value.type(); + //! Check if values are consecutive, if yes transform them to >= <= (only for integers) + // e.g. if we have x IN (1, 2, 3, 4, 5) we transform this into x >= 1 AND x <= 5 + if (!type.IsIntegral()) { + continue; + } -namespace duckdb { + bool can_simplify_in_clause = true; + for (idx_t i = 1; i < func.children.size(); i++) { + auto &const_value_expr = (BoundConstantExpression &)*func.children[i].get(); + if (const_value_expr.value.IsNull()) { + can_simplify_in_clause = false; + break; + } + in_values.push_back(const_value_expr.value.GetValue()); + } + if (!can_simplify_in_clause || in_values.empty()) { + continue; + } -StatisticsPropagator::StatisticsPropagator(ClientContext &context) : context(context) { -} + sort(in_values.begin(), in_values.end()); -void StatisticsPropagator::ReplaceWithEmptyResult(unique_ptr &node) { - node = make_unique(move(node)); -} + for (idx_t in_val_idx = 1; in_val_idx < in_values.size(); in_val_idx++) { + if (in_values[in_val_idx] - in_values[in_val_idx - 1] > 1) { + can_simplify_in_clause = false; + break; + } + } + if (!can_simplify_in_clause) { + continue; + } + auto lower_bound = make_unique(ExpressionType::COMPARE_GREATERTHANOREQUALTO, + 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, make_unique()); -unique_ptr StatisticsPropagator::PropagateChildren(LogicalOperator &node, - unique_ptr *node_ptr) { - for (idx_t child_idx = 0; child_idx < node.children.size(); child_idx++) { - PropagateStatistics(node.children[child_idx]); + remaining_filters.erase(remaining_filters.begin() + rem_fil_idx); + } } - return nullptr; -} -unique_ptr StatisticsPropagator::PropagateStatistics(LogicalOperator &node, - unique_ptr *node_ptr) { - switch (node.type) { - case LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY: - return PropagateStatistics((LogicalAggregate &)node, node_ptr); - case LogicalOperatorType::LOGICAL_CROSS_PRODUCT: - return PropagateStatistics((LogicalCrossProduct &)node, node_ptr); - case LogicalOperatorType::LOGICAL_FILTER: - return PropagateStatistics((LogicalFilter &)node, node_ptr); - case LogicalOperatorType::LOGICAL_GET: - return PropagateStatistics((LogicalGet &)node, node_ptr); - case LogicalOperatorType::LOGICAL_PROJECTION: - return PropagateStatistics((LogicalProjection &)node, node_ptr); - case LogicalOperatorType::LOGICAL_ANY_JOIN: - case LogicalOperatorType::LOGICAL_COMPARISON_JOIN: - case LogicalOperatorType::LOGICAL_JOIN: - return PropagateStatistics((LogicalJoin &)node, node_ptr); - case LogicalOperatorType::LOGICAL_UNION: - case LogicalOperatorType::LOGICAL_EXCEPT: - case LogicalOperatorType::LOGICAL_INTERSECT: - return PropagateStatistics((LogicalSetOperation &)node, node_ptr); - case LogicalOperatorType::LOGICAL_ORDER_BY: - return PropagateStatistics((LogicalOrder &)node, node_ptr); - case LogicalOperatorType::LOGICAL_WINDOW: - return PropagateStatistics((LogicalWindow &)node, node_ptr); - default: - return PropagateChildren(node, node_ptr); - } -} + GenerateORFilters(table_filters, column_ids); -unique_ptr StatisticsPropagator::PropagateStatistics(unique_ptr &node_ptr) { - return PropagateStatistics(*node_ptr, &node_ptr); + return table_filters; } -unique_ptr StatisticsPropagator::PropagateExpression(Expression &expr, - unique_ptr *expr_ptr) { - switch (expr.GetExpressionClass()) { - case ExpressionClass::BOUND_AGGREGATE: - return PropagateExpression((BoundAggregateExpression &)expr, expr_ptr); - case ExpressionClass::BOUND_BETWEEN: - return PropagateExpression((BoundBetweenExpression &)expr, expr_ptr); - case ExpressionClass::BOUND_CASE: - return PropagateExpression((BoundCaseExpression &)expr, expr_ptr); - case ExpressionClass::BOUND_FUNCTION: - return PropagateExpression((BoundFunctionExpression &)expr, expr_ptr); - case ExpressionClass::BOUND_CAST: - return PropagateExpression((BoundCastExpression &)expr, expr_ptr); - case ExpressionClass::BOUND_COMPARISON: - return PropagateExpression((BoundComparisonExpression &)expr, expr_ptr); - case ExpressionClass::BOUND_CONSTANT: - return PropagateExpression((BoundConstantExpression &)expr, expr_ptr); - case ExpressionClass::BOUND_COLUMN_REF: - return PropagateExpression((BoundColumnRefExpression &)expr, expr_ptr); - case ExpressionClass::BOUND_OPERATOR: - return PropagateExpression((BoundOperatorExpression &)expr, expr_ptr); - default: - break; - } - ExpressionIterator::EnumerateChildren(expr, [&](unique_ptr &child) { PropagateExpression(child); }); - return nullptr; +static bool IsGreaterThan(ExpressionType type) { + return type == ExpressionType::COMPARE_GREATERTHAN || type == ExpressionType::COMPARE_GREATERTHANOREQUALTO; } -unique_ptr StatisticsPropagator::PropagateExpression(unique_ptr &expr) { - auto stats = PropagateExpression(*expr, &expr); - if (context.query_verification_enabled && stats) { - expr->verification_stats = stats->Copy(); - } - return stats; +static bool IsLessThan(ExpressionType type) { + return type == ExpressionType::COMPARE_LESSTHAN || type == ExpressionType::COMPARE_LESSTHANOREQUALTO; } -} // namespace duckdb - - - - - +FilterResult FilterCombiner::AddBoundComparisonFilter(Expression *expr) { + auto &comparison = (BoundComparisonExpression &)*expr; + if (comparison.type != ExpressionType::COMPARE_LESSTHAN && + comparison.type != ExpressionType::COMPARE_LESSTHANOREQUALTO && + comparison.type != ExpressionType::COMPARE_GREATERTHAN && + comparison.type != ExpressionType::COMPARE_GREATERTHANOREQUALTO && + comparison.type != ExpressionType::COMPARE_EQUAL && comparison.type != ExpressionType::COMPARE_NOTEQUAL) { + // only support [>, >=, <, <=, ==] expressions + return FilterResult::UNSUPPORTED; + } + // check if one of the sides is a scalar value + bool left_is_scalar = comparison.left->IsFoldable(); + bool right_is_scalar = comparison.right->IsFoldable(); + if (left_is_scalar || right_is_scalar) { + // comparison with scalar + auto node = GetNode(left_is_scalar ? comparison.right.get() : comparison.left.get()); + idx_t equivalence_set = GetEquivalenceSet(node); + auto scalar = left_is_scalar ? comparison.left.get() : comparison.right.get(); + auto constant_value = ExpressionExecutor::EvaluateScalar(*scalar); + if (constant_value.IsNull()) { + // comparisons with null are always null (i.e. will never result in rows) + return FilterResult::UNSATISFIABLE; + } -namespace duckdb { + // create the ExpressionValueInformation + ExpressionValueInformation info; + info.comparison_type = left_is_scalar ? FlipComparisionExpression(comparison.type) : comparison.type; + info.constant = constant_value; -unique_ptr TopN::Optimize(unique_ptr op) { - if (op->type == LogicalOperatorType::LOGICAL_LIMIT && - op->children[0]->type == LogicalOperatorType::LOGICAL_ORDER_BY) { - auto &limit = (LogicalLimit &)*op; - auto &order_by = (LogicalOrder &)*(op->children[0]); + // 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; + // check the existing constant comparisons to see if we can do any pruning + auto ret = AddConstantComparison(info_list, info); - // 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 non_scalar = left_is_scalar ? comparison.right.get() : comparison.left.get(); + auto transitive_filter = FindTransitiveFilter(non_scalar); + if (transitive_filter != nullptr) { + // 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)); + } } + return ret; } else { - for (auto &child : op->children) { - child = Optimize(move(child)); + // comparison between two non-scalars + // only handle comparisons for now + if (expr->type != ExpressionType::COMPARE_EQUAL) { + if (IsGreaterThan(expr->type) || IsLessThan(expr->type)) { + return AddTransitiveFilters(comparison); + } + return FilterResult::UNSUPPORTED; + } + // get the LHS and RHS nodes + auto left_node = GetNode(comparison.left.get()); + auto right_node = GetNode(comparison.right.get()); + if (BaseExpression::Equals(left_node, right_node)) { + return FilterResult::UNSUPPORTED; + } + // get the equivalence sets of the LHS and RHS + auto left_equivalence_set = GetEquivalenceSet(left_node); + auto right_equivalence_set = GetEquivalenceSet(right_node); + if (left_equivalence_set == right_equivalence_set) { + // this equality filter already exists, prune it + return FilterResult::SUCCESS; + } + // add the right bucket into the left bucket + D_ASSERT(equivalence_map.find(left_equivalence_set) != equivalence_map.end()); + D_ASSERT(equivalence_map.find(right_equivalence_set) != equivalence_map.end()); + + auto &left_bucket = equivalence_map.find(left_equivalence_set)->second; + auto &right_bucket = equivalence_map.find(right_equivalence_set)->second; + for (auto &i : right_bucket) { + // rewrite the equivalence set mapping for this node + equivalence_set_map[i] = left_equivalence_set; + // add the node to the left bucket + left_bucket.push_back(i); + } + // now add all constant values from the right bucket to the left bucket + D_ASSERT(constant_values.find(left_equivalence_set) != constant_values.end()); + D_ASSERT(constant_values.find(right_equivalence_set) != constant_values.end()); + auto &left_constant_bucket = constant_values.find(left_equivalence_set)->second; + auto &right_constant_bucket = constant_values.find(right_equivalence_set)->second; + for (auto &i : right_constant_bucket) { + if (AddConstantComparison(left_constant_bucket, i) == FilterResult::UNSATISFIABLE) { + return FilterResult::UNSATISFIABLE; + } } } - return op; + return FilterResult::SUCCESS; } -} // namespace duckdb - - - +FilterResult FilterCombiner::AddFilter(Expression *expr) { + if (expr->HasParameter()) { + return FilterResult::UNSUPPORTED; + } + if (expr->IsFoldable()) { + // scalar condition, evaluate it + auto result = ExpressionExecutor::EvaluateScalar(*expr).CastAs(LogicalType::BOOLEAN); + // check if the filter passes + if (result.IsNull() || !BooleanValue::Get(result)) { + // the filter does not pass the scalar test, create an empty result + return FilterResult::UNSATISFIABLE; + } else { + // the filter passes the scalar test, just remove the condition + return FilterResult::SUCCESS; + } + } + D_ASSERT(!expr->IsFoldable()); + if (expr->GetExpressionClass() == ExpressionClass::BOUND_BETWEEN) { + auto &comparison = (BoundBetweenExpression &)*expr; + //! check if one of the sides is a scalar value + bool left_is_scalar = comparison.lower->IsFoldable(); + bool right_is_scalar = comparison.upper->IsFoldable(); + if (left_is_scalar || right_is_scalar) { + //! comparison with scalar + auto node = GetNode(comparison.input.get()); + idx_t equivalence_set = GetEquivalenceSet(node); + auto scalar = comparison.lower.get(); + auto constant_value = ExpressionExecutor::EvaluateScalar(*scalar); + // create the ExpressionValueInformation + ExpressionValueInformation info; + if (comparison.lower_inclusive) { + info.comparison_type = ExpressionType::COMPARE_GREATERTHANOREQUALTO; + } else { + info.comparison_type = ExpressionType::COMPARE_GREATERTHAN; + } + info.constant = constant_value; + // 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; + // check the existing constant comparisons to see if we can do any pruning + AddConstantComparison(info_list, info); + scalar = comparison.upper.get(); + constant_value = ExpressionExecutor::EvaluateScalar(*scalar); -namespace duckdb { + // create the ExpressionValueInformation + if (comparison.upper_inclusive) { + info.comparison_type = ExpressionType::COMPARE_LESSTHANOREQUALTO; + } else { + info.comparison_type = ExpressionType::COMPARE_LESSTHAN; + } + info.constant = constant_value; -Event::Event(Executor &executor_p) - : executor(executor_p), finished_tasks(0), total_tasks(0), finished_dependencies(0), total_dependencies(0), - finished(false) { + // get the current bucket of constant values + D_ASSERT(constant_values.find(equivalence_set) != constant_values.end()); + // check the existing constant comparisons to see if we can do any pruning + return AddConstantComparison(constant_values.find(equivalence_set)->second, info); + } + } else if (expr->GetExpressionClass() == ExpressionClass::BOUND_COMPARISON) { + return AddBoundComparisonFilter(expr); + } + // only comparisons supported for now + return FilterResult::UNSUPPORTED; } -void Event::CompleteDependency() { - idx_t current_finished = ++finished_dependencies; - D_ASSERT(current_finished <= total_dependencies); - if (current_finished == total_dependencies) { - // all dependencies have been completed: schedule the event - D_ASSERT(total_tasks == 0); - Schedule(); - if (total_tasks == 0) { - Finish(); +/* + * Create and add new transitive filters from a two non-scalar filter such as j > i, j >= i, j < i, and j <= i + * It's missing to create another method to add transitive filters from scalar filters, e.g, i > 10 + */ +FilterResult FilterCombiner::AddTransitiveFilters(BoundComparisonExpression &comparison) { + D_ASSERT(IsGreaterThan(comparison.type) || IsLessThan(comparison.type)); + // get the LHS and RHS nodes + Expression *left_node = GetNode(comparison.left.get()); + Expression *right_node = GetNode(comparison.right.get()); + // In case with filters like CAST(i) = j and i = 5 we replace the COLUMN_REF i with the constant 5 + if (right_node->type == ExpressionType::OPERATOR_CAST) { + auto &bound_cast_expr = (BoundCastExpression &)*right_node; + if (bound_cast_expr.child->type == ExpressionType::BOUND_COLUMN_REF) { + auto &col_ref = (BoundColumnRefExpression &)*bound_cast_expr.child; + 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) { + bound_cast_expr.child = stored_exp.second->Copy(); + right_node = GetNode(bound_cast_expr.child.get()); + break; + } + } + } } } -} -void Event::Finish() { - D_ASSERT(!finished); - FinishEvent(); - finished = true; - // finished processing the pipeline, now we can schedule pipelines that depend on this pipeline - for (auto &parent_entry : parents) { - auto parent = parent_entry.lock(); - if (!parent) { // LCOV_EXCL_START + if (BaseExpression::Equals(left_node, right_node)) { + return FilterResult::UNSUPPORTED; + } + // get the equivalence sets of the LHS and RHS + idx_t left_equivalence_set = GetEquivalenceSet(left_node); + idx_t right_equivalence_set = GetEquivalenceSet(right_node); + if (left_equivalence_set == right_equivalence_set) { + // this equality filter already exists, prune it + return FilterResult::SUCCESS; + } + + vector &left_constants = constant_values.find(left_equivalence_set)->second; + vector &right_constants = constant_values.find(right_equivalence_set)->second; + bool is_successful = false; + bool is_inserted = false; + // read every constant filters already inserted for the right scalar variable + // and see if we can create new transitive filters, e.g., there is already a filter i > 10, + // suppose that we have now the j >= i, then we can infer a new filter j > 10 + for (const auto &right_constant : right_constants) { + ExpressionValueInformation info; + info.constant = right_constant.constant; + // there is already an equality filter, e.g., i = 10 + if (right_constant.comparison_type == ExpressionType::COMPARE_EQUAL) { + // create filter j [>, >=, <, <=] 10 + // suppose the new comparison is j >= i and we have already a filter i = 10, + // then we create a new filter j >= 10 + // and the filter j >= i can be pruned by not adding it into the remaining filters + info.comparison_type = comparison.type; + } else if ((comparison.type == ExpressionType::COMPARE_GREATERTHANOREQUALTO && + IsGreaterThan(right_constant.comparison_type)) || + (comparison.type == ExpressionType::COMPARE_LESSTHANOREQUALTO && + IsLessThan(right_constant.comparison_type))) { + // filters (j >= i AND i [>, >=] 10) OR (j <= i AND i [<, <=] 10) + // create filter j [>, >=] 10 and add the filter j [>=, <=] i into the remaining filters + info.comparison_type = right_constant.comparison_type; // create filter j [>, >=, <, <=] 10 + if (!is_inserted) { + // 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)); + is_inserted = true; + } + } else if ((comparison.type == ExpressionType::COMPARE_GREATERTHAN && + IsGreaterThan(right_constant.comparison_type)) || + (comparison.type == ExpressionType::COMPARE_LESSTHAN && + IsLessThan(right_constant.comparison_type))) { + // filters (j > i AND i [>, >=] 10) OR j < i AND i [<, <=] 10 + // create filter j [>, <] 10 and add the filter j [>, <] i into the remaining filters + // the comparisons j > i and j < i are more restrictive + info.comparison_type = comparison.type; + if (!is_inserted) { + // Add the filter j [>, <] i + auto filter = make_unique(comparison.type, comparison.left->Copy(), + comparison.right->Copy()); + remaining_filters.push_back(move(filter)); + is_inserted = true; + } + } else { + // we cannot add a new filter continue; - } // LCOV_EXCL_STOP - // mark a dependency as completed for each of the parents - parent->CompleteDependency(); + } + // Add the new filer into the left set + if (AddConstantComparison(left_constants, info) == FilterResult::UNSATISFIABLE) { + return FilterResult::UNSATISFIABLE; + } + is_successful = true; } - FinalizeFinish(); + if (is_successful) { + // now check for remaining trasitive filters from the left column + auto transitive_filter = FindTransitiveFilter(comparison.left.get()); + if (transitive_filter != nullptr) { + // 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)); + } + } + return FilterResult::SUCCESS; + } + + return FilterResult::UNSUPPORTED; } -void Event::AddDependency(Event &event) { - total_dependencies++; - event.parents.push_back(weak_ptr(shared_from_this())); +/* + * Find a transitive filter already inserted into the remaining filters + * Check for a match between the right column of bound comparisons and the expression, + * then removes the bound comparison from the remaining filters and returns it + */ +unique_ptr FilterCombiner::FindTransitiveFilter(Expression *expr) { + // We only check for bound column ref + if (expr->type == ExpressionType::BOUND_COLUMN_REF) { + for (idx_t i = 0; i < remaining_filters.size(); i++) { + 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]); + remaining_filters.erase(remaining_filters.begin() + i); + return filter; + } + } + } + } + return nullptr; } -void Event::FinishTask() { - D_ASSERT(finished_tasks.load() < total_tasks.load()); - idx_t current_tasks = total_tasks; - idx_t current_finished = ++finished_tasks; - D_ASSERT(current_finished <= current_tasks); - if (current_finished == current_tasks) { - Finish(); +ValueComparisonResult InvertValueComparisonResult(ValueComparisonResult result) { + if (result == ValueComparisonResult::PRUNE_RIGHT) { + return ValueComparisonResult::PRUNE_LEFT; } + if (result == ValueComparisonResult::PRUNE_LEFT) { + return ValueComparisonResult::PRUNE_RIGHT; + } + return result; } -void Event::InsertEvent(shared_ptr replacement_event) { - replacement_event->parents = move(parents); - replacement_event->AddDependency(*this); - executor.AddEvent(move(replacement_event)); +ValueComparisonResult CompareValueInformation(ExpressionValueInformation &left, ExpressionValueInformation &right) { + if (left.comparison_type == ExpressionType::COMPARE_EQUAL) { + // left is COMPARE_EQUAL, we can either + // (1) prune the right side or + // (2) return UNSATISFIABLE + bool prune_right_side = false; + switch (right.comparison_type) { + case ExpressionType::COMPARE_LESSTHAN: + prune_right_side = left.constant < right.constant; + break; + case ExpressionType::COMPARE_LESSTHANOREQUALTO: + prune_right_side = left.constant <= right.constant; + break; + case ExpressionType::COMPARE_GREATERTHAN: + prune_right_side = left.constant > right.constant; + break; + case ExpressionType::COMPARE_GREATERTHANOREQUALTO: + prune_right_side = left.constant >= right.constant; + break; + case ExpressionType::COMPARE_NOTEQUAL: + prune_right_side = left.constant != right.constant; + break; + default: + D_ASSERT(right.comparison_type == ExpressionType::COMPARE_EQUAL); + prune_right_side = left.constant == right.constant; + break; + } + if (prune_right_side) { + return ValueComparisonResult::PRUNE_RIGHT; + } else { + return ValueComparisonResult::UNSATISFIABLE_CONDITION; + } + } else if (right.comparison_type == ExpressionType::COMPARE_EQUAL) { + // right is COMPARE_EQUAL + return InvertValueComparisonResult(CompareValueInformation(right, left)); + } else if (left.comparison_type == ExpressionType::COMPARE_NOTEQUAL) { + // left is COMPARE_NOTEQUAL, we can either + // (1) prune the left side or + // (2) not prune anything + bool prune_left_side = false; + switch (right.comparison_type) { + case ExpressionType::COMPARE_LESSTHAN: + prune_left_side = left.constant >= right.constant; + break; + case ExpressionType::COMPARE_LESSTHANOREQUALTO: + prune_left_side = left.constant > right.constant; + break; + case ExpressionType::COMPARE_GREATERTHAN: + prune_left_side = left.constant <= right.constant; + break; + case ExpressionType::COMPARE_GREATERTHANOREQUALTO: + prune_left_side = left.constant < right.constant; + break; + default: + D_ASSERT(right.comparison_type == ExpressionType::COMPARE_NOTEQUAL); + prune_left_side = left.constant == right.constant; + break; + } + if (prune_left_side) { + return ValueComparisonResult::PRUNE_LEFT; + } else { + return ValueComparisonResult::PRUNE_NOTHING; + } + } else if (right.comparison_type == ExpressionType::COMPARE_NOTEQUAL) { + return InvertValueComparisonResult(CompareValueInformation(right, left)); + } else if (IsGreaterThan(left.comparison_type) && IsGreaterThan(right.comparison_type)) { + // both comparisons are [>], we can either + // (1) prune the left side or + // (2) prune the right side + if (left.constant > right.constant) { + // left constant is more selective, prune right + return ValueComparisonResult::PRUNE_RIGHT; + } else if (left.constant < right.constant) { + // right constant is more selective, prune left + return ValueComparisonResult::PRUNE_LEFT; + } else { + // constants are equivalent + // however we can still have the scenario where one is [>=] and the other is [>] + // we want to prune the [>=] because [>] is more selective + // if left is [>=] we prune the left, else we prune the right + if (left.comparison_type == ExpressionType::COMPARE_GREATERTHANOREQUALTO) { + return ValueComparisonResult::PRUNE_LEFT; + } else { + return ValueComparisonResult::PRUNE_RIGHT; + } + } + } else if (IsLessThan(left.comparison_type) && IsLessThan(right.comparison_type)) { + // both comparisons are [<], we can either + // (1) prune the left side or + // (2) prune the right side + if (left.constant < right.constant) { + // left constant is more selective, prune right + return ValueComparisonResult::PRUNE_RIGHT; + } else if (left.constant > right.constant) { + // right constant is more selective, prune left + return ValueComparisonResult::PRUNE_LEFT; + } else { + // constants are equivalent + // however we can still have the scenario where one is [<=] and the other is [<] + // we want to prune the [<=] because [<] is more selective + // if left is [<=] we prune the left, else we prune the right + if (left.comparison_type == ExpressionType::COMPARE_LESSTHANOREQUALTO) { + return ValueComparisonResult::PRUNE_LEFT; + } else { + return ValueComparisonResult::PRUNE_RIGHT; + } + } + } else if (IsLessThan(left.comparison_type)) { + D_ASSERT(IsGreaterThan(right.comparison_type)); + // left is [<] and right is [>], in this case we can either + // (1) prune nothing or + // (2) return UNSATISFIABLE + // the SMALLER THAN constant has to be greater than the BIGGER THAN constant + if (left.constant >= right.constant) { + return ValueComparisonResult::PRUNE_NOTHING; + } else { + return ValueComparisonResult::UNSATISFIABLE_CONDITION; + } + } else { + // left is [>] and right is [<] or [!=] + D_ASSERT(IsLessThan(right.comparison_type) && IsGreaterThan(left.comparison_type)); + return InvertValueComparisonResult(CompareValueInformation(right, left)); + } } -void Event::SetTasks(vector> tasks) { - auto &ts = TaskScheduler::GetScheduler(executor.context); - D_ASSERT(total_tasks == 0); - D_ASSERT(!tasks.empty()); - this->total_tasks = tasks.size(); - for (auto &task : tasks) { - ts.ScheduleTask(executor.GetToken(), move(task)); +void FilterCombiner::LookUpConjunctions(Expression *expr) { + if (expr->GetExpressionType() == ExpressionType::CONJUNCTION_OR) { + auto root_or_expr = (BoundConjunctionExpression *)expr; + for (const auto &entry : map_col_conjunctions) { + for (const auto &conjs_to_push : entry.second) { + if (conjs_to_push->root_or->Equals(root_or_expr)) { + return; + } + } + } + + cur_root_or = root_or_expr; + cur_conjunction = root_or_expr; + cur_colref_to_push = nullptr; + if (!BFSLookUpConjunctions(cur_root_or)) { + if (cur_colref_to_push) { + auto entry = map_col_conjunctions.find(cur_colref_to_push); + auto &vec_conjs_to_push = entry->second; + if (vec_conjs_to_push.size() == 1) { + map_col_conjunctions.erase(entry); + return; + } + vec_conjs_to_push.pop_back(); + } + } + return; } + + // Verify if the expression has a column already pushed down by other OR expression + VerifyOrsToPush(*expr); } -} // namespace duckdb +bool FilterCombiner::BFSLookUpConjunctions(BoundConjunctionExpression *conjunction) { + vector conjunctions_to_visit; + for (auto &child : conjunction->children) { + switch (child->GetExpressionClass()) { + case ExpressionClass::BOUND_CONJUNCTION: { + auto child_conjunction = (BoundConjunctionExpression *)child.get(); + conjunctions_to_visit.emplace_back(child_conjunction); + break; + } + case ExpressionClass::BOUND_COMPARISON: { + if (!UpdateConjunctionFilter((BoundComparisonExpression *)child.get())) { + return false; + } + break; + } + default: { + return false; + } + } + } + for (auto child_conjunction : conjunctions_to_visit) { + cur_conjunction = child_conjunction; + // traverse child conjuction + if (!BFSLookUpConjunctions(child_conjunction)) { + return false; + } + } + return true; +} +void FilterCombiner::VerifyOrsToPush(Expression &expr) { + if (expr.type == ExpressionType::BOUND_COLUMN_REF) { + auto colref = (BoundColumnRefExpression *)&expr; + auto entry = map_col_conjunctions.find(colref); + if (entry == map_col_conjunctions.end()) { + return; + } + map_col_conjunctions.erase(entry); + } + ExpressionIterator::EnumerateChildren(expr, [&](Expression &child) { VerifyOrsToPush(child); }); +} +bool FilterCombiner::UpdateConjunctionFilter(BoundComparisonExpression *comparison_expr) { + bool left_is_scalar = comparison_expr->left->IsFoldable(); + bool right_is_scalar = comparison_expr->right->IsFoldable(); + Expression *non_scalar_expr; + if (left_is_scalar || right_is_scalar) { + // only support comparison with scalar + non_scalar_expr = left_is_scalar ? comparison_expr->right.get() : comparison_expr->left.get(); + if (non_scalar_expr->GetExpressionType() == ExpressionType::BOUND_COLUMN_REF) { + return UpdateFilterByColumn((BoundColumnRefExpression *)non_scalar_expr, comparison_expr); + } + } + return false; +} +bool FilterCombiner::UpdateFilterByColumn(BoundColumnRefExpression *column_ref, + BoundComparisonExpression *comparison_expr) { + if (cur_colref_to_push == nullptr) { + cur_colref_to_push = column_ref; + auto or_conjunction = make_unique(ExpressionType::CONJUNCTION_OR); + 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->root_or = cur_root_or; -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parallel/pipeline_executor.hpp -// -// -//===----------------------------------------------------------------------===// + auto &&vec_col_conjs = map_col_conjunctions[column_ref]; + vec_col_conjs.emplace_back(move(conjs_to_push)); + vec_colref_insertion_order.emplace_back(column_ref); + return true; + } + auto entry = map_col_conjunctions.find(cur_colref_to_push); + D_ASSERT(entry != map_col_conjunctions.end()); + auto &conjunctions_to_push = entry->second.back(); + if (!cur_colref_to_push->Equals(column_ref)) { + // check for multiple colunms in the same root OR node + if (cur_root_or == cur_conjunction) { + return false; + } + // found an AND using a different column, we should stop the look up + if (cur_conjunction->GetExpressionType() == ExpressionType::CONJUNCTION_AND) { + return false; + } + // found a different column, AND conditions cannot be preserved anymore + conjunctions_to_push->preserve_and = false; + return true; + } + auto &last_conjunction = conjunctions_to_push->conjunctions.back(); + if (cur_conjunction->GetExpressionType() == last_conjunction->GetExpressionType()) { + last_conjunction->children.emplace_back(comparison_expr->Copy()); + } 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)); + } + return true; +} +void FilterCombiner::GenerateORFilters(TableFilterSet &table_filter, vector &column_ids) { + for (const auto colref : vec_colref_insertion_order) { + auto column_index = column_ids[colref->binding.column_index]; + if (column_index == COLUMN_IDENTIFIER_ROW_ID) { + break; + } + for (const auto &conjunctions_to_push : map_col_conjunctions[colref]) { + // root OR filter to push into the TableFilter + auto root_or_filter = make_unique(); + // variable to hold the last conjuntion filter pointer + // the next filter will be added into it, i.e., we create a chain of conjunction filters + ConjunctionFilter *last_conj_filter = root_or_filter.get(); + for (auto &conjunction : conjunctions_to_push->conjunctions) { + if (conjunction->GetExpressionType() == ExpressionType::CONJUNCTION_AND && + conjunctions_to_push->preserve_and) { + GenerateConjunctionFilter(conjunction.get(), last_conj_filter); + } else { + GenerateConjunctionFilter(conjunction.get(), last_conj_filter); + } + } + table_filter.PushFilter(column_index, move(root_or_filter)); + } + } + map_col_conjunctions.clear(); + vec_colref_insertion_order.clear(); +} +} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/stack.hpp +// duckdb/optimizer/filter_pullup.hpp // // //===----------------------------------------------------------------------===// -#include -namespace duckdb { -using std::stack; -} -#include -namespace duckdb { -class Executor; -//! The Pipeline class represents an execution pipeline -class PipelineExecutor { - static constexpr const idx_t CACHE_THRESHOLD = 64; -public: - PipelineExecutor(ClientContext &context, Pipeline &pipeline); +namespace duckdb { - //! Fully execute a pipeline with a source and a sink until the source is completely exhausted - void Execute(); - //! Push a single input DataChunk into the pipeline. - //! Returns either OperatorResultType::NEED_MORE_INPUT or OperatorResultType::FINISHED - //! If OperatorResultType::FINISHED is returned, more input will not change the result anymore - OperatorResultType ExecutePush(DataChunk &input); - //! Called after depleting the source: finalizes the execution of this pipeline executor - //! This should only be called once per PipelineExecutor - void PushFinalize(); +class FilterPullup { +public: + explicit FilterPullup(bool pullup = false, bool add_column = false) + : can_pullup(pullup), can_add_column(add_column) { + } - //! Initializes a chunk with the types that will flow out of ExecutePull - void InitializeChunk(DataChunk &chunk); - //! Execute a pipeline without a sink, and retrieve a single DataChunk - //! Returns an empty chunk when finished. - void ExecutePull(DataChunk &result); - //! Called after depleting the source using ExecutePull - //! This flushes profiler states - void PullFinalize(); + //! Perform filter pullup + unique_ptr Rewrite(unique_ptr op); private: - //! The pipeline to process - Pipeline &pipeline; - //! The thread context of this executor - ThreadContext thread; - //! The total execution context of this executor - ExecutionContext context; + vector> filters_expr_pullup; - //! Intermediate chunks for the operators - vector> intermediate_chunks; - //! Intermediate states for the operators - vector> intermediate_states; + // only pull up filters when there is a fork + bool can_pullup = false; - //! The local source state - unique_ptr local_source_state; - //! The local sink state (if any) - unique_ptr local_sink_state; + // identifiy case the branch is a set operation (INTERSECT or EXCEPT) + bool can_add_column = false; - //! The final chunk used for moving data into the sink - DataChunk final_chunk; +private: + // Generate logical filters pulled up + unique_ptr GeneratePullupFilter(unique_ptr child, + vector> &expressions); - //! The operators that are not yet finished executing and have data remaining - //! If the stack of in_process_operators is empty, we fetch from the source instead - stack in_process_operators; - //! Whether or not the pipeline has been finalized (used for verification only) - bool finalized = false; - //! Whether or not the pipeline has finished processing - bool finished_processing = false; + //! Pull up a LogicalFilter op + unique_ptr PullupFilter(unique_ptr op); - //! Cached chunks for any operators that require caching - vector> cached_chunks; + //! Pull up filter in a LogicalProjection op + unique_ptr PullupProjection(unique_ptr op); -private: - void StartOperator(PhysicalOperator *op); - void EndOperator(PhysicalOperator *op, DataChunk *chunk); + //! Pull up filter in a LogicalCrossProduct op + unique_ptr PullupCrossProduct(unique_ptr op); - //! Reset the operator index to the first operator - void GoToSource(idx_t ¤t_idx, idx_t initial_idx); - void FetchFromSource(DataChunk &result); + unique_ptr PullupJoin(unique_ptr op); - OperatorResultType ExecutePushInternal(DataChunk &input, idx_t initial_idx = 0); - //! Pushes a chunk through the pipeline and returns a single result chunk - //! Returns whether or not a new input chunk is needed, or whether or not we are finished - OperatorResultType Execute(DataChunk &input, DataChunk &result, idx_t initial_index = 0); + // PPullup filter in a left join + unique_ptr PullupFromLeft(unique_ptr op); - static bool CanCacheType(const LogicalType &type); - void CacheChunk(DataChunk &input, idx_t operator_idx); -}; + // Pullup filter in a inner join + unique_ptr PullupInnerJoin(unique_ptr op); -} // namespace duckdb + // Pullup filter in LogicalIntersect or LogicalExcept op + unique_ptr PullupSetOperation(unique_ptr op); + unique_ptr PullupBothSide(unique_ptr op); -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parallel/pipeline_event.hpp -// -// -//===----------------------------------------------------------------------===// + // Finish pull up at this operator + unique_ptr FinishPullup(unique_ptr op); + // special treatment for SetOperations and projections + void ProjectSetOperation(LogicalProjection &proj); +}; // end FilterPullup +} // namespace duckdb namespace duckdb { -class PipelineEvent : public Event { -public: - PipelineEvent(shared_ptr pipeline); +unique_ptr FilterPullup::Rewrite(unique_ptr op) { + switch (op->type) { + case LogicalOperatorType::LOGICAL_FILTER: + return PullupFilter(move(op)); + case LogicalOperatorType::LOGICAL_PROJECTION: + return PullupProjection(move(op)); + case LogicalOperatorType::LOGICAL_CROSS_PRODUCT: + return PullupCrossProduct(move(op)); + case LogicalOperatorType::LOGICAL_COMPARISON_JOIN: + case LogicalOperatorType::LOGICAL_ANY_JOIN: + case LogicalOperatorType::LOGICAL_DELIM_JOIN: + return PullupJoin(move(op)); + case LogicalOperatorType::LOGICAL_INTERSECT: + case LogicalOperatorType::LOGICAL_EXCEPT: + return PullupSetOperation(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])); + return op; + } + default: + return FinishPullup(move(op)); + } +} - //! The pipeline that this event belongs to - shared_ptr pipeline; +unique_ptr FilterPullup::PullupJoin(unique_ptr op) { + D_ASSERT(op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN || + op->type == LogicalOperatorType::LOGICAL_ANY_JOIN || op->type == LogicalOperatorType::LOGICAL_DELIM_JOIN); + auto &join = (LogicalJoin &)*op; -public: - void Schedule() override; - void FinishEvent() override; -}; + switch (join.join_type) { + case JoinType::INNER: + return PullupInnerJoin(move(op)); + case JoinType::LEFT: + case JoinType::ANTI: + case JoinType::SEMI: { + can_add_column = true; + return PullupFromLeft(move(op)); + } + default: + // unsupported join type: call children pull up + return FinishPullup(move(op)); + } +} -} // namespace duckdb +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)); +} + +unique_ptr FilterPullup::PullupCrossProduct(unique_ptr op) { + D_ASSERT(op->type == LogicalOperatorType::LOGICAL_CROSS_PRODUCT); + return PullupBothSide(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])); + } + expressions.clear(); + filter->children.push_back(move(child)); + return 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])); + } + // 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); +} + +} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/parallel/pipeline_finish_event.hpp +// duckdb/optimizer/filter_pushdown.hpp // // //===----------------------------------------------------------------------===// @@ -115556,754 +120059,630 @@ class PipelineEvent : public Event { -namespace duckdb { -class Executor; -class PipelineFinishEvent : public Event { -public: - PipelineFinishEvent(shared_ptr pipeline); +namespace duckdb { - //! The pipeline that this event belongs to - shared_ptr pipeline; +class Optimizer; +class FilterPushdown { public: - void Schedule() override; - void FinishEvent() override; -}; + explicit FilterPushdown(Optimizer &optimizer) : optimizer(optimizer) { + } + //! Perform filter pushdown + unique_ptr Rewrite(unique_ptr op); -} // namespace duckdb + struct Filter { + unordered_set bindings; + unique_ptr filter; -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parallel/pipeline_complete_event.hpp -// -// -//===----------------------------------------------------------------------===// + Filter() { + } + explicit Filter(unique_ptr filter) : filter(move(filter)) { + } + void ExtractBindings(); + }; +private: + vector> filters; + Optimizer &optimizer; + //! Push down a LogicalAggregate op + unique_ptr PushdownAggregate(unique_ptr op); + //! Push down a LogicalFilter op + unique_ptr PushdownFilter(unique_ptr op); + //! Push down a LogicalCrossProduct op + unique_ptr PushdownCrossProduct(unique_ptr op); + //! Push down a join operator + unique_ptr PushdownJoin(unique_ptr op); + //! Push down a LogicalProjection op + unique_ptr PushdownProjection(unique_ptr op); + //! Push down a LogicalSetOperation op + unique_ptr PushdownSetOperation(unique_ptr op); + //! Push down a LogicalGet op + unique_ptr PushdownGet(unique_ptr op); + // Pushdown an inner join + unique_ptr PushdownInnerJoin(unique_ptr op, unordered_set &left_bindings, + unordered_set &right_bindings); + // Pushdown a left join + unique_ptr PushdownLeftJoin(unique_ptr op, unordered_set &left_bindings, + unordered_set &right_bindings); + // Pushdown a mark join + unique_ptr PushdownMarkJoin(unique_ptr op, unordered_set &left_bindings, + unordered_set &right_bindings); + // Pushdown a single join + unique_ptr PushdownSingleJoin(unique_ptr op, unordered_set &left_bindings, + unordered_set &right_bindings); + // Finish pushing down at this operator, creating a LogicalFilter to store any of the stored filters and recursively + // pushing down into its children (if any) + unique_ptr FinishPushdown(unique_ptr op); + //! Adds a filter to the set of filters. Returns FilterResult::UNSATISFIABLE if the subtree should be stripped, or + //! FilterResult::SUCCESS otherwise + FilterResult AddFilter(unique_ptr expr); + //! Generate filters from the current set of filters stored in the FilterCombiner + void GenerateFilters(); + //! if there are filters in this FilterPushdown node, push them into the combiner + void PushFilters(); -namespace duckdb { -class Executor; + FilterCombiner combiner; +}; -class PipelineCompleteEvent : public Event { -public: - PipelineCompleteEvent(Executor &executor, bool complete_pipeline_p); +} // namespace duckdb - bool complete_pipeline; -public: - void Schedule() override; - void FinalizeFinish() override; -}; -} // namespace duckdb -#include namespace duckdb { -Executor::Executor(ClientContext &context) : context(context) { -} +using Filter = FilterPushdown::Filter; -Executor::~Executor() { +unique_ptr FilterPushdown::Rewrite(unique_ptr op) { + D_ASSERT(!combiner.HasFilters()); + switch (op->type) { + case LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY: + return PushdownAggregate(move(op)); + case LogicalOperatorType::LOGICAL_FILTER: + return PushdownFilter(move(op)); + case LogicalOperatorType::LOGICAL_CROSS_PRODUCT: + return PushdownCrossProduct(move(op)); + case LogicalOperatorType::LOGICAL_COMPARISON_JOIN: + case LogicalOperatorType::LOGICAL_ANY_JOIN: + case LogicalOperatorType::LOGICAL_DELIM_JOIN: + return PushdownJoin(move(op)); + case LogicalOperatorType::LOGICAL_PROJECTION: + return PushdownProjection(move(op)); + case LogicalOperatorType::LOGICAL_INTERSECT: + case LogicalOperatorType::LOGICAL_EXCEPT: + case LogicalOperatorType::LOGICAL_UNION: + return PushdownSetOperation(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])); + return op; + } + case LogicalOperatorType::LOGICAL_GET: + return PushdownGet(move(op)); + default: + return FinishPushdown(move(op)); + } } -Executor &Executor::Get(ClientContext &context) { - return context.executor; +unique_ptr FilterPushdown::PushdownJoin(unique_ptr op) { + D_ASSERT(op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN || + op->type == LogicalOperatorType::LOGICAL_ANY_JOIN || op->type == LogicalOperatorType::LOGICAL_DELIM_JOIN); + auto &join = (LogicalJoin &)*op; + unordered_set left_bindings, right_bindings; + LogicalJoin::GetTableReferences(*op->children[0], left_bindings); + LogicalJoin::GetTableReferences(*op->children[1], right_bindings); + + switch (join.join_type) { + case JoinType::INNER: + return PushdownInnerJoin(move(op), left_bindings, right_bindings); + case JoinType::LEFT: + return PushdownLeftJoin(move(op), left_bindings, right_bindings); + case JoinType::MARK: + return PushdownMarkJoin(move(op), left_bindings, right_bindings); + case JoinType::SINGLE: + return PushdownSingleJoin(move(op), left_bindings, right_bindings); + default: + // unsupported join type: stop pushing down + return FinishPushdown(move(op)); + } +} +void FilterPushdown::PushFilters() { + for (auto &f : filters) { + auto result = combiner.AddFilter(move(f->filter)); + D_ASSERT(result == FilterResult::SUCCESS); + (void)result; + } + filters.clear(); } -void Executor::AddEvent(shared_ptr event) { - lock_guard elock(executor_lock); - events.push_back(move(event)); +FilterResult FilterPushdown::AddFilter(unique_ptr expr) { + PushFilters(); + // split up the filters by AND predicate + vector> expressions; + expressions.push_back(move(expr)); + LogicalFilter::SplitPredicates(expressions); + // push the filters into the combiner + for (auto &child_expr : expressions) { + if (combiner.AddFilter(move(child_expr)) == FilterResult::UNSATISFIABLE) { + return FilterResult::UNSATISFIABLE; + } + } + return FilterResult::SUCCESS; } -struct PipelineEventStack { - Event *pipeline_event; - Event *pipeline_finish_event; - Event *pipeline_complete_event; -}; +void FilterPushdown::GenerateFilters() { + if (!filters.empty()) { + D_ASSERT(!combiner.HasFilters()); + return; + } + combiner.GenerateFilters([&](unique_ptr filter) { + auto f = make_unique(); + f->filter = move(filter); + f->ExtractBindings(); + filters.push_back(move(f)); + }); +} -Pipeline *Executor::ScheduleUnionPipeline(const shared_ptr &pipeline, const Pipeline *parent, - event_map_t &event_map, vector> &events) { - pipeline->Ready(); +unique_ptr FilterPushdown::FinishPushdown(unique_ptr op) { + // unhandled type, first perform filter pushdown in its children + for (auto &child : op->children) { + FilterPushdown pushdown(optimizer); + child = pushdown.Rewrite(move(child)); + } + // now push any existing filters + if (filters.empty()) { + // no filters to push + return op; + } + auto filter = make_unique(); + for (auto &f : filters) { + filter->expressions.push_back(move(f->filter)); + } + filter->children.push_back(move(op)); + return move(filter); +} - D_ASSERT(pipeline); - auto pipeline_event = make_shared(pipeline); +void FilterPushdown::Filter::ExtractBindings() { + bindings.clear(); + LogicalJoin::GetExpressionBindings(*filter, bindings); +} - auto parent_stack_entry = event_map.find(parent); - D_ASSERT(parent_stack_entry != event_map.end()); +} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/in_clause_rewriter.hpp +// +// +//===----------------------------------------------------------------------===// - auto &parent_stack = parent_stack_entry->second; - PipelineEventStack stack; - stack.pipeline_event = pipeline_event.get(); - stack.pipeline_finish_event = parent_stack.pipeline_finish_event; - stack.pipeline_complete_event = parent_stack.pipeline_complete_event; - stack.pipeline_event->AddDependency(*parent_stack.pipeline_event); - parent_stack.pipeline_finish_event->AddDependency(*pipeline_event); - events.push_back(move(pipeline_event)); - event_map.insert(make_pair(pipeline.get(), stack)); - auto parent_pipeline = pipeline.get(); +namespace duckdb { +class Optimizer; - auto union_entry = union_pipelines.find(pipeline.get()); - if (union_entry != union_pipelines.end()) { - for (auto &entry : union_entry->second) { - parent_pipeline = ScheduleUnionPipeline(entry, parent_pipeline, event_map, events); - } +class InClauseRewriter : public LogicalOperatorVisitor { +public: + explicit InClauseRewriter(Optimizer &optimizer) : optimizer(optimizer) { } - return parent_pipeline; -} + Optimizer &optimizer; + unique_ptr root; -void Executor::ScheduleChildPipeline(Pipeline *parent, const shared_ptr &pipeline, event_map_t &event_map, - vector> &events) { - pipeline->Ready(); +public: + unique_ptr Rewrite(unique_ptr op); - auto child_ptr = pipeline.get(); - auto dependencies = child_dependencies.find(child_ptr); - D_ASSERT(union_pipelines.find(child_ptr) == union_pipelines.end()); - D_ASSERT(dependencies != child_dependencies.end()); - // create the pipeline event and the event stack - auto pipeline_event = make_shared(pipeline); + unique_ptr VisitReplace(BoundOperatorExpression &expr, unique_ptr *expr_ptr) override; +}; - auto parent_entry = event_map.find(parent); - PipelineEventStack stack; - stack.pipeline_event = pipeline_event.get(); - stack.pipeline_finish_event = parent_entry->second.pipeline_finish_event; - stack.pipeline_complete_event = parent_entry->second.pipeline_complete_event; +} // namespace duckdb - // set up the dependencies for this child pipeline - unordered_set finish_events; - for (auto &dep : dependencies->second) { - auto dep_entry = event_map.find(dep); - D_ASSERT(dep_entry != event_map.end()); - D_ASSERT(dep_entry->second.pipeline_event); - D_ASSERT(dep_entry->second.pipeline_finish_event); - auto finish_event = dep_entry->second.pipeline_finish_event; - stack.pipeline_event->AddDependency(*dep_entry->second.pipeline_event); - if (finish_events.find(finish_event) == finish_events.end()) { - finish_event->AddDependency(*stack.pipeline_event); - finish_events.insert(finish_event); - } - } - events.push_back(move(pipeline_event)); - event_map.insert(make_pair(child_ptr, stack)); -} -void Executor::SchedulePipeline(const shared_ptr &pipeline, event_map_t &event_map, - vector> &events, bool complete_pipeline) { - D_ASSERT(pipeline); - pipeline->Ready(); - auto pipeline_event = make_shared(pipeline); - auto pipeline_finish_event = make_shared(pipeline); - auto pipeline_complete_event = make_shared(pipeline->executor, complete_pipeline); - PipelineEventStack stack; - stack.pipeline_event = pipeline_event.get(); - stack.pipeline_finish_event = pipeline_finish_event.get(); - stack.pipeline_complete_event = pipeline_complete_event.get(); - pipeline_finish_event->AddDependency(*pipeline_event); - pipeline_complete_event->AddDependency(*pipeline_finish_event); - events.push_back(move(pipeline_event)); - events.push_back(move(pipeline_finish_event)); - events.push_back(move(pipeline_complete_event)); - event_map.insert(make_pair(pipeline.get(), stack)); +namespace duckdb { - auto union_entry = union_pipelines.find(pipeline.get()); - if (union_entry != union_pipelines.end()) { - auto parent_pipeline = pipeline.get(); - for (auto &entry : union_entry->second) { - parent_pipeline = ScheduleUnionPipeline(entry, parent_pipeline, event_map, events); - } +unique_ptr InClauseRewriter::Rewrite(unique_ptr op) { + if (op->children.size() == 1) { + root = move(op->children[0]); + VisitOperatorExpressions(*op); + op->children[0] = move(root); } + + for (auto &child : op->children) { + child = Rewrite(move(child)); + } + return op; } -void Executor::ScheduleEventsInternal(const vector> &pipelines, - unordered_map>> &child_pipelines, - vector> &events, bool main_schedule) { - D_ASSERT(events.empty()); - // create all the required pipeline events - event_map_t event_map; - for (auto &pipeline : pipelines) { - SchedulePipeline(pipeline, event_map, events, main_schedule); +unique_ptr InClauseRewriter::VisitReplace(BoundOperatorExpression &expr, unique_ptr *expr_ptr) { + if (expr.type != ExpressionType::COMPARE_IN && expr.type != ExpressionType::COMPARE_NOT_IN) { + return nullptr; } - // schedule child pipelines - for (auto &entry : child_pipelines) { - // iterate in reverse order - // since child entries are added from top to bottom - // dependencies are in reverse order (bottom to top) - for (idx_t i = entry.second.size(); i > 0; i--) { - auto &child_entry = entry.second[i - 1]; - ScheduleChildPipeline(entry.first, child_entry, event_map, events); + D_ASSERT(root); + auto in_type = expr.children[0]->return_type; + bool is_regular_in = expr.type == ExpressionType::COMPARE_IN; + bool all_scalar = true; + // IN clause with many children: try to generate a mark join that replaces this IN expression + // we can only do this if the expressions in the expression list are scalar + for (idx_t i = 1; i < expr.children.size(); i++) { + D_ASSERT(expr.children[i]->return_type == in_type); + if (!expr.children[i]->IsFoldable()) { + // non-scalar expression + all_scalar = false; } } - // set up the dependencies between pipeline events - for (auto &entry : event_map) { - auto pipeline = entry.first; - for (auto &dependency : pipeline->dependencies) { - auto dep = dependency.lock(); - D_ASSERT(dep); - auto event_map_entry = event_map.find(dep.get()); - D_ASSERT(event_map_entry != event_map.end()); - auto &dep_entry = event_map_entry->second; - D_ASSERT(dep_entry.pipeline_complete_event); - entry.second.pipeline_event->AddDependency(*dep_entry.pipeline_complete_event); + if (expr.children.size() == 2) { + // only one child + // IN: turn into X = 1 + // 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])); + } + if (expr.children.size() < 6 || !all_scalar) { + // low amount of children or not all scalar + // IN: turn into (X = 1 OR X = 2 OR X = 3...) + // NOT IN: turn into (X <> 1 AND X <> 2 AND X <> 3 ...) + auto conjunction = make_unique(is_regular_in ? ExpressionType::CONJUNCTION_OR + : ExpressionType::CONJUNCTION_AND); + 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]))); } + return move(conjunction); } - // schedule the pipelines that do not have dependencies - for (auto &event : events) { - if (!event->HasDependencies()) { - event->Schedule(); + // IN clause with many constant children + // generate a mark join that replaces this IN expression + // first generate a ChunkCollection from the set of expressions + vector types = {in_type}; + auto collection = make_unique(); + DataChunk chunk; + chunk.Initialize(types); + for (idx_t i = 1; i < expr.children.size(); i++) { + // resolve this expression to a constant + auto value = ExpressionExecutor::EvaluateScalar(*expr.children[i]); + idx_t index = chunk.size(); + chunk.SetCardinality(chunk.size() + 1); + chunk.SetValue(0, index, value); + if (chunk.size() == STANDARD_VECTOR_SIZE || i + 1 == expr.children.size()) { + // chunk full: append to chunk collection + collection->Append(chunk); + chunk.Reset(); } } -} - -void Executor::ScheduleEvents() { - ScheduleEventsInternal(pipelines, child_pipelines, events); -} - -void Executor::ReschedulePipelines(const vector> &pipelines, vector> &events) { - unordered_map>> child_pipelines; - ScheduleEventsInternal(pipelines, child_pipelines, events, false); -} + // now generate a ChunkGet that scans this collection + auto chunk_index = optimizer.binder.GenerateTableIndex(); + auto chunk_scan = make_unique(chunk_index, types, move(collection)); -void Executor::ExtractPipelines(shared_ptr &pipeline, vector> &result) { - pipeline->Ready(); + // 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)); + // create the JOIN condition + JoinCondition cond; + cond.left = move(expr.children[0]); - auto pipeline_ptr = pipeline.get(); - result.push_back(move(pipeline)); - auto union_entry = union_pipelines.find(pipeline_ptr); - if (union_entry != union_pipelines.end()) { - auto &union_pipeline_list = union_entry->second; - for (auto &pipeline : union_pipeline_list) { - ExtractPipelines(pipeline, result); - } - union_pipelines.erase(pipeline_ptr); - } - auto child_entry = child_pipelines.find(pipeline_ptr); - if (child_entry != child_pipelines.end()) { - for (auto &entry : child_entry->second) { - ExtractPipelines(entry, result); - } - child_pipelines.erase(pipeline_ptr); - } -} + cond.right = make_unique(in_type, ColumnBinding(chunk_index, 0)); + cond.comparison = ExpressionType::COMPARE_EQUAL; + join->conditions.push_back(move(cond)); + root = move(join); -bool Executor::NextExecutor() { - if (root_pipeline_idx >= root_pipelines.size()) { - return false; + // we replace the original subquery with a BoundColumnRefExpression referring to the mark column + unique_ptr result = + make_unique("IN (...)", LogicalType::BOOLEAN, ColumnBinding(chunk_index, 0)); + 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); } - root_executor = make_unique(context, *root_pipelines[root_pipeline_idx]); - root_pipeline_idx++; - return true; + return result; } -void Executor::VerifyPipeline(Pipeline &pipeline) { - D_ASSERT(!pipeline.ToString().empty()); - auto operators = pipeline.GetOperators(); - for (auto &other_pipeline : pipelines) { - auto other_operators = other_pipeline->GetOperators(); - for (idx_t op_idx = 0; op_idx < operators.size(); op_idx++) { - for (idx_t other_idx = 0; other_idx < other_operators.size(); other_idx++) { - auto &left = *operators[op_idx]; - auto &right = *other_operators[other_idx]; - if (left.Equals(right)) { - D_ASSERT(right.Equals(left)); - } else { - D_ASSERT(!right.Equals(left)); - } - } - } - } -} - -void Executor::VerifyPipelines() { -#ifdef DEBUG - for (auto &pipeline : pipelines) { - VerifyPipeline(*pipeline); - } - for (auto &pipeline : root_pipelines) { - VerifyPipeline(*pipeline); - } -#endif -} - -void Executor::WorkOnTasks() { - auto &scheduler = TaskScheduler::GetScheduler(context); +} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/join_order/join_relation.hpp +// +// +//===----------------------------------------------------------------------===// - unique_ptr task; - while (scheduler.GetTaskFromProducer(*producer, task)) { - task->Execute(); - task.reset(); - } -} -void Executor::Initialize(PhysicalOperator *plan) { - Reset(); - auto &scheduler = TaskScheduler::GetScheduler(context); - { - lock_guard elock(executor_lock); - physical_plan = plan; - context.profiler->Initialize(physical_plan); - this->producer = scheduler.CreateProducer(); - auto root_pipeline = make_shared(*this); - root_pipeline->sink = nullptr; - BuildPipelines(physical_plan, root_pipeline.get()); - this->total_pipelines = pipelines.size(); - root_pipeline_idx = 0; - ExtractPipelines(root_pipeline, root_pipelines); +namespace duckdb { +class LogicalOperator; - VerifyPipelines(); +//! Represents a single relation and any metadata accompanying that relation +struct SingleJoinRelation { + LogicalOperator *op; + LogicalOperator *parent; - ScheduleEvents(); + SingleJoinRelation() { } + SingleJoinRelation(LogicalOperator *op, LogicalOperator *parent) : op(op), parent(parent) { + } +}; - // now execute tasks from this producer until all pipelines are completed - while (completed_pipelines < total_pipelines) { - WorkOnTasks(); - if (!HasError()) { - // no exceptions: continue - continue; - } - - // an exception has occurred executing one of the pipelines - // we need to wait until all threads are finished - // we do this by creating weak pointers to all pipelines - // then clearing our references to the pipelines - // and waiting until all pipelines have been destroyed - vector> weak_references; - { - lock_guard elock(executor_lock); - weak_references.reserve(pipelines.size()); - for (auto &pipeline : pipelines) { - weak_references.push_back(weak_ptr(pipeline)); - } - for (auto &kv : union_pipelines) { - for (auto &pipeline : kv.second) { - weak_references.push_back(weak_ptr(pipeline)); - } - } - for (auto &kv : child_pipelines) { - for (auto &pipeline : kv.second) { - weak_references.push_back(weak_ptr(pipeline)); - } - } - pipelines.clear(); - union_pipelines.clear(); - child_pipelines.clear(); - events.clear(); - } - for (auto &weak_ref : weak_references) { - while (true) { - auto weak = weak_ref.lock(); - if (!weak) { - break; - } - } - } - ThrowException(); +//! Set of relations, used in the join graph. +struct JoinRelationSet { + JoinRelationSet(unique_ptr relations, idx_t count) : relations(move(relations)), count(count) { } - lock_guard elock(executor_lock); - pipelines.clear(); - NextExecutor(); - if (!exceptions.empty()) { // LCOV_EXCL_START - // an exception has occurred executing one of the pipelines - ThrowExceptionInternal(); - } // LCOV_EXCL_STOP -} + string ToString() const; -void Executor::Reset() { - lock_guard elock(executor_lock); - delim_join_dependencies.clear(); - recursive_cte = nullptr; - physical_plan = nullptr; - root_executor.reset(); - root_pipelines.clear(); - root_pipeline_idx = 0; - completed_pipelines = 0; - total_pipelines = 0; - exceptions.clear(); - pipelines.clear(); - events.clear(); - union_pipelines.clear(); - child_pipelines.clear(); - child_dependencies.clear(); -} + unique_ptr relations; + idx_t count; -void Executor::AddChildPipeline(Pipeline *current) { - D_ASSERT(!current->operators.empty()); - // found another operator that is a source - // schedule a child pipeline - auto child_pipeline = make_shared(*this); - auto child_pipeline_ptr = child_pipeline.get(); - child_pipeline->sink = current->sink; - child_pipeline->operators = current->operators; - child_pipeline->source = current->operators.back(); - D_ASSERT(child_pipeline->source->IsSource()); - child_pipeline->operators.pop_back(); + static bool IsSubset(JoinRelationSet *super, JoinRelationSet *sub); +}; - vector dependencies; - dependencies.push_back(current); - auto child_entry = child_pipelines.find(current); - if (child_entry != child_pipelines.end()) { - for (auto ¤t_child : child_entry->second) { - D_ASSERT(child_dependencies.find(current_child.get()) != child_dependencies.end()); - child_dependencies[current_child.get()].push_back(child_pipeline_ptr); - } - } - D_ASSERT(child_dependencies.find(child_pipeline_ptr) == child_dependencies.end()); - child_dependencies.insert(make_pair(child_pipeline_ptr, move(dependencies))); - child_pipelines[current].push_back(move(child_pipeline)); -} +//! 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; + }; -void Executor::BuildPipelines(PhysicalOperator *op, Pipeline *current) { - D_ASSERT(current); - if (op->IsSink()) { - // operator is a sink, build a pipeline - op->sink_state.reset(); +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); - PhysicalOperator *pipeline_child = nullptr; - switch (op->type) { - case PhysicalOperatorType::CREATE_TABLE_AS: - case PhysicalOperatorType::INSERT: - case PhysicalOperatorType::DELETE_OPERATOR: - case PhysicalOperatorType::UPDATE: - case PhysicalOperatorType::HASH_GROUP_BY: - case PhysicalOperatorType::SIMPLE_AGGREGATE: - case PhysicalOperatorType::PERFECT_HASH_GROUP_BY: - case PhysicalOperatorType::WINDOW: - case PhysicalOperatorType::ORDER_BY: - case PhysicalOperatorType::RESERVOIR_SAMPLE: - case PhysicalOperatorType::TOP_N: - case PhysicalOperatorType::COPY_TO_FILE: - case PhysicalOperatorType::LIMIT: - case PhysicalOperatorType::EXPRESSION_SCAN: - D_ASSERT(op->children.size() == 1); - // single operator: - // the operator becomes the data source of the current pipeline - current->source = op; - // we create a new pipeline starting from the child - pipeline_child = op->children[0].get(); - break; - case PhysicalOperatorType::EXPORT: - // EXPORT has an optional child - // we only need to schedule child pipelines if there is a child - current->source = op; - if (op->children.empty()) { - return; - } - D_ASSERT(op->children.size() == 1); - pipeline_child = op->children[0].get(); - break; - case PhysicalOperatorType::NESTED_LOOP_JOIN: - case PhysicalOperatorType::BLOCKWISE_NL_JOIN: - case PhysicalOperatorType::HASH_JOIN: - case PhysicalOperatorType::PIECEWISE_MERGE_JOIN: - case PhysicalOperatorType::CROSS_PRODUCT: - // regular join, create a pipeline with RHS source that sinks into this pipeline - pipeline_child = op->children[1].get(); - // on the LHS (probe child), the operator becomes a regular operator - current->operators.push_back(op); - if (op->IsSource()) { - // FULL or RIGHT outer join - // schedule a scan of the node as a child pipeline - // this scan has to be performed AFTER all the probing has happened - if (recursive_cte) { - throw NotImplementedException("FULL and RIGHT outer joins are not supported in recursive CTEs yet"); - } - AddChildPipeline(current); - } - BuildPipelines(op->children[0].get(), current); - break; - case PhysicalOperatorType::DELIM_JOIN: { - // duplicate eliminated join - // for delim joins, recurse into the actual join - pipeline_child = op->children[0].get(); - break; - } - case PhysicalOperatorType::RECURSIVE_CTE: { - auto &cte_node = (PhysicalRecursiveCTE &)*op; +private: + JoinRelationTreeNode root; +}; - // recursive CTE - current->source = op; - // the LHS of the recursive CTE is our initial state - // we build this pipeline as normal - pipeline_child = op->children[0].get(); - // for the RHS, we gather all pipelines that depend on the recursive cte - // these pipelines need to be rerun - if (recursive_cte) { - throw InternalException("Recursive CTE detected WITHIN a recursive CTE node"); - } - recursive_cte = op; +} // namespace duckdb - auto recursive_pipeline = make_shared(*this); - recursive_pipeline->sink = op; - op->sink_state.reset(); - BuildPipelines(op->children[1].get(), recursive_pipeline.get()); - cte_node.pipelines.push_back(move(recursive_pipeline)); - recursive_cte = nullptr; - break; - } - default: - throw InternalException("Unimplemented sink type!"); - } - // the current is dependent on this pipeline to complete - auto pipeline = make_shared(*this); - pipeline->sink = op; - current->AddDependency(pipeline); - D_ASSERT(pipeline_child); - // recurse into the pipeline child - BuildPipelines(pipeline_child, pipeline.get()); - if (op->type == PhysicalOperatorType::DELIM_JOIN) { - // for delim joins, recurse into the actual join - // any pipelines in there depend on the main pipeline - auto &delim_join = (PhysicalDelimJoin &)*op; - // any scan of the duplicate eliminated data on the RHS depends on this pipeline - // we add an entry to the mapping of (PhysicalOperator*) -> (Pipeline*) - for (auto &delim_scan : delim_join.delim_scans) { - delim_join_dependencies[delim_scan] = pipeline.get(); - } - BuildPipelines(delim_join.join.get(), current); - } - if (!recursive_cte) { - // regular pipeline: schedule it - pipelines.push_back(move(pipeline)); - } else { - // CTE pipeline! add it to the CTE pipelines - D_ASSERT(recursive_cte); - auto &cte = (PhysicalRecursiveCTE &)*recursive_cte; - cte.pipelines.push_back(move(pipeline)); - } - } else { - // operator is not a sink! recurse in children - // first check if there is any additional action we need to do depending on the type - switch (op->type) { - case PhysicalOperatorType::DELIM_SCAN: { - D_ASSERT(op->children.empty()); - auto entry = delim_join_dependencies.find(op); - D_ASSERT(entry != delim_join_dependencies.end()); - // this chunk scan introduces a dependency to the current pipeline - // namely a dependency on the duplicate elimination pipeline to finish - auto delim_dependency = entry->second->shared_from_this(); - D_ASSERT(delim_dependency->sink->type == PhysicalOperatorType::DELIM_JOIN); - auto &delim_join = (PhysicalDelimJoin &)*delim_dependency->sink; - current->AddDependency(delim_dependency); - current->source = (PhysicalOperator *)delim_join.distinct.get(); - return; - } - case PhysicalOperatorType::EXECUTE: { - // EXECUTE statement: build pipeline on child - auto &execute = (PhysicalExecute &)*op; - BuildPipelines(execute.plan, current); - return; - } - case PhysicalOperatorType::RECURSIVE_CTE_SCAN: { - if (!recursive_cte) { - throw InternalException("Recursive CTE scan found without recursive CTE node"); - } - break; - } - case PhysicalOperatorType::INDEX_JOIN: { - // index join: we only continue into the LHS - // the right side is probed by the index join - // so we don't need to do anything in the pipeline with this child - current->operators.push_back(op); - BuildPipelines(op->children[0].get(), current); - return; - } - case PhysicalOperatorType::UNION: { - if (recursive_cte) { - throw NotImplementedException("UNIONS are not supported in recursive CTEs yet"); - } - auto union_pipeline = make_shared(*this); - auto pipeline_ptr = union_pipeline.get(); - // set up dependencies for any child pipelines to this union pipeline - auto child_entry = child_pipelines.find(current); - if (child_entry != child_pipelines.end()) { - for (auto ¤t_child : child_entry->second) { - D_ASSERT(child_dependencies.find(current_child.get()) != child_dependencies.end()); - child_dependencies[current_child.get()].push_back(pipeline_ptr); - } - } - // for the current pipeline, continue building on the LHS - union_pipeline->operators = current->operators; - BuildPipelines(op->children[0].get(), current); - // insert the union pipeline as a union pipeline of the current node - union_pipelines[current].push_back(move(union_pipeline)); - // for the union pipeline, build on the RHS - pipeline_ptr->sink = current->sink; - BuildPipelines(op->children[1].get(), pipeline_ptr); - return; - } - default: - break; - } - if (op->children.empty()) { - // source - current->source = op; - } else { - if (op->children.size() != 1) { - throw InternalException("Operator not supported yet"); - } - current->operators.push_back(op); - BuildPipelines(op->children[0].get(), current); - } - } -} +#include -vector Executor::GetTypes() { - D_ASSERT(physical_plan); - return physical_plan->GetTypes(); -} +namespace duckdb { -void Executor::PushError(ExceptionType type, const string &exception) { - lock_guard elock(executor_lock); - // interrupt execution of any other pipelines that belong to this executor - context.interrupted = true; - // push the exception onto the stack - exceptions.emplace_back(type, exception); -} +using JoinRelationTreeNode = JoinRelationSetManager::JoinRelationTreeNode; -bool Executor::HasError() { - lock_guard elock(executor_lock); - return !exceptions.empty(); +// 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 -void Executor::ThrowException() { - lock_guard elock(executor_lock); - ThrowExceptionInternal(); +//! 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; } -void Executor::ThrowExceptionInternal() { // LCOV_EXCL_START - D_ASSERT(!exceptions.empty()); - auto &entry = exceptions[0]; - switch (entry.first) { - case ExceptionType::TRANSACTION: - throw TransactionException(entry.second); - case ExceptionType::CATALOG: - throw CatalogException(entry.second); - case ExceptionType::PARSER: - throw ParserException(entry.second); - case ExceptionType::BINDER: - throw BinderException(entry.second); - case ExceptionType::INTERRUPT: - throw InterruptException(); - case ExceptionType::FATAL: - throw FatalException(entry.second); - case ExceptionType::INTERNAL: - throw InternalException(entry.second); - case ExceptionType::IO: - throw IOException(entry.second); - case ExceptionType::CONSTRAINT: - throw ConstraintException(entry.second); - case ExceptionType::CONVERSION: - throw ConversionException(entry.second); - default: - throw Exception(entry.second); +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(); } -} // LCOV_EXCL_STOP - -void Executor::Flush(ThreadContext &tcontext) { - lock_guard elock(executor_lock); - context.profiler->Flush(tcontext.profiler); + // 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(); } -bool Executor::GetPipelinesProgress(int ¤t_progress) { // LCOV_EXCL_START - lock_guard elock(executor_lock); +//! 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); +} - if (!pipelines.empty()) { - return pipelines.back()->GetProgress(current_progress); - } else { - current_progress = -1; - return true; +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; } -} // LCOV_EXCL_STOP - -unique_ptr Executor::FetchChunk() { - D_ASSERT(physical_plan); + std::sort(relations.get(), relations.get() + count); + return GetJoinRelation(move(relations), count); +} - auto chunk = make_unique(); - root_executor->InitializeChunk(*chunk); +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) { - root_executor->ExecutePull(*chunk); - if (chunk->size() == 0) { - root_executor->PullFinalize(); - if (NextExecutor()) { - continue; + if (i == left->count) { + // exhausted left relation, add remaining of right relation + for (; j < right->count; j++) { + relations[count++] = right->relations[j]; } break; - } else { + } 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 chunk; + return GetJoinRelation(move(relations), count); } -} // namespace duckdb - - +// 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 +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/join_order/query_graph.hpp +// +// +//===----------------------------------------------------------------------===// -ExecutorTask::ExecutorTask(Executor &executor_p) : executor(executor_p) { -} -ExecutorTask::ExecutorTask(ClientContext &context) : ExecutorTask(Executor::Get(context)) { -} -ExecutorTask::~ExecutorTask() { -} -void ExecutorTask::Execute() { - try { - ExecuteTask(); - } catch (Exception &ex) { - executor.PushError(ex.type, ex.what()); - } catch (std::exception &ex) { - executor.PushError(ExceptionType::UNKNOWN_TYPE, ex.what()); - } catch (...) { // LCOV_EXCL_START - executor.PushError(ExceptionType::UNKNOWN_TYPE, "Unknown exception in Finalize!"); - } // LCOV_EXCL_STOP -} -} // namespace duckdb +#include +namespace duckdb { +class Expression; +class LogicalOperator; +struct FilterInfo { + idx_t filter_index; + JoinRelationSet *left_set = nullptr; + JoinRelationSet *right_set = nullptr; + JoinRelationSet *set = nullptr; +}; +struct FilterNode { + vector filters; + unordered_map> children; +}; +struct NeighborInfo { + JoinRelationSet *neighbor; + vector filters; +}; +//! The QueryGraph contains edges between relations and allows edges to be created/queried +class QueryGraph { +public: + //! Contains a node with info about neighboring relations and child edge infos + struct QueryEdge { + vector> neighbors; + unordered_map> children; + }; +public: + string ToString() const; + void Print(); + //! Create an edge in the edge_set + void CreateEdge(JoinRelationSet *left, JoinRelationSet *right, FilterInfo *info); + //! Returns a connection if there is an edge that connects these two sets, or nullptr otherwise + NeighborInfo *GetConnection(JoinRelationSet *node, JoinRelationSet *other); + //! Enumerate the neighbors of a specific node that do not belong to any of the exclusion_set. Note that if a + //! neighbor has multiple nodes, this function will return the lowest entry in that set. + vector GetNeighbors(JoinRelationSet *node, unordered_set &exclusion_set); + //! Enumerate all neighbors of a given JoinRelationSet node + void EnumerateNeighbors(JoinRelationSet *node, const std::function &callback); +private: + //! Get the QueryEdge of a specific node + QueryEdge *GetQueryEdge(JoinRelationSet *left); + QueryEdge root; +}; +} // namespace duckdb @@ -116313,549 +120692,1064 @@ void ExecutorTask::Execute() { namespace duckdb { -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)) { - } - - Pipeline &pipeline; - shared_ptr event; - -public: - void ExecuteTask() override { - PipelineExecutor executor(pipeline.GetClientContext(), pipeline); - executor.Execute(); - event->FinishTask(); - } -}; - -Pipeline::Pipeline(Executor &executor_p) : executor(executor_p), ready(false), source(nullptr), sink(nullptr) { -} - -ClientContext &Pipeline::GetClientContext() { - return executor.context; -} +using QueryEdge = QueryGraph::QueryEdge; // LCOV_EXCL_START -bool Pipeline::GetProgressInternal(ClientContext &context, PhysicalOperator *op, int ¤t_percentage) { - current_percentage = -1; - switch (op->type) { - case PhysicalOperatorType::TABLE_SCAN: { - auto &get = (PhysicalTableScan &)*op; - if (get.function.table_scan_progress) { - current_percentage = get.function.table_scan_progress(context, get.bind_data.get()); - return true; - } - //! If the table_scan_progress is not implemented it means we don't support this function yet in the progress - //! bar - return false; +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 ? ", " : ""); } - default: - return false; + 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; } -// LCOV_EXCL_STOP -bool Pipeline::GetProgress(int ¤t_percentage) { - auto &client = executor.context; - return GetProgressInternal(client, source, current_percentage); +string QueryGraph::ToString() const { + return QueryEdgeToString(&root, {}); } -void Pipeline::ScheduleSequentialTask(shared_ptr &event) { - vector> tasks; - tasks.push_back(make_unique(*this, event)); - event->SetTasks(move(tasks)); +void QueryGraph::Print() { + Printer::Print(ToString()); } +// LCOV_EXCL_STOP -bool Pipeline::ScheduleParallel(shared_ptr &event) { - if (!sink->ParallelSink()) { - return false; - } - if (!source->ParallelSource()) { - return false; - } - for (auto &op : operators) { - if (!op->ParallelOperator()) { - return false; +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(); } - idx_t max_threads = source_state->MaxThreads(); - return LaunchScanTasks(event, max_threads); -} - -void Pipeline::Schedule(shared_ptr &event) { - D_ASSERT(ready); - D_ASSERT(sink); - if (!ScheduleParallel(event)) { - // could not parallelize this pipeline: push a sequential task instead - ScheduleSequentialTask(event); - } + return info; } -bool Pipeline::LaunchScanTasks(shared_ptr &event, idx_t max_threads) { - // split the scan up into parts and schedule the parts - auto &scheduler = TaskScheduler::GetScheduler(executor.context); - idx_t active_threads = scheduler.NumberOfThreads(); - if (max_threads > active_threads) { - max_threads = active_threads; - } - if (max_threads <= 1) { - // too small to parallelize - return false; +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; + } } - - // launch a task for every thread - vector> tasks; - for (idx_t i = 0; i < max_threads; i++) { - tasks.push_back(make_unique(*this, event)); + // neighbor does not exist, create it + auto n = make_unique(); + if (filter_info) { + n->filters.push_back(filter_info); } - event->SetTasks(move(tasks)); - return true; + n->neighbor = right; + info->neighbors.push_back(move(n)); } -void Pipeline::Reset() { - if (sink && !sink->sink_state) { - sink->sink_state = sink->GetGlobalSinkState(GetClientContext()); +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; + } + } + } } - ResetSource(); } -void Pipeline::ResetSource() { - source_state = source->GetGlobalSourceState(GetClientContext()); +//! 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(); } -void Pipeline::Ready() { - if (ready) { - return; - } - ready = true; - std::reverse(operators.begin(), operators.end()); - Reset(); +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; } -void Pipeline::Finalize(Event &event) { - D_ASSERT(ready); - try { - auto sink_state = sink->Finalize(*this, event, executor.context, *sink->sink_state); - sink->sink_state->state = sink_state; - } catch (Exception &ex) { // LCOV_EXCL_START - executor.PushError(ex.type, ex.what()); - } catch (std::exception &ex) { - executor.PushError(ExceptionType::UNKNOWN_TYPE, ex.what()); - } catch (...) { - executor.PushError(ExceptionType::UNKNOWN_TYPE, "Unknown exception in Finalize!"); - } // LCOV_EXCL_STOP +NeighborInfo *QueryGraph::GetConnection(JoinRelationSet *node, JoinRelationSet *other) { + NeighborInfo *connection = nullptr; + EnumerateNeighbors(node, [&](NeighborInfo *info) -> bool { + if (JoinRelationSet::IsSubset(other, info->neighbor)) { + connection = info; + return true; + } + return false; + }); + return connection; } -void Pipeline::AddDependency(shared_ptr &pipeline) { - D_ASSERT(pipeline); - dependencies.push_back(weak_ptr(pipeline)); - pipeline->parents.push_back(weak_ptr(shared_from_this())); -} +} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/join_order_optimizer.hpp +// +// +//===----------------------------------------------------------------------===// + + + -string Pipeline::ToString() const { - TreeRenderer renderer; - return renderer.ToString(*this); -} -void Pipeline::Print() const { - Printer::Print(ToString()); -} -vector Pipeline::GetOperators() const { - vector result; - D_ASSERT(source); - result.push_back(source); - result.insert(result.end(), operators.begin(), operators.end()); - if (sink) { - result.push_back(sink); - } - return result; -} -} // namespace duckdb + +#include + namespace duckdb { -PipelineCompleteEvent::PipelineCompleteEvent(Executor &executor, bool complete_pipeline_p) - : Event(executor), complete_pipeline(complete_pipeline_p) { -} +class JoinOrderOptimizer { +public: + //! Represents a node in the join plan + struct JoinNode { + JoinRelationSet *set; + NeighborInfo *info; + idx_t cardinality; + idx_t cost; + JoinNode *left; + JoinNode *right; -void PipelineCompleteEvent::Schedule() { -} + //! Create a leaf node in the join tree + JoinNode(JoinRelationSet *set, idx_t cardinality) + : set(set), info(nullptr), cardinality(cardinality), cost(cardinality), left(nullptr), right(nullptr) { + } + //! Create an intermediate node in the join tree + JoinNode(JoinRelationSet *set, NeighborInfo *info, JoinNode *left, JoinNode *right, idx_t cardinality, + idx_t cost) + : set(set), info(info), cardinality(cardinality), cost(cost), left(left), right(right) { + } + }; -void PipelineCompleteEvent::FinalizeFinish() { - if (complete_pipeline) { - executor.CompletePipeline(); +public: + explicit JoinOrderOptimizer(ClientContext &context) : context(context) { } -} + + //! Perform join reordering inside a plan + unique_ptr Optimize(unique_ptr plan); + +private: + ClientContext &context; + //! The total amount of join pairs that have been considered + idx_t pairs = 0; + //! Set of all relations considered in the join optimizer + vector> relations; + //! A mapping of base table index -> index into relations array (relation number) + unordered_map relation_mapping; + //! A structure holding all the created JoinRelationSet objects + JoinRelationSetManager set_manager; + //! The set of edges used in the join optimizer + QueryGraph query_graph; + //! The optimal join plan found for the specific JoinRelationSet* + unordered_map> plans; + //! The set of filters extracted from the query graph + vector> filters; + //! 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} + expression_map_t> equivalence_sets; + + //! Extract the bindings referred to by an Expression + bool ExtractBindings(Expression &expression, unordered_set &bindings); + //! Traverse the query tree to find (1) base relations, (2) existing join conditions and (3) filters that can be + //! rewritten into joins. Returns true if there are joins in the tree that can be reordered, false otherwise. + bool ExtractJoinRelations(LogicalOperator &input_op, vector &filter_operators, + LogicalOperator *parent = nullptr); + //! Emit a pair as a potential join candidate. Returns the best plan found for the (left, right) connection (either + //! the newly created plan, or an existing plan) + JoinNode *EmitPair(JoinRelationSet *left, JoinRelationSet *right, NeighborInfo *info); + //! Tries to emit a potential join candidate pair. Returns false if too many pairs have already been emitted, + //! cancelling the dynamic programming step. + bool TryEmitPair(JoinRelationSet *left, JoinRelationSet *right, NeighborInfo *info); + + bool EnumerateCmpRecursive(JoinRelationSet *left, JoinRelationSet *right, unordered_set exclusion_set); + //! Emit a relation set node + bool EmitCSG(JoinRelationSet *node); + //! Enumerate the possible connected subgraphs that can be joined together in the join graph + bool EnumerateCSGRecursive(JoinRelationSet *node, unordered_set &exclusion_set); + //! Rewrite a logical query plan given the join plan + unique_ptr RewritePlan(unique_ptr plan, JoinNode *node); + //! Generate cross product edges inside the side + void GenerateCrossProducts(); + //! Perform the join order solving + void SolveJoinOrder(); + //! Solve the join order exactly using dynamic programming. Returns true if it was completed successfully (i.e. did + //! not time-out) + bool SolveJoinOrderExactly(); + //! Solve the join order approximately using a greedy algorithm + void SolveJoinOrderApproximately(); + + unique_ptr ResolveJoinConditions(unique_ptr op); + std::pair> + GenerateJoins(vector> &extracted_relations, JoinNode *node); +}; } // namespace duckdb -namespace duckdb { -PipelineEvent::PipelineEvent(shared_ptr pipeline_p) - : Event(pipeline_p->executor), pipeline(move(pipeline_p)) { -} -void PipelineEvent::Schedule() { - auto event = shared_from_this(); - pipeline->Schedule(event); - D_ASSERT(total_tasks > 0); -} -void PipelineEvent::FinishEvent() { -} -} // namespace duckdb -namespace duckdb { -PipelineExecutor::PipelineExecutor(ClientContext &context_p, Pipeline &pipeline_p) - : pipeline(pipeline_p), thread(context_p), context(context_p, thread) { - D_ASSERT(pipeline.source_state); - local_source_state = pipeline.source->GetLocalSourceState(context, *pipeline.source_state); - if (pipeline.sink) { - local_sink_state = pipeline.sink->GetLocalSinkState(context); - } - intermediate_chunks.reserve(pipeline.operators.size()); - intermediate_states.reserve(pipeline.operators.size()); - cached_chunks.resize(pipeline.operators.size()); - for (idx_t i = 0; i < pipeline.operators.size(); i++) { - auto prev_operator = i == 0 ? pipeline.source : pipeline.operators[i - 1]; - auto current_operator = pipeline.operators[i]; - auto chunk = make_unique(); - chunk->Initialize(prev_operator->GetTypes()); - intermediate_chunks.push_back(move(chunk)); - intermediate_states.push_back(current_operator->GetOperatorState(context.client)); - if (pipeline.sink && !pipeline.sink->SinkOrderMatters() && current_operator->RequiresCache()) { - auto &cache_types = current_operator->GetTypes(); - bool can_cache = true; - for (auto &type : cache_types) { - if (!CanCacheType(type)) { - can_cache = false; - break; - } - } - if (!can_cache) { - continue; - } - cached_chunks[i] = make_unique(); - cached_chunks[i]->Initialize(current_operator->GetTypes()); - } - if (current_operator->IsSink() && current_operator->sink_state->state == SinkFinalizeType::NO_OUTPUT_POSSIBLE) { - // one of the operators has already figured out no output is possible - // we can skip executing the pipeline - finished_processing = true; - } - } - InitializeChunk(final_chunk); -} -void PipelineExecutor::Execute() { - D_ASSERT(pipeline.sink); - auto &source_chunk = pipeline.operators.empty() ? final_chunk : *intermediate_chunks[0]; - while (true) { - if (finished_processing) { - break; - } - source_chunk.Reset(); - FetchFromSource(source_chunk); - if (source_chunk.size() == 0) { - break; - } - auto result = ExecutePushInternal(source_chunk); - if (result == OperatorResultType::FINISHED) { - finished_processing = true; - break; - } - } - PushFinalize(); -} -OperatorResultType PipelineExecutor::ExecutePush(DataChunk &input) { // LCOV_EXCL_START - return ExecutePushInternal(input); -} // LCOV_EXCL_STOP -OperatorResultType PipelineExecutor::ExecutePushInternal(DataChunk &input, idx_t initial_idx) { - D_ASSERT(pipeline.sink); - if (input.size() == 0) { // LCOV_EXCL_START - return OperatorResultType::NEED_MORE_INPUT; - } // LCOV_EXCL_STOP - while (true) { - OperatorResultType result; - if (!pipeline.operators.empty()) { - final_chunk.Reset(); - result = Execute(input, final_chunk, initial_idx); - if (result == OperatorResultType::FINISHED) { - return OperatorResultType::FINISHED; - } - } else { - result = OperatorResultType::NEED_MORE_INPUT; - } - auto &sink_chunk = pipeline.operators.empty() ? input : final_chunk; - if (sink_chunk.size() > 0) { - StartOperator(pipeline.sink); - D_ASSERT(pipeline.sink); - D_ASSERT(pipeline.sink->sink_state); - auto sink_result = pipeline.sink->Sink(context, *pipeline.sink->sink_state, *local_sink_state, sink_chunk); - EndOperator(pipeline.sink, nullptr); - if (sink_result == SinkResultType::FINISHED) { - return OperatorResultType::FINISHED; - } - } - if (result == OperatorResultType::NEED_MORE_INPUT) { - return OperatorResultType::NEED_MORE_INPUT; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +#include + +namespace duckdb { + +using JoinNode = JoinOrderOptimizer::JoinNode; + +//! Returns true if A and B are disjoint, false otherwise +template +static bool Disjoint(unordered_set &a, unordered_set &b) { + for (auto &entry : a) { + if (b.find(entry) != b.end()) { + return false; } } - return OperatorResultType::FINISHED; + return true; } -void PipelineExecutor::PushFinalize() { - if (finalized) { - throw InternalException("Calling PushFinalize on a pipeline that has been finalized already"); +//! Extract the set of relations referred to inside an expression +bool JoinOrderOptimizer::ExtractBindings(Expression &expression, unordered_set &bindings) { + if (expression.type == ExpressionType::BOUND_COLUMN_REF) { + auto &colref = (BoundColumnRefExpression &)expression; + D_ASSERT(colref.depth == 0); + D_ASSERT(colref.binding.table_index != DConstants::INVALID_INDEX); + // map the base table index to the relation index used by the JoinOrderOptimizer + D_ASSERT(relation_mapping.find(colref.binding.table_index) != relation_mapping.end()); + bindings.insert(relation_mapping[colref.binding.table_index]); } - finalized = true; - // flush all caches - if (!finished_processing) { - D_ASSERT(in_process_operators.empty()); - for (idx_t i = 0; i < cached_chunks.size(); i++) { - if (cached_chunks[i] && cached_chunks[i]->size() > 0) { - ExecutePushInternal(*cached_chunks[i], i + 1); - cached_chunks[i].reset(); - } - } + if (expression.type == ExpressionType::BOUND_REF) { + // bound expression + bindings.clear(); + return false; } - D_ASSERT(local_sink_state); - // run the combine for the sink - pipeline.sink->Combine(context, *pipeline.sink->sink_state, *local_sink_state); + D_ASSERT(expression.type != ExpressionType::SUBQUERY); + bool can_reorder = true; + ExpressionIterator::EnumerateChildren(expression, [&](Expression &expr) { + if (!ExtractBindings(expr, bindings)) { + can_reorder = false; + return; + } + }); + return can_reorder; +} - // flush all query profiler info - for (idx_t i = 0; i < intermediate_states.size(); i++) { - intermediate_states[i]->Finalize(pipeline.operators[i], context); +static unique_ptr PushFilter(unique_ptr node, unique_ptr expr) { + // push an expression into a filter + // first check if we have any filter to push it into + 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); } - pipeline.executor.Flush(thread); - local_sink_state.reset(); + // push the filter into the LogicalFilter + D_ASSERT(node->type == LogicalOperatorType::LOGICAL_FILTER); + auto filter = (LogicalFilter *)node.get(); + filter->expressions.push_back(move(expr)); + return node; } -bool PipelineExecutor::CanCacheType(const LogicalType &type) { - switch (type.id()) { - case LogicalTypeId::LIST: - case LogicalTypeId::MAP: - return false; - case LogicalTypeId::STRUCT: { - auto &entries = StructType::GetChildTypes(type); - for (auto &entry : entries) { - if (!CanCacheType(entry.second)) { - return false; +bool JoinOrderOptimizer::ExtractJoinRelations(LogicalOperator &input_op, vector &filter_operators, + LogicalOperator *parent) { + LogicalOperator *op = &input_op; + while (op->children.size() == 1 && (op->type != LogicalOperatorType::LOGICAL_PROJECTION && + op->type != LogicalOperatorType::LOGICAL_EXPRESSION_GET)) { + if (op->type == LogicalOperatorType::LOGICAL_FILTER) { + // extract join conditions from filter + filter_operators.push_back(op); + } + if (op->type == LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY || + 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])); + return false; + } + op = op->children[0].get(); + } + bool non_reorderable_operation = false; + if (op->type == LogicalOperatorType::LOGICAL_UNION || op->type == LogicalOperatorType::LOGICAL_EXCEPT || + op->type == LogicalOperatorType::LOGICAL_INTERSECT || op->type == LogicalOperatorType::LOGICAL_DELIM_JOIN || + op->type == LogicalOperatorType::LOGICAL_ANY_JOIN) { + // set operation, optimize separately in children + non_reorderable_operation = true; + } + + if (op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN) { + auto &join = (LogicalComparisonJoin &)*op; + if (join.join_type == JoinType::INNER) { + // extract join conditions from inner join + filter_operators.push_back(op); + } else { + // non-inner join, not reorderable yet + non_reorderable_operation = true; + if (join.join_type == JoinType::LEFT && join.right_projection_map.empty()) { + // for left joins; if the RHS cardinality is significantly larger than the LHS (2x) + // we convert to doing a RIGHT OUTER JOIN + // FIXME: for now we don't swap if the right_projection_map is not empty + // this can be fixed once we implement the left_projection_map properly... + auto lhs_cardinality = join.children[0]->EstimateCardinality(context); + auto rhs_cardinality = join.children[1]->EstimateCardinality(context); + if (rhs_cardinality > lhs_cardinality * 2) { + join.join_type = JoinType::RIGHT; + std::swap(join.children[0], join.children[1]); + for (auto &cond : join.conditions) { + std::swap(cond.left, cond.right); + cond.comparison = FlipComparisionExpression(cond.comparison); + } + } } } + } + if (non_reorderable_operation) { + // we encountered a non-reordable operation (setop or non-inner join) + // we do not reorder non-inner joins yet, however we do want to expand the potential join graph around them + // non-inner joins are also tricky because we can't freely make conditions through them + // e.g. suppose we have (left LEFT OUTER JOIN right WHERE right IS NOT NULL), the join can generate + // new NULL values in the right side, so pushing this condition through the join leads to incorrect results + // for this reason, we just start a new JoinOptimizer pass in each of the children of the join + for (auto &child : op->children) { + JoinOrderOptimizer optimizer(context); + child = optimizer.Optimize(move(child)); + } + // after this we want to treat this node as one "end node" (like e.g. a base relation) + // however the join refers to multiple base relations + // enumerate all base relations obtained from this join and add them to the relation mapping + // also, we have to resolve the join conditions for the joins here + // get the left and right bindings + unordered_set bindings; + LogicalJoin::GetTableReferences(*op, bindings); + // now create the relation that refers to all these bindings + auto relation = make_unique(&input_op, parent); + for (idx_t it : bindings) { + relation_mapping[it] = relations.size(); + } + relations.push_back(move(relation)); return true; } - default: + if (op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN || + op->type == 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) { + // base table scan, add to set of relations + auto get = (LogicalGet *)op; + auto relation = make_unique(&input_op, parent); + relation_mapping[get->table_index] = relations.size(); + relations.push_back(move(relation)); + return true; + } else if (op->type == LogicalOperatorType::LOGICAL_EXPRESSION_GET) { + // base table scan, add to set of relations + auto get = (LogicalExpressionGet *)op; + auto relation = make_unique(&input_op, parent); + relation_mapping[get->table_index] = relations.size(); + relations.push_back(move(relation)); + return true; + } else if (op->type == 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)); + return true; + } else if (op->type == 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])); + // 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)); return true; } + return false; } -void PipelineExecutor::CacheChunk(DataChunk ¤t_chunk, idx_t operator_idx) { -#if STANDARD_VECTOR_SIZE >= 128 - if (cached_chunks[operator_idx]) { - if (current_chunk.size() < CACHE_THRESHOLD) { - // we have filtered out a significant amount of tuples - // add this chunk to the cache and continue - auto &chunk_cache = *cached_chunks[operator_idx]; - chunk_cache.Append(current_chunk); - if (chunk_cache.size() >= (STANDARD_VECTOR_SIZE - CACHE_THRESHOLD)) { - // chunk cache full: return it - current_chunk.Move(chunk_cache); - chunk_cache.Initialize(pipeline.operators[operator_idx]->GetTypes()); - } else { - // chunk cache not full: probe again - current_chunk.Reset(); +//! Update the exclusion set with all entries in the subgraph +static void UpdateExclusionSet(JoinRelationSet *node, unordered_set &exclusion_set) { + for (idx_t i = 0; i < node->count; i++) { + exclusion_set.insert(node->relations[i]); + } +} + +//! Create a new JoinTree node by joining together two previous JoinTree nodes +static unique_ptr CreateJoinTree(JoinRelationSet *set, NeighborInfo *info, JoinNode *left, JoinNode *right) { + // for the hash join we want the right side (build side) to have the smallest cardinality + // also just a heuristic but for now... + // FIXME: we should probably actually benchmark that as well + // FIXME: should consider different join algorithms, should we pick a join algorithm here as well? (probably) + if (left->cardinality < right->cardinality) { + return CreateJoinTree(set, info, right, left); + } + // the expected cardinality is the max of the child cardinalities + // FIXME: we should obviously use better cardinality estimation here + // but for now we just assume foreign key joins only + idx_t expected_cardinality; + if (info->filters.empty()) { + // cross product + expected_cardinality = left->cardinality * right->cardinality; + } else { + // normal join, expect foreign key join + expected_cardinality = MaxValue(left->cardinality, right->cardinality); + } + // cost is expected_cardinality plus the cost of the previous plans + idx_t cost = expected_cardinality; + return make_unique(set, info, left, right, expected_cardinality, cost); +} + +JoinNode *JoinOrderOptimizer::EmitPair(JoinRelationSet *left, JoinRelationSet *right, NeighborInfo *info) { + // get the left and right join plans + auto &left_plan = plans[left]; + auto &right_plan = plans[right]; + auto new_set = set_manager.Union(left, right); + // create the join tree based on combining the two plans + auto new_plan = CreateJoinTree(new_set, info, left_plan.get(), right_plan.get()); + // check if this plan is the optimal plan we found for this set of relations + auto entry = plans.find(new_set); + if (entry == plans.end() || new_plan->cost < entry->second->cost) { + // the plan is the optimal plan, move it into the dynamic programming tree + auto result = new_plan.get(); + plans[new_set] = move(new_plan); + return result; + } + return entry->second.get(); +} + +bool JoinOrderOptimizer::TryEmitPair(JoinRelationSet *left, JoinRelationSet *right, NeighborInfo *info) { + pairs++; + if (pairs >= 2000) { + // when the amount of pairs gets too large we exit the dynamic programming and resort to a greedy algorithm + // FIXME: simple heuristic currently + // at 10K pairs stop searching exactly and switch to heuristic + return false; + } + EmitPair(left, right, info); + return true; +} + +bool JoinOrderOptimizer::EmitCSG(JoinRelationSet *node) { + // create the exclusion set as everything inside the subgraph AND anything with members BELOW it + unordered_set exclusion_set; + for (idx_t i = 0; i < node->relations[0]; i++) { + exclusion_set.insert(i); + } + UpdateExclusionSet(node, exclusion_set); + // find the neighbors given this exclusion set + auto neighbors = query_graph.GetNeighbors(node, exclusion_set); + if (neighbors.empty()) { + return true; + } + // we iterate over the neighbors ordered by their first node + sort(neighbors.begin(), neighbors.end()); + for (auto neighbor : neighbors) { + // since the GetNeighbors only returns the smallest element in a list, the entry might not be connected to + // (only!) this neighbor, hence we have to do a connectedness check before we can emit it + auto neighbor_relation = set_manager.GetJoinRelation(neighbor); + auto connection = query_graph.GetConnection(node, neighbor_relation); + if (connection) { + if (!TryEmitPair(node, neighbor_relation, connection)) { + return false; } } + if (!EnumerateCmpRecursive(node, neighbor_relation, exclusion_set)) { + return false; + } } -#endif + return true; } -void PipelineExecutor::ExecutePull(DataChunk &result) { - if (finished_processing) { - return; +bool JoinOrderOptimizer::EnumerateCmpRecursive(JoinRelationSet *left, JoinRelationSet *right, + unordered_set exclusion_set) { + // get the neighbors of the second relation under the exclusion set + auto neighbors = query_graph.GetNeighbors(right, exclusion_set); + if (neighbors.empty()) { + return true; } - auto &executor = pipeline.executor; - try { - D_ASSERT(!pipeline.sink); - auto &source_chunk = pipeline.operators.empty() ? result : *intermediate_chunks[0]; - while (result.size() == 0) { - if (in_process_operators.empty()) { - source_chunk.Reset(); - FetchFromSource(source_chunk); - if (source_chunk.size() == 0) { - break; + vector union_sets; + union_sets.resize(neighbors.size()); + for (idx_t i = 0; i < neighbors.size(); i++) { + auto neighbor = set_manager.GetJoinRelation(neighbors[i]); + // emit the combinations of this node and its neighbors + auto combined_set = set_manager.Union(right, neighbor); + if (plans.find(combined_set) != plans.end()) { + auto connection = query_graph.GetConnection(left, combined_set); + if (connection) { + if (!TryEmitPair(left, combined_set, connection)) { + return false; } } - if (!pipeline.operators.empty()) { - Execute(source_chunk, result); - } - } - } catch (std::exception &ex) { // LCOV_EXCL_START - if (executor.HasError()) { - executor.ThrowException(); } - throw; - } catch (...) { - if (executor.HasError()) { - executor.ThrowException(); + union_sets[i] = combined_set; + } + // recursively enumerate the sets + for (idx_t i = 0; i < neighbors.size(); i++) { + // updated the set of excluded entries with this neighbor + unordered_set new_exclusion_set = exclusion_set; + new_exclusion_set.insert(neighbors[i]); + if (!EnumerateCmpRecursive(left, union_sets[i], new_exclusion_set)) { + return false; } - throw; - } // LCOV_EXCL_STOP + } + return true; } -void PipelineExecutor::PullFinalize() { - if (finalized) { - throw InternalException("Calling PullFinalize on a pipeline that has been finalized already"); +bool JoinOrderOptimizer::EnumerateCSGRecursive(JoinRelationSet *node, unordered_set &exclusion_set) { + // find neighbors of S under the exlusion set + auto neighbors = query_graph.GetNeighbors(node, exclusion_set); + if (neighbors.empty()) { + return true; } - finalized = true; - pipeline.executor.Flush(thread); + // now first emit the connected subgraphs of the neighbors + vector union_sets; + union_sets.resize(neighbors.size()); + for (idx_t i = 0; i < neighbors.size(); i++) { + auto neighbor = set_manager.GetJoinRelation(neighbors[i]); + // emit the combinations of this node and its neighbors + auto new_set = set_manager.Union(node, neighbor); + if (plans.find(new_set) != plans.end()) { + if (!EmitCSG(new_set)) { + return false; + } + } + union_sets[i] = new_set; + } + // recursively enumerate the sets + for (idx_t i = 0; i < neighbors.size(); i++) { + // updated the set of excluded entries with this neighbor + unordered_set new_exclusion_set = exclusion_set; + new_exclusion_set.insert(neighbors[i]); + if (!EnumerateCSGRecursive(union_sets[i], new_exclusion_set)) { + return false; + } + } + return true; } -void PipelineExecutor::GoToSource(idx_t ¤t_idx, idx_t initial_idx) { - // we go back to the first operator (the source) - current_idx = initial_idx; - if (!in_process_operators.empty()) { - // ... UNLESS there is an in process operator - // if there is an in-process operator, we start executing at the latest one - // for example, if we have a join operator that has tuples left, we first need to emit those tuples - current_idx = in_process_operators.top(); - in_process_operators.pop(); +bool JoinOrderOptimizer::SolveJoinOrderExactly() { + // now we perform the actual dynamic programming to compute the final result + // we enumerate over all the possible pairs in the neighborhood + for (idx_t i = relations.size(); i > 0; i--) { + // for every node in the set, we consider it as the start node once + auto start_node = set_manager.GetJoinRelation(i - 1); + // emit the start node + if (!EmitCSG(start_node)) { + return false; + } + // initialize the set of exclusion_set as all the nodes with a number below this + unordered_set exclusion_set; + for (idx_t j = 0; j < i - 1; j++) { + exclusion_set.insert(j); + } + // then we recursively search for neighbors that do not belong to the banned entries + if (!EnumerateCSGRecursive(start_node, exclusion_set)) { + return false; + } } - D_ASSERT(current_idx >= initial_idx); + return true; } -OperatorResultType PipelineExecutor::Execute(DataChunk &input, DataChunk &result, idx_t initial_idx) { - if (input.size() == 0) { // LCOV_EXCL_START - return OperatorResultType::NEED_MORE_INPUT; - } // LCOV_EXCL_STOP - D_ASSERT(!pipeline.operators.empty()); - - idx_t current_idx; - GoToSource(current_idx, initial_idx); - if (current_idx == initial_idx) { - current_idx++; - } - if (current_idx > pipeline.operators.size()) { - result.Reference(input); - return OperatorResultType::NEED_MORE_INPUT; +void JoinOrderOptimizer::SolveJoinOrderApproximately() { + // at this point, we exited the dynamic programming but did not compute the final join order because it took too + // long instead, we use a greedy heuristic to obtain a join ordering now we use Greedy Operator Ordering to + // construct the result tree first we start out with all the base relations (the to-be-joined relations) + vector join_relations; // T in the paper + for (idx_t i = 0; i < relations.size(); i++) { + join_relations.push_back(set_manager.GetJoinRelation(i)); } - while (true) { - if (context.client.interrupted) { - throw InterruptException(); - } - // now figure out where to put the chunk - // if current_idx is the last possible index (>= operators.size()) we write to the result - // otherwise we write to an intermediate chunk - auto current_intermediate = current_idx; - auto ¤t_chunk = - current_intermediate >= intermediate_chunks.size() ? result : *intermediate_chunks[current_intermediate]; - current_chunk.Reset(); - if (current_idx == initial_idx) { - // we went back to the source: we need more input - return OperatorResultType::NEED_MORE_INPUT; - } else { - auto &prev_chunk = - current_intermediate == initial_idx + 1 ? input : *intermediate_chunks[current_intermediate - 1]; - auto operator_idx = current_idx - 1; - auto current_operator = pipeline.operators[operator_idx]; - - // if current_idx > source_idx, we pass the previous' operators output through the Execute of the current - // operator - StartOperator(current_operator); - auto result = current_operator->Execute(context, prev_chunk, current_chunk, - *intermediate_states[current_intermediate - 1]); - EndOperator(current_operator, ¤t_chunk); - if (result == OperatorResultType::HAVE_MORE_OUTPUT) { - // more data remains in this operator - // push in-process marker - in_process_operators.push(current_idx); - } else if (result == OperatorResultType::FINISHED) { - D_ASSERT(current_chunk.size() == 0); - return OperatorResultType::FINISHED; + while (join_relations.size() > 1) { + // now in every step of the algorithm, we greedily pick the join between the to-be-joined relations that has the + // smallest cost. This is O(r^2) per step, and every step will reduce the total amount of relations to-be-joined + // by 1, so the total cost is O(r^3) in the amount of relations + idx_t best_left = 0, best_right = 0; + JoinNode *best_connection = nullptr; + for (idx_t i = 0; i < join_relations.size(); i++) { + auto left = join_relations[i]; + for (idx_t j = i + 1; j < join_relations.size(); j++) { + auto right = join_relations[j]; + // check if we can connect these two relations + auto connection = query_graph.GetConnection(left, right); + if (connection) { + // we can! check the cost of this connection + auto node = EmitPair(left, right, connection); + if (!best_connection || node->cost < best_connection->cost) { + // best pair found so far + best_connection = node; + best_left = i; + best_right = j; + } + } } - current_chunk.Verify(); - CacheChunk(current_chunk, operator_idx); } - - if (current_chunk.size() == 0) { - // no output from this operator! - if (current_idx == initial_idx) { - // if we got no output from the scan, we are done - break; - } else { - // if we got no output from an intermediate op - // we go back and try to pull data from the source again - GoToSource(current_idx, initial_idx); - continue; + if (!best_connection) { + // could not find a connection, but we were not done with finding a completed plan + // we have to add a cross product; we add it between the two smallest relations + JoinNode *smallest_plans[2] = {nullptr}; + idx_t smallest_index[2]; + for (idx_t i = 0; i < join_relations.size(); i++) { + // get the plan for this relation + auto current_plan = plans[join_relations[i]].get(); + // check if the cardinality is smaller than the smallest two found so far + for (idx_t j = 0; j < 2; j++) { + if (!smallest_plans[j] || smallest_plans[j]->cardinality > current_plan->cardinality) { + smallest_plans[j] = current_plan; + smallest_index[j] = i; + break; + } + } } - } else { - // we got output! continue to the next operator - current_idx++; - if (current_idx > pipeline.operators.size()) { - // if we got output and are at the last operator, we are finished executing for this output chunk - // return the data and push it into the chunk - break; + if (!smallest_plans[0] || !smallest_plans[1]) { + throw InternalException("Internal error in join order optimizer"); + } + D_ASSERT(smallest_plans[0] && smallest_plans[1]); + D_ASSERT(smallest_index[0] != smallest_index[1]); + auto left = smallest_plans[0]->set; + auto right = smallest_plans[1]->set; + // create a cross product edge (i.e. edge with empty filter) between these two sets in the query graph + query_graph.CreateEdge(left, right, nullptr); + // now emit the pair and continue with the algorithm + auto connection = query_graph.GetConnection(left, right); + D_ASSERT(connection); + + best_connection = EmitPair(left, right, connection); + best_left = smallest_index[0]; + best_right = smallest_index[1]; + // the code below assumes best_right > best_left + if (best_left > best_right) { + std::swap(best_left, best_right); } } + // now update the to-be-checked pairs + // remove left and right, and add the combination + + // important to erase the biggest element first + // if we erase the smallest element first the index of the biggest element changes + D_ASSERT(best_right > best_left); + join_relations.erase(join_relations.begin() + best_right); + join_relations.erase(join_relations.begin() + best_left); + join_relations.push_back(best_connection->set); } - return in_process_operators.empty() ? OperatorResultType::NEED_MORE_INPUT : OperatorResultType::HAVE_MORE_OUTPUT; } -void PipelineExecutor::FetchFromSource(DataChunk &result) { - StartOperator(pipeline.source); - pipeline.source->GetData(context, result, *pipeline.source_state, *local_source_state); - EndOperator(pipeline.source, &result); +void JoinOrderOptimizer::SolveJoinOrder() { + // first try to solve the join order exactly + if (!SolveJoinOrderExactly()) { + // otherwise, if that times out we resort to a greedy algorithm + SolveJoinOrderApproximately(); + } } -void PipelineExecutor::InitializeChunk(DataChunk &chunk) { - PhysicalOperator *last_op = pipeline.operators.empty() ? pipeline.source : pipeline.operators.back(); - chunk.Initialize(last_op->GetTypes()); +void JoinOrderOptimizer::GenerateCrossProducts() { + // generate a set of cross products to combine the currently available plans into a full join plan + // we create edges between every relation with a high cost + for (idx_t i = 0; i < relations.size(); i++) { + auto left = set_manager.GetJoinRelation(i); + for (idx_t j = 0; j < relations.size(); j++) { + if (i != j) { + auto right = set_manager.GetJoinRelation(j); + query_graph.CreateEdge(left, right, nullptr); + query_graph.CreateEdge(right, left, nullptr); + } + } + } } -void PipelineExecutor::StartOperator(PhysicalOperator *op) { - if (context.client.interrupted) { - throw InterruptException(); +static unique_ptr ExtractJoinRelation(SingleJoinRelation &rel) { + auto &children = rel.parent->children; + 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]); + children.erase(children.begin() + i); + return result; + } } - context.thread.profiler.StartOperator(op); + throw Exception("Could not find relation in parent node (?)"); } -void PipelineExecutor::EndOperator(PhysicalOperator *op, DataChunk *chunk) { - context.thread.profiler.EndOperator(chunk); +pair> +JoinOrderOptimizer::GenerateJoins(vector> &extracted_relations, JoinNode *node) { + JoinRelationSet *left_node = nullptr, *right_node = nullptr; + JoinRelationSet *result_relation; + unique_ptr result_operator; + if (node->left && node->right) { + // generate the left and right children + auto left = GenerateJoins(extracted_relations, node->left); + auto right = GenerateJoins(extracted_relations, node->right); - if (chunk) { - chunk->Verify(); + if (node->info->filters.empty()) { + // no filters, create a cross product + auto join = make_unique(); + join->children.push_back(move(left.second)); + join->children.push_back(move(right.second)); + result_operator = move(join); + } 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)); + // 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]); + // now create the actual join condition + D_ASSERT((JoinRelationSet::IsSubset(left.first, f->left_set) && + JoinRelationSet::IsSubset(right.first, f->right_set)) || + (JoinRelationSet::IsSubset(left.first, f->right_set) && + JoinRelationSet::IsSubset(right.first, f->left_set))); + JoinCondition cond; + D_ASSERT(condition->GetExpressionClass() == ExpressionClass::BOUND_COMPARISON); + 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); + if (condition->type == ExpressionType::COMPARE_NOT_DISTINCT_FROM) { + cond.comparison = ExpressionType::COMPARE_EQUAL; + cond.null_values_are_equal = true; + } else if (condition->type == ExpressionType::COMPARE_DISTINCT_FROM) { + cond.comparison = condition->type; + cond.null_values_are_equal = true; + } else { + 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)); + } + D_ASSERT(!join->conditions.empty()); + result_operator = move(join); + } + left_node = left.first; + right_node = right.first; + result_relation = set_manager.Union(left_node, right_node); + } else { + // base node, get the entry from the list of extracted relations + 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]]); + } + // 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 + for (auto &filter_info : filter_infos) { + // check if the filter has already been extracted + auto info = filter_info.get(); + if (filters[info->filter_index]) { + // 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]); + // 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)); + continue; + } + // the node below us is a join or cross product and the expression is a comparison + // check if the nodes can be split up into left/right + bool found_subset = false; + bool invert = false; + if (JoinRelationSet::IsSubset(left_node, info->left_set) && + JoinRelationSet::IsSubset(right_node, info->right_set)) { + found_subset = true; + } else if (JoinRelationSet::IsSubset(right_node, info->left_set) && + JoinRelationSet::IsSubset(left_node, info->right_set)) { + invert = true; + found_subset = true; + } + if (!found_subset) { + // could not be split up into left/right + result_operator = PushFilter(move(result_operator), move(filter)); + continue; + } + // create the join condition + JoinCondition cond; + 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.comparison = comparison.type; + if (invert) { + // reverse comparison expression if we reverse the order of the children + cond.comparison = FlipComparisionExpression(comparison.type); + } + // now find the join to push it into + auto node = result_operator.get(); + if (node->type == LogicalOperatorType::LOGICAL_FILTER) { + node = node->children[0].get(); + } + 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)); + if (node == result_operator.get()) { + result_operator = move(comp_join); + } else { + D_ASSERT(result_operator->type == LogicalOperatorType::LOGICAL_FILTER); + result_operator->children[0] = move(comp_join); + } + } else { + D_ASSERT(node->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN); + auto &comp_join = (LogicalComparisonJoin &)*node; + comp_join.conditions.push_back(move(cond)); + } + } + } } + return make_pair(result_relation, move(result_operator)); } -} // namespace duckdb - - - -namespace duckdb { +unique_ptr JoinOrderOptimizer::RewritePlan(unique_ptr plan, JoinNode *node) { + // now we have to rewrite the plan + bool root_is_join = plan->children.size() > 1; -PipelineFinishEvent::PipelineFinishEvent(shared_ptr pipeline_p) - : Event(pipeline_p->executor), pipeline(move(pipeline_p)) { -} + // first we will extract all relations from the main plan + vector> extracted_relations; + for (auto &relation : relations) { + extracted_relations.push_back(ExtractJoinRelation(*relation)); + } + // now we generate the actual joins + auto join_tree = GenerateJoins(extracted_relations, node); + // perform the final pushdown of remaining filters + for (auto &filter : filters) { + // check if the filter has already been extracted + if (filter) { + // if not we need to push it + join_tree.second = PushFilter(move(join_tree.second), move(filter)); + } + } -void PipelineFinishEvent::Schedule() { + // find the first join in the relation to know where to place this node + if (root_is_join) { + // first node is the join, return it immediately + return move(join_tree.second); + } + D_ASSERT(plan->children.size() == 1); + // have to move up through the relations + auto op = plan.get(); + auto parent = plan.get(); + while (op->type != LogicalOperatorType::LOGICAL_CROSS_PRODUCT && + op->type != LogicalOperatorType::LOGICAL_COMPARISON_JOIN) { + D_ASSERT(op->children.size() == 1); + parent = op; + op = op->children[0].get(); + } + // have to replace at this node + parent->children[0] = move(join_tree.second); + return plan; } -void PipelineFinishEvent::FinishEvent() { - pipeline->Finalize(*this); +// the join ordering is pretty much a straight implementation of the paper "Dynamic Programming Strikes Back" by Guido +// Moerkotte and Thomas Neumannn, see that paper for additional info/documentation bonus slides: +// https://db.in.tum.de/teaching/ws1415/queryopt/chapter3.pdf?lang=de +// FIXME: incorporate cardinality estimation into the plans, possibly by pushing samples? +unique_ptr JoinOrderOptimizer::Optimize(unique_ptr plan) { + D_ASSERT(filters.empty() && relations.empty()); // assert that the JoinOrderOptimizer has not been used before + LogicalOperator *op = plan.get(); + // now we optimize the current plan + // we skip past until we find the first projection, we do this because the HAVING clause inserts a Filter AFTER the + // group by and this filter cannot be reordered + // extract a list of all relations that have to be joined together + // and a list of all conditions that is applied to them + vector filter_operators; + if (!ExtractJoinRelations(*op, filter_operators)) { + // do not support reordering this type of plan + return plan; + } + if (relations.size() <= 1) { + // at most one relation, nothing to reorder + return plan; + } + // now that we know we are going to perform join ordering we actually extract the filters, eliminating duplicate + // filters in the process + expression_set_t filter_set; + for (auto &op : filter_operators) { + if (op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN) { + auto &join = (LogicalComparisonJoin &)*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)); + if (filter_set.find(comparison.get()) == filter_set.end()) { + filter_set.insert(comparison.get()); + filters.push_back(move(comparison)); + } + } + join.conditions.clear(); + } else { + for (auto &expression : op->expressions) { + if (filter_set.find(expression.get()) == filter_set.end()) { + filter_set.insert(expression.get()); + filters.push_back(move(expression)); + } + } + op->expressions.clear(); + } + } + // create potential edges from the comparisons + for (idx_t i = 0; i < filters.size(); i++) { + auto &filter = filters[i]; + auto info = make_unique(); + auto filter_info = info.get(); + filter_infos.push_back(move(info)); + // first extract the relation set for the entire filter + unordered_set bindings; + ExtractBindings(*filter, bindings); + filter_info->set = set_manager.GetJoinRelation(bindings); + filter_info->filter_index = i; + // now check if it can be used as a join predicate + if (filter->GetExpressionClass() == ExpressionClass::BOUND_COMPARISON) { + auto comparison = (BoundComparisonExpression *)filter.get(); + // extract the bindings that are required for the left and right side of the comparison + unordered_set left_bindings, right_bindings; + ExtractBindings(*comparison->left, left_bindings); + ExtractBindings(*comparison->right, right_bindings); + if (!left_bindings.empty() && !right_bindings.empty()) { + // both the left and the right side have bindings + // first create the relation sets, if they do not exist + filter_info->left_set = set_manager.GetJoinRelation(left_bindings); + filter_info->right_set = set_manager.GetJoinRelation(right_bindings); + // we can only create a meaningful edge if the sets are not exactly the same + if (filter_info->left_set != filter_info->right_set) { + // check if the sets are disjoint + if (Disjoint(left_bindings, right_bindings)) { + // they are disjoint, we only need to create one set of edges in the join graph + query_graph.CreateEdge(filter_info->left_set, filter_info->right_set, filter_info); + query_graph.CreateEdge(filter_info->right_set, filter_info->left_set, filter_info); + } else { + continue; + } + continue; + } + } + } + } + // now use dynamic programming to figure out the optimal join order + // First we initialize each of the single-node plans with themselves and with their cardinalities these are the leaf + // nodes of the join tree NOTE: we can just use pointers to JoinRelationSet* here because the GetJoinRelation + // function ensures that a unique combination of relations will have a unique JoinRelationSet object. + for (idx_t i = 0; i < relations.size(); i++) { + auto &rel = *relations[i]; + auto node = set_manager.GetJoinRelation(i); + plans[node] = make_unique(node, rel.op->EstimateCardinality(context)); + } + // now we perform the actual dynamic programming to compute the final result + SolveJoinOrder(); + // now the optimal join path should have been found + // get it from the node + unordered_set bindings; + for (idx_t i = 0; i < relations.size(); i++) { + bindings.insert(i); + } + auto total_relation = set_manager.GetJoinRelation(bindings); + auto final_plan = plans.find(total_relation); + if (final_plan == plans.end()) { + // could not find the final plan + // this should only happen in case the sets are actually disjunct + // in this case we need to generate cross product to connect the disjoint sets + GenerateCrossProducts(); + //! solve the join order again + SolveJoinOrder(); + // now we can obtain the final plan! + final_plan = plans.find(total_relation); + D_ASSERT(final_plan != plans.end()); + } + // now perform the actual reordering + return RewritePlan(move(plan), final_plan->second.get()); } } // namespace duckdb @@ -116863,932 +121757,7067 @@ void PipelineFinishEvent::FinishEvent() { +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; +} -#ifndef DUCKDB_NO_THREADS +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; +} -// LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #7 -// See the end of this file for a list +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); +} -// Provides a C++11 implementation of a multi-producer, multi-consumer lock-free queue. -// An overview, including benchmark results, is provided here: -// http://moodycamel.com/blog/2014/a-fast-general-purpose-lock-free-queue-for-c++ -// The full design is also described in excruciating detail at: -// http://moodycamel.com/blog/2014/detailed-design-of-a-lock-free-queue +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); +} -// Simplified BSD license: -// Copyright (c) 2013-2016, Cameron Desrochers. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// - Redistributions in binary form must reproduce the above copyright notice, this list of -// conditions and the following disclaimer in the documentation and/or other materials -// provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -// TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +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; +} -#if defined(__GNUC__) -// Disable -Wconversion warnings (spuriously triggered when Traits::size_t and -// Traits::index_t are set to < 32 bits, causing integer promotion, causing warnings -// upon assigning any computed values) +} // namespace duckdb -#endif -#if defined(__APPLE__) -#include -#endif -#include // Requires C++11. Sorry VS2010. -#include -#include // for max_align_t -#include -#include -#include -#include -#include -#include -#include // for CHAR_BIT -#include -#include // partly for __WINPTHREADS_VERSION if on MinGW-w64 w/ POSIX threading -// Platform-specific definitions of a numeric thread ID type and an invalid value -namespace duckdb_moodycamel { namespace details { - template struct thread_id_converter { - typedef thread_id_t thread_id_numeric_size_t; - typedef thread_id_t thread_id_hash_t; - static thread_id_hash_t prehash(thread_id_t const& x) { return x; } - }; -} } -#if defined(MCDBGQ_USE_RELACY) -namespace duckdb_moodycamel { namespace details { - typedef std::uint32_t thread_id_t; - static const thread_id_t invalid_thread_id = 0xFFFFFFFFU; - static const thread_id_t invalid_thread_id2 = 0xFFFFFFFEU; - static inline thread_id_t thread_id() { return rl::thread_index(); } -} } -#elif defined(_WIN32) || defined(__WINDOWS__) || defined(__WIN32__) -// No sense pulling in windows.h in a header, we'll manually declare the function -// we use and rely on backwards-compatibility for this not to break -extern "C" __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId(void); -namespace duckdb_moodycamel { namespace details { - static_assert(sizeof(unsigned long) == sizeof(std::uint32_t), "Expected size of unsigned long to be 32 bits on Windows"); - typedef std::uint32_t thread_id_t; - static const thread_id_t invalid_thread_id = 0; // See http://blogs.msdn.com/b/oldnewthing/archive/2004/02/23/78395.aspx - static const thread_id_t invalid_thread_id2 = 0xFFFFFFFFU; // Not technically guaranteed to be invalid, but is never used in practice. Note that all Win32 thread IDs are presently multiples of 4. - static inline thread_id_t thread_id() { return static_cast(::GetCurrentThreadId()); } -} } -#elif defined(__arm__) || defined(_M_ARM) || defined(__aarch64__) || (defined(__APPLE__) && TARGET_OS_IPHONE) -namespace duckdb_moodycamel { namespace details { - static_assert(sizeof(std::thread::id) == 4 || sizeof(std::thread::id) == 8, "std::thread::id is expected to be either 4 or 8 bytes"); - - typedef std::thread::id thread_id_t; - static const thread_id_t invalid_thread_id; // Default ctor creates invalid ID - // Note we don't define a invalid_thread_id2 since std::thread::id doesn't have one; it's - // only used if MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED is defined anyway, which it won't - // be. - static inline thread_id_t thread_id() { return std::this_thread::get_id(); } - template struct thread_id_size { }; - template<> struct thread_id_size<4> { typedef std::uint32_t numeric_t; }; - template<> struct thread_id_size<8> { typedef std::uint64_t numeric_t; }; - template<> struct thread_id_converter { - typedef thread_id_size::numeric_t thread_id_numeric_size_t; -#ifndef __APPLE__ - typedef std::size_t thread_id_hash_t; -#else - typedef thread_id_numeric_size_t thread_id_hash_t; -#endif - static thread_id_hash_t prehash(thread_id_t const& x) - { -#ifndef __APPLE__ - return std::hash()(x); -#else - return *reinterpret_cast(&x); -#endif - } - }; -} } -#else -// Use a nice trick from this answer: http://stackoverflow.com/a/8438730/21475 -// In order to get a numeric thread ID in a platform-independent way, we use a thread-local -// static variable's address as a thread identifier :-) -#if defined(__GNUC__) || defined(__INTEL_COMPILER) -#define MOODYCAMEL_THREADLOCAL __thread -#elif defined(_MSC_VER) -#define MOODYCAMEL_THREADLOCAL __declspec(thread) -#else -// Assume C++11 compliant compiler -#define MOODYCAMEL_THREADLOCAL thread_local -#endif -namespace duckdb_moodycamel { namespace details { - typedef std::uintptr_t thread_id_t; - static const thread_id_t invalid_thread_id = 0; // Address can't be nullptr -#ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED - static const thread_id_t invalid_thread_id2 = 1; // Member accesses off a null pointer are also generally invalid. Plus it's not aligned. -#endif - inline thread_id_t thread_id() { static MOODYCAMEL_THREADLOCAL int x; return reinterpret_cast(&x); } -} } -#endif -// Constexpr if -#ifndef MOODYCAMEL_CONSTEXPR_IF -#if (defined(_MSC_VER) && defined(_HAS_CXX17) && _HAS_CXX17) || __cplusplus > 201402L -#define MOODYCAMEL_CONSTEXPR_IF if constexpr -#define MOODYCAMEL_MAYBE_UNUSED [[maybe_unused]] -#else -#define MOODYCAMEL_CONSTEXPR_IF if -#define MOODYCAMEL_MAYBE_UNUSED -#endif -#endif -// Exceptions -#ifndef MOODYCAMEL_EXCEPTIONS_ENABLED -#if (defined(_MSC_VER) && defined(_CPPUNWIND)) || (defined(__GNUC__) && defined(__EXCEPTIONS)) || (!defined(_MSC_VER) && !defined(__GNUC__)) -#define MOODYCAMEL_EXCEPTIONS_ENABLED -#endif -#endif -#ifdef MOODYCAMEL_EXCEPTIONS_ENABLED -#define MOODYCAMEL_TRY try -#define MOODYCAMEL_CATCH(...) catch(__VA_ARGS__) -#define MOODYCAMEL_RETHROW throw -#define MOODYCAMEL_THROW(expr) throw (expr) -#else -#define MOODYCAMEL_TRY MOODYCAMEL_CONSTEXPR_IF (true) -#define MOODYCAMEL_CATCH(...) else MOODYCAMEL_CONSTEXPR_IF (false) -#define MOODYCAMEL_RETHROW -#define MOODYCAMEL_THROW(expr) -#endif -#ifndef MOODYCAMEL_NOEXCEPT -#if !defined(MOODYCAMEL_EXCEPTIONS_ENABLED) -#define MOODYCAMEL_NOEXCEPT -#define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) true -#define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) true -#elif defined(_MSC_VER) && defined(_NOEXCEPT) && _MSC_VER < 1800 -// VS2012's std::is_nothrow_[move_]constructible is broken and returns true when it shouldn't :-( -// We have to assume *all* non-trivial constructors may throw on VS2012! -#define MOODYCAMEL_NOEXCEPT _NOEXCEPT -#define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) (std::is_rvalue_reference::value && std::is_move_constructible::value ? std::is_trivially_move_constructible::value : std::is_trivially_copy_constructible::value) -#define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) ((std::is_rvalue_reference::value && std::is_move_assignable::value ? std::is_trivially_move_assignable::value || std::is_nothrow_move_assignable::value : std::is_trivially_copy_assignable::value || std::is_nothrow_copy_assignable::value) && MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr)) -#elif defined(_MSC_VER) && defined(_NOEXCEPT) && _MSC_VER < 1900 -#define MOODYCAMEL_NOEXCEPT _NOEXCEPT -#define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) (std::is_rvalue_reference::value && std::is_move_constructible::value ? std::is_trivially_move_constructible::value || std::is_nothrow_move_constructible::value : std::is_trivially_copy_constructible::value || std::is_nothrow_copy_constructible::value) -#define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) ((std::is_rvalue_reference::value && std::is_move_assignable::value ? std::is_trivially_move_assignable::value || std::is_nothrow_move_assignable::value : std::is_trivially_copy_assignable::value || std::is_nothrow_copy_assignable::value) && MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr)) -#else -#define MOODYCAMEL_NOEXCEPT noexcept -#define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) noexcept(expr) -#define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) noexcept(expr) -#endif -#endif -#ifndef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED -#ifdef MCDBGQ_USE_RELACY -#define MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED -#else -// VS2013 doesn't support `thread_local`, and MinGW-w64 w/ POSIX threading has a crippling bug: http://sourceforge.net/p/mingw-w64/bugs/445 -// g++ <=4.7 doesn't support thread_local either. -// Finally, iOS/ARM doesn't have support for it either, and g++/ARM allows it to compile but it's unconfirmed to actually work -#if (!defined(_MSC_VER) || _MSC_VER >= 1900) && (!defined(__MINGW32__) && !defined(__MINGW64__) || !defined(__WINPTHREADS_VERSION)) && (!defined(__GNUC__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) && (!defined(__APPLE__) || !TARGET_OS_IPHONE) && !defined(__arm__) && !defined(_M_ARM) && !defined(__aarch64__) -// Assume `thread_local` is fully supported in all other C++11 compilers/platforms -//#define MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED // always disabled for now since several users report having problems with it on -#endif -#endif -#endif -// VS2012 doesn't support deleted functions. -// In this case, we declare the function normally but don't define it. A link error will be generated if the function is called. -#ifndef MOODYCAMEL_DELETE_FUNCTION -#if defined(_MSC_VER) && _MSC_VER < 1800 -#define MOODYCAMEL_DELETE_FUNCTION -#else -#define MOODYCAMEL_DELETE_FUNCTION = delete -#endif -#endif +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/regex_range_filter.hpp +// +// +//===----------------------------------------------------------------------===// -#ifndef MOODYCAMEL_ALIGNAS -// VS2013 doesn't support alignas or alignof -#if defined(_MSC_VER) && _MSC_VER <= 1800 -#define MOODYCAMEL_ALIGNAS(alignment) __declspec(align(alignment)) -#define MOODYCAMEL_ALIGNOF(obj) __alignof(obj) -#else -#define MOODYCAMEL_ALIGNAS(alignment) alignas(alignment) -#define MOODYCAMEL_ALIGNOF(obj) alignof(obj) -#endif -#endif -// Compiler-specific likely/unlikely hints -namespace duckdb_moodycamel { namespace details { -#if defined(__GNUC__) - static inline bool (likely)(bool x) { return __builtin_expect((x), true); } -// static inline bool (unlikely)(bool x) { return __builtin_expect((x), false); } -#else - static inline bool (likely)(bool x) { return x; } -// static inline bool (unlikely)(bool x) { return x; } -#endif -} } +namespace duckdb { -namespace duckdb_moodycamel { -namespace details { - template - struct const_numeric_max { - static_assert(std::is_integral::value, "const_numeric_max can only be used with integers"); - static const T value = std::numeric_limits::is_signed - ? (static_cast(1) << (sizeof(T) * CHAR_BIT - 1)) - static_cast(1) - : static_cast(-1); - }; +class Optimizer; -#if defined(__GLIBCXX__) - typedef ::max_align_t std_max_align_t; // libstdc++ forgot to add it to std:: for a while -#else - typedef std::max_align_t std_max_align_t; // Others (e.g. MSVC) insist it can *only* be accessed via std:: -#endif +class RegexRangeFilter { +public: + RegexRangeFilter() { + } + //! Perform filter pushdown + unique_ptr Rewrite(unique_ptr op); +}; - // Some platforms have incorrectly set max_align_t to a type with <8 bytes alignment even while supporting - // 8-byte aligned scalar values (*cough* 32-bit iOS). Work around this with our own union. See issue #64. - typedef union { - std_max_align_t x; - long long y; - void* z; - } max_align_t; -} +} // namespace duckdb -// Default traits for the ConcurrentQueue. To change some of the -// traits without re-implementing all of them, inherit from this -// struct and shadow the declarations you wish to be different; -// since the traits are used as a template type parameter, the -// shadowed declarations will be used where defined, and the defaults -// otherwise. -struct ConcurrentQueueDefaultTraits -{ - // General-purpose size type. std::size_t is strongly recommended. - typedef std::size_t size_t; - - // The type used for the enqueue and dequeue indices. Must be at least as - // large as size_t. Should be significantly larger than the number of elements - // you expect to hold at once, especially if you have a high turnover rate; - // for example, on 32-bit x86, if you expect to have over a hundred million - // elements or pump several million elements through your queue in a very - // short space of time, using a 32-bit type *may* trigger a race condition. - // A 64-bit int type is recommended in that case, and in practice will - // prevent a race condition no matter the usage of the queue. Note that - // whether the queue is lock-free with a 64-int type depends on the whether - // std::atomic is lock-free, which is platform-specific. - typedef std::size_t index_t; - - // Internally, all elements are enqueued and dequeued from multi-element - // blocks; this is the smallest controllable unit. If you expect few elements - // but many producers, a smaller block size should be favoured. For few producers - // and/or many elements, a larger block size is preferred. A sane default - // is provided. Must be a power of 2. - static const size_t BLOCK_SIZE = 32; - - // For explicit producers (i.e. when using a producer token), the block is - // checked for being empty by iterating through a list of flags, one per element. - // For large block sizes, this is too inefficient, and switching to an atomic - // counter-based approach is faster. The switch is made for block sizes strictly - // larger than this threshold. - static const size_t EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD = 32; - - // How many full blocks can be expected for a single explicit producer? This should - // reflect that number's maximum for optimal performance. Must be a power of 2. - static const size_t EXPLICIT_INITIAL_INDEX_SIZE = 32; - - // How many full blocks can be expected for a single implicit producer? This should - // reflect that number's maximum for optimal performance. Must be a power of 2. - static const size_t IMPLICIT_INITIAL_INDEX_SIZE = 32; - - // The initial size of the hash table mapping thread IDs to implicit producers. - // Note that the hash is resized every time it becomes half full. - // Must be a power of two, and either 0 or at least 1. If 0, implicit production - // (using the enqueue methods without an explicit producer token) is disabled. - static const size_t INITIAL_IMPLICIT_PRODUCER_HASH_SIZE = 32; - - // Controls the number of items that an explicit consumer (i.e. one with a token) - // must consume before it causes all consumers to rotate and move on to the next - // internal queue. - static const std::uint32_t EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE = 256; - - // The maximum number of elements (inclusive) that can be enqueued to a sub-queue. - // Enqueue operations that would cause this limit to be surpassed will fail. Note - // that this limit is enforced at the block level (for performance reasons), i.e. - // it's rounded up to the nearest block size. - static const size_t MAX_SUBQUEUE_SIZE = details::const_numeric_max::value; - - -#ifndef MCDBGQ_USE_RELACY - // Memory allocation can be customized if needed. - // malloc should return nullptr on failure, and handle alignment like std::malloc. -#if defined(malloc) || defined(free) - // Gah, this is 2015, stop defining macros that break standard code already! - // Work around malloc/free being special macros: - static inline void* WORKAROUND_malloc(size_t size) { return malloc(size); } - static inline void WORKAROUND_free(void* ptr) { return free(ptr); } - static inline void* (malloc)(size_t size) { return WORKAROUND_malloc(size); } - static inline void (free)(void* ptr) { return WORKAROUND_free(ptr); } -#else - static inline void* malloc(size_t size) { return std::malloc(size); } - static inline void free(void* ptr) { return std::free(ptr); } -#endif -#else - // Debug versions when running under the Relacy race detector (ignore - // these in user code) - static inline void* malloc(size_t size) { return rl::rl_malloc(size, $); } - static inline void free(void* ptr) { return rl::rl_free(ptr, $); } -#endif -}; +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/remove_unused_columns.hpp +// +// +//===----------------------------------------------------------------------===// -// When producing or consuming many elements, the most efficient way is to: -// 1) Use one of the bulk-operation methods of the queue with a token -// 2) Failing that, use the bulk-operation methods without a token -// 3) Failing that, create a token and use that with the single-item methods -// 4) Failing that, use the single-parameter methods of the queue -// Having said that, don't create tokens willy-nilly -- ideally there should be -// a maximum of one token per thread (of each kind). -struct ProducerToken; -struct ConsumerToken; -template class ConcurrentQueue; -template class BlockingConcurrentQueue; -class ConcurrentQueueTests; -namespace details -{ - struct ConcurrentQueueProducerTypelessBase - { - ConcurrentQueueProducerTypelessBase* next; - std::atomic inactive; - ProducerToken* token; - - ConcurrentQueueProducerTypelessBase() - : next(nullptr), inactive(false), token(nullptr) - { - } - }; - - template struct _hash_32_or_64 { - static inline std::uint32_t hash(std::uint32_t h) - { - // MurmurHash3 finalizer -- see https://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp - // Since the thread ID is already unique, all we really want to do is propagate that - // uniqueness evenly across all the bits, so that we can use a subset of the bits while - // reducing collisions significantly - h ^= h >> 16; - h *= 0x85ebca6b; - h ^= h >> 13; - h *= 0xc2b2ae35; - return h ^ (h >> 16); - } - }; - template<> struct _hash_32_or_64<1> { - static inline std::uint64_t hash(std::uint64_t h) - { - h ^= h >> 33; - h *= 0xff51afd7ed558ccd; - h ^= h >> 33; - h *= 0xc4ceb9fe1a85ec53; - return h ^ (h >> 33); - } - }; - template struct hash_32_or_64 : public _hash_32_or_64<(size > 4)> { }; - - static inline size_t hash_thread_id(thread_id_t id) - { - static_assert(sizeof(thread_id_t) <= 8, "Expected a platform where thread IDs are at most 64-bit values"); - return static_cast(hash_32_or_64::thread_id_hash_t)>::hash( - thread_id_converter::prehash(id))); - } - - template - static inline bool circular_less_than(T a, T b) - { -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable: 4554) -#endif - static_assert(std::is_integral::value && !std::numeric_limits::is_signed, "circular_less_than is intended to be used only with unsigned integer types"); - return static_cast(a - b) > static_cast(static_cast(1) << static_cast(sizeof(T) * CHAR_BIT - 1)); -#ifdef _MSC_VER -#pragma warning(pop) -#endif - } - - template - static inline char* align_for(char* ptr) - { - const std::size_t alignment = std::alignment_of::value; - return ptr + (alignment - (reinterpret_cast(ptr) % alignment)) % alignment; - } - template - static inline T ceil_to_pow_2(T x) - { - static_assert(std::is_integral::value && !std::numeric_limits::is_signed, "ceil_to_pow_2 is intended to be used only with unsigned integer types"); - // Adapted from http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 - --x; - x |= x >> 1; - x |= x >> 2; - x |= x >> 4; - for (std::size_t i = 1; i < sizeof(T); i <<= 1) { - x |= x >> (i << 3); - } - ++x; - return x; - } - - template - static inline void swap_relaxed(std::atomic& left, std::atomic& right) - { - T temp = std::move(left.load(std::memory_order_relaxed)); - left.store(std::move(right.load(std::memory_order_relaxed)), std::memory_order_relaxed); - right.store(std::move(temp), std::memory_order_relaxed); - } - - template - static inline T const& nomove(T const& x) - { - return x; - } - - template - struct nomove_if - { - template - static inline T const& eval(T const& x) - { - return x; - } - }; - - template<> - struct nomove_if - { - template - static inline auto eval(U&& x) - -> decltype(std::forward(x)) - { - return std::forward(x); - } - }; - - template - static inline auto deref_noexcept(It& it) MOODYCAMEL_NOEXCEPT -> decltype(*it) - { - return *it; +namespace duckdb { +class Binder; +class BoundColumnRefExpression; +class ClientContext; + +//! The RemoveUnusedColumns optimizer traverses the logical operator tree and removes any columns that are not required +class RemoveUnusedColumns : public LogicalOperatorVisitor { +public: + RemoveUnusedColumns(Binder &binder, ClientContext &context, bool is_root = false) + : binder(binder), context(context), everything_referenced(is_root) { } - -#if defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) - template struct is_trivially_destructible : std::is_trivially_destructible { }; -#else - template struct is_trivially_destructible : std::has_trivial_destructor { }; -#endif - -#ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED -#ifdef MCDBGQ_USE_RELACY - typedef RelacyThreadExitListener ThreadExitListener; - typedef RelacyThreadExitNotifier ThreadExitNotifier; -#else - struct ThreadExitListener - { - typedef void (*callback_t)(void*); - callback_t callback; - void* userData; - - ThreadExitListener* next; // reserved for use by the ThreadExitNotifier - }; - - - class ThreadExitNotifier - { - public: - static void subscribe(ThreadExitListener* listener) - { - auto& tlsInst = instance(); - listener->next = tlsInst.tail; - tlsInst.tail = listener; - } - - static void unsubscribe(ThreadExitListener* listener) - { - auto& tlsInst = instance(); - ThreadExitListener** prev = &tlsInst.tail; - for (auto ptr = tlsInst.tail; ptr != nullptr; ptr = ptr->next) { - if (ptr == listener) { - *prev = ptr->next; - break; - } - prev = &ptr->next; - } - } - - private: - ThreadExitNotifier() : tail(nullptr) { } - ThreadExitNotifier(ThreadExitNotifier const&) MOODYCAMEL_DELETE_FUNCTION; - ThreadExitNotifier& operator=(ThreadExitNotifier const&) MOODYCAMEL_DELETE_FUNCTION; - - ~ThreadExitNotifier() - { - // This thread is about to exit, let everyone know! - assert(this == &instance() && "If this assert fails, you likely have a buggy compiler! Change the preprocessor conditions such that MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED is no longer defined."); - for (auto ptr = tail; ptr != nullptr; ptr = ptr->next) { - ptr->callback(ptr->userData); - } - } - - // Thread-local - static inline ThreadExitNotifier& instance() - { - static thread_local ThreadExitNotifier notifier; - return notifier; - } - - private: - ThreadExitListener* tail; - }; -#endif -#endif - - template struct static_is_lock_free_num { enum { value = 0 }; }; - template<> struct static_is_lock_free_num { enum { value = ATOMIC_CHAR_LOCK_FREE }; }; - template<> struct static_is_lock_free_num { enum { value = ATOMIC_SHORT_LOCK_FREE }; }; - template<> struct static_is_lock_free_num { enum { value = ATOMIC_INT_LOCK_FREE }; }; - template<> struct static_is_lock_free_num { enum { value = ATOMIC_LONG_LOCK_FREE }; }; - template<> struct static_is_lock_free_num { enum { value = ATOMIC_LLONG_LOCK_FREE }; }; - template struct static_is_lock_free : static_is_lock_free_num::type> { }; - template<> struct static_is_lock_free { enum { value = ATOMIC_BOOL_LOCK_FREE }; }; - template struct static_is_lock_free { enum { value = ATOMIC_POINTER_LOCK_FREE }; }; -} + void VisitOperator(LogicalOperator &op) override; -struct ProducerToken -{ - template - explicit ProducerToken(ConcurrentQueue& queue); - - template - explicit ProducerToken(BlockingConcurrentQueue& queue); - - ProducerToken(ProducerToken&& other) MOODYCAMEL_NOEXCEPT - : producer(other.producer) - { - other.producer = nullptr; - if (producer != nullptr) { - producer->token = this; - } - } - - inline ProducerToken& operator=(ProducerToken&& other) MOODYCAMEL_NOEXCEPT - { - swap(other); - return *this; - } - - void swap(ProducerToken& other) MOODYCAMEL_NOEXCEPT - { - std::swap(producer, other.producer); - if (producer != nullptr) { - producer->token = this; - } - if (other.producer != nullptr) { - other.producer->token = &other; - } - } - - // A token is always valid unless: - // 1) Memory allocation failed during construction - // 2) It was moved via the move constructor - // (Note: assignment does a swap, leaving both potentially valid) - // 3) The associated queue was destroyed - // Note that if valid() returns true, that only indicates - // that the token is valid for use with a specific queue, - // but not which one; that's up to the user to track. - inline bool valid() const { return producer != nullptr; } - - ~ProducerToken() - { - if (producer != nullptr) { - producer->token = nullptr; - producer->inactive.store(true, std::memory_order_release); - } - } - - // Disable copying and assignment - ProducerToken(ProducerToken const&) MOODYCAMEL_DELETE_FUNCTION; - ProducerToken& operator=(ProducerToken const&) MOODYCAMEL_DELETE_FUNCTION; - -private: - template friend class ConcurrentQueue; - friend class ConcurrentQueueTests; - protected: - details::ConcurrentQueueProducerTypelessBase* producer; + unique_ptr VisitReplace(BoundColumnRefExpression &expr, unique_ptr *expr_ptr) override; + unique_ptr VisitReplace(BoundReferenceExpression &expr, unique_ptr *expr_ptr) override; + +private: + Binder &binder; + ClientContext &context; + //! 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 map of column references + column_binding_map_t> column_references; + +private: + template + void ClearUnusedExpressions(vector &list, idx_t table_idx); + + //! Perform a replacement of the ColumnBinding, iterating over all the currently found column references and + //! replacing the bindings + void ReplaceBinding(ColumnBinding current_binding, ColumnBinding new_binding); }; +} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/rule/arithmetic_simplification.hpp +// +// +//===----------------------------------------------------------------------===// -struct ConsumerToken -{ - template - explicit ConsumerToken(ConcurrentQueue& q); - - template - explicit ConsumerToken(BlockingConcurrentQueue& q); - - ConsumerToken(ConsumerToken&& other) MOODYCAMEL_NOEXCEPT - : initialOffset(other.initialOffset), lastKnownGlobalOffset(other.lastKnownGlobalOffset), itemsConsumedFromCurrent(other.itemsConsumedFromCurrent), currentProducer(other.currentProducer), desiredProducer(other.desiredProducer) - { - } - - inline ConsumerToken& operator=(ConsumerToken&& other) MOODYCAMEL_NOEXCEPT - { - swap(other); - return *this; - } - - void swap(ConsumerToken& other) MOODYCAMEL_NOEXCEPT - { - std::swap(initialOffset, other.initialOffset); - std::swap(lastKnownGlobalOffset, other.lastKnownGlobalOffset); - std::swap(itemsConsumedFromCurrent, other.itemsConsumedFromCurrent); - std::swap(currentProducer, other.currentProducer); - std::swap(desiredProducer, other.desiredProducer); - } - - // Disable copying and assignment - ConsumerToken(ConsumerToken const&) MOODYCAMEL_DELETE_FUNCTION; - ConsumerToken& operator=(ConsumerToken const&) MOODYCAMEL_DELETE_FUNCTION; -private: - template friend class ConcurrentQueue; - friend class ConcurrentQueueTests; - -private: // but shared with ConcurrentQueue - std::uint32_t initialOffset; - std::uint32_t lastKnownGlobalOffset; - std::uint32_t itemsConsumedFromCurrent; - details::ConcurrentQueueProducerTypelessBase* currentProducer; - details::ConcurrentQueueProducerTypelessBase* desiredProducer; + + + +namespace duckdb { + +// The Arithmetic Simplification rule applies arithmetic expressions to which the answer is known (e.g. X + 0 => X, X * +// 0 => 0) +class ArithmeticSimplificationRule : public Rule { +public: + explicit ArithmeticSimplificationRule(ExpressionRewriter &rewriter); + + unique_ptr Apply(LogicalOperator &op, vector &bindings, bool &changes_made, + bool is_root) override; }; -// Need to forward-declare this swap because it's in a namespace. -// See http://stackoverflow.com/questions/4492062/why-does-a-c-friend-class-need-a-forward-declaration-only-in-other-namespaces -template -inline void swap(typename ConcurrentQueue::ImplicitProducerKVP& a, typename ConcurrentQueue::ImplicitProducerKVP& b) MOODYCAMEL_NOEXCEPT; +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/rule/case_simplification.hpp +// +// +//===----------------------------------------------------------------------===// -template -class ConcurrentQueue -{ + + + +namespace duckdb { + +// The Case Simplification rule rewrites cases with a constant check (i.e. [CASE WHEN 1=1 THEN x ELSE y END] => x) +class CaseSimplificationRule : public Rule { public: - typedef ::duckdb_moodycamel::ProducerToken producer_token_t; - typedef ::duckdb_moodycamel::ConsumerToken consumer_token_t; - - typedef typename Traits::index_t index_t; - typedef typename Traits::size_t size_t; - - static const size_t BLOCK_SIZE = static_cast(Traits::BLOCK_SIZE); - static const size_t EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD = static_cast(Traits::EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD); - static const size_t EXPLICIT_INITIAL_INDEX_SIZE = static_cast(Traits::EXPLICIT_INITIAL_INDEX_SIZE); - static const size_t IMPLICIT_INITIAL_INDEX_SIZE = static_cast(Traits::IMPLICIT_INITIAL_INDEX_SIZE); - static const size_t INITIAL_IMPLICIT_PRODUCER_HASH_SIZE = static_cast(Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE); - static const std::uint32_t EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE = static_cast(Traits::EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE); -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable: 4307) // + integral constant overflow (that's what the ternary expression is for!) -#pragma warning(disable: 4309) // static_cast: Truncation of constant value -#endif - static const size_t MAX_SUBQUEUE_SIZE = (details::const_numeric_max::value - static_cast(Traits::MAX_SUBQUEUE_SIZE) < BLOCK_SIZE) ? details::const_numeric_max::value : ((static_cast(Traits::MAX_SUBQUEUE_SIZE) + (BLOCK_SIZE - 1)) / BLOCK_SIZE * BLOCK_SIZE); -#ifdef _MSC_VER -#pragma warning(pop) -#endif + explicit CaseSimplificationRule(ExpressionRewriter &rewriter); - static_assert(!std::numeric_limits::is_signed && std::is_integral::value, "Traits::size_t must be an unsigned integral type"); - static_assert(!std::numeric_limits::is_signed && std::is_integral::value, "Traits::index_t must be an unsigned integral type"); - static_assert(sizeof(index_t) >= sizeof(size_t), "Traits::index_t must be at least as wide as Traits::size_t"); - static_assert((BLOCK_SIZE > 1) && !(BLOCK_SIZE & (BLOCK_SIZE - 1)), "Traits::BLOCK_SIZE must be a power of 2 (and at least 2)"); - static_assert((EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD > 1) && !(EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD & (EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD - 1)), "Traits::EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD must be a power of 2 (and greater than 1)"); - static_assert((EXPLICIT_INITIAL_INDEX_SIZE > 1) && !(EXPLICIT_INITIAL_INDEX_SIZE & (EXPLICIT_INITIAL_INDEX_SIZE - 1)), "Traits::EXPLICIT_INITIAL_INDEX_SIZE must be a power of 2 (and greater than 1)"); - static_assert((IMPLICIT_INITIAL_INDEX_SIZE > 1) && !(IMPLICIT_INITIAL_INDEX_SIZE & (IMPLICIT_INITIAL_INDEX_SIZE - 1)), "Traits::IMPLICIT_INITIAL_INDEX_SIZE must be a power of 2 (and greater than 1)"); - static_assert((INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) || !(INITIAL_IMPLICIT_PRODUCER_HASH_SIZE & (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE - 1)), "Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE must be a power of 2"); - static_assert(INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0 || INITIAL_IMPLICIT_PRODUCER_HASH_SIZE >= 1, "Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE must be at least 1 (or 0 to disable implicit enqueueing)"); + unique_ptr Apply(LogicalOperator &op, vector &bindings, bool &changes_made, + bool is_root) override; +}; + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/rule/comparison_simplification.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { +// The Comparison Simplification rule rewrites comparisons with a constant NULL (i.e. [x = NULL] => [NULL]) +class ComparisonSimplificationRule : public Rule { public: - // Creates a queue with at least `capacity` element slots; note that the - // actual number of elements that can be inserted without additional memory - // allocation depends on the number of producers and the block size (e.g. if - // the block size is equal to `capacity`, only a single block will be allocated - // up-front, which means only a single producer will be able to enqueue elements - // without an extra allocation -- blocks aren't shared between producers). - // This method is not thread safe -- it is up to the user to ensure that the - // queue is fully constructed before it starts being used by other threads (this - // includes making the memory effects of construction visible, possibly with a - // memory barrier). - explicit ConcurrentQueue(size_t capacity = 6 * BLOCK_SIZE) - : producerListTail(nullptr), - producerCount(0), - initialBlockPoolIndex(0), - nextExplicitConsumerId(0), - globalExplicitConsumerOffset(0) - { - implicitProducerHashResizeInProgress.clear(std::memory_order_relaxed); - populate_initial_implicit_producer_hash(); - populate_initial_block_list(capacity / BLOCK_SIZE + ((capacity & (BLOCK_SIZE - 1)) == 0 ? 0 : 1)); - -#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG - // Track all the producers using a fully-resolved typed list for - // each kind; this makes it possible to debug them starting from - // the root queue object (otherwise wacky casts are needed that - // don't compile in the debugger's expression evaluator). - explicitProducers.store(nullptr, std::memory_order_relaxed); - implicitProducers.store(nullptr, std::memory_order_relaxed); -#endif - } - - // Computes the correct amount of pre-allocated blocks for you based - // on the minimum number of elements you want available at any given - // time, and the maximum concurrent number of each type of producer. - ConcurrentQueue(size_t minCapacity, size_t maxExplicitProducers, size_t maxImplicitProducers) - : producerListTail(nullptr), - producerCount(0), - initialBlockPoolIndex(0), - nextExplicitConsumerId(0), - globalExplicitConsumerOffset(0) - { - implicitProducerHashResizeInProgress.clear(std::memory_order_relaxed); - populate_initial_implicit_producer_hash(); - size_t blocks = (((minCapacity + BLOCK_SIZE - 1) / BLOCK_SIZE) - 1) * (maxExplicitProducers + 1) + 2 * (maxExplicitProducers + maxImplicitProducers); - populate_initial_block_list(blocks); - -#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG - explicitProducers.store(nullptr, std::memory_order_relaxed); - implicitProducers.store(nullptr, std::memory_order_relaxed); -#endif - } - - // Note: The queue should not be accessed concurrently while it's - // being deleted. It's up to the user to synchronize this. - // This method is not thread safe. - ~ConcurrentQueue() - { - // Destroy producers - auto ptr = producerListTail.load(std::memory_order_relaxed); - while (ptr != nullptr) { - auto next = ptr->next_prod(); - if (ptr->token != nullptr) { - ptr->token->producer = nullptr; - } - destroy(ptr); - ptr = next; - } - - // Destroy implicit producer hash tables - MOODYCAMEL_CONSTEXPR_IF (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE != 0) { - auto hash = implicitProducerHash.load(std::memory_order_relaxed); - while (hash != nullptr) { - auto prev = hash->prev; - if (prev != nullptr) { // The last hash is part of this object and was not allocated dynamically - for (size_t i = 0; i != hash->capacity; ++i) { - hash->entries[i].~ImplicitProducerKVP(); - } - hash->~ImplicitProducerHash(); - (Traits::free)(hash); - } - hash = prev; - } - } - - // Destroy global free list - auto block = freeList.head_unsafe(); - while (block != nullptr) { - auto next = block->freeListNext.load(std::memory_order_relaxed); - if (block->dynamicallyAllocated) { - destroy(block); - } - block = next; - } - - // Destroy initial free list - destroy_array(initialBlockPool, initialBlockPoolSize); - } + explicit ComparisonSimplificationRule(ExpressionRewriter &rewriter); - // Disable copying and copy assignment - ConcurrentQueue(ConcurrentQueue const&) MOODYCAMEL_DELETE_FUNCTION; - ConcurrentQueue& operator=(ConcurrentQueue const&) MOODYCAMEL_DELETE_FUNCTION; - - // Moving is supported, but note that it is *not* a thread-safe operation. - // Nobody can use the queue while it's being moved, and the memory effects - // of that move must be propagated to other threads before they can use it. - // Note: When a queue is moved, its tokens are still valid but can only be - // used with the destination queue (i.e. semantically they are moved along - // with the queue itself). - ConcurrentQueue(ConcurrentQueue&& other) MOODYCAMEL_NOEXCEPT - : producerListTail(other.producerListTail.load(std::memory_order_relaxed)), - producerCount(other.producerCount.load(std::memory_order_relaxed)), - initialBlockPoolIndex(other.initialBlockPoolIndex.load(std::memory_order_relaxed)), - initialBlockPool(other.initialBlockPool), - initialBlockPoolSize(other.initialBlockPoolSize), - freeList(std::move(other.freeList)), - nextExplicitConsumerId(other.nextExplicitConsumerId.load(std::memory_order_relaxed)), - globalExplicitConsumerOffset(other.globalExplicitConsumerOffset.load(std::memory_order_relaxed)) - { - // Move the other one into this, and leave the other one as an empty queue - implicitProducerHashResizeInProgress.clear(std::memory_order_relaxed); - populate_initial_implicit_producer_hash(); - swap_implicit_producer_hashes(other); - - other.producerListTail.store(nullptr, std::memory_order_relaxed); - other.producerCount.store(0, std::memory_order_relaxed); - other.nextExplicitConsumerId.store(0, std::memory_order_relaxed); - other.globalExplicitConsumerOffset.store(0, std::memory_order_relaxed); - -#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG - explicitProducers.store(other.explicitProducers.load(std::memory_order_relaxed), std::memory_order_relaxed); - other.explicitProducers.store(nullptr, std::memory_order_relaxed); - implicitProducers.store(other.implicitProducers.load(std::memory_order_relaxed), std::memory_order_relaxed); - other.implicitProducers.store(nullptr, std::memory_order_relaxed); -#endif - - other.initialBlockPoolIndex.store(0, std::memory_order_relaxed); - other.initialBlockPoolSize = 0; - other.initialBlockPool = nullptr; - - reown_producers(); - } - - inline ConcurrentQueue& operator=(ConcurrentQueue&& other) MOODYCAMEL_NOEXCEPT - { - return swap_internal(other); - } - - // Swaps this queue's state with the other's. Not thread-safe. - // Swapping two queues does not invalidate their tokens, however - // the tokens that were created for one queue must be used with - // only the swapped queue (i.e. the tokens are tied to the - // queue's movable state, not the object itself). - inline void swap(ConcurrentQueue& other) MOODYCAMEL_NOEXCEPT - { - swap_internal(other); - } - -private: - ConcurrentQueue& swap_internal(ConcurrentQueue& other) - { - if (this == &other) { - return *this; - } - - details::swap_relaxed(producerListTail, other.producerListTail); - details::swap_relaxed(producerCount, other.producerCount); - details::swap_relaxed(initialBlockPoolIndex, other.initialBlockPoolIndex); - std::swap(initialBlockPool, other.initialBlockPool); - std::swap(initialBlockPoolSize, other.initialBlockPoolSize); - freeList.swap(other.freeList); - details::swap_relaxed(nextExplicitConsumerId, other.nextExplicitConsumerId); - details::swap_relaxed(globalExplicitConsumerOffset, other.globalExplicitConsumerOffset); - - swap_implicit_producer_hashes(other); - - reown_producers(); - other.reown_producers(); - -#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG - details::swap_relaxed(explicitProducers, other.explicitProducers); - details::swap_relaxed(implicitProducers, other.implicitProducers); -#endif - - return *this; - } - + unique_ptr Apply(LogicalOperator &op, vector &bindings, bool &changes_made, + bool is_root) override; +}; + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/rule/conjunction_simplification.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +// The Conjunction Simplification rule rewrites conjunctions with a constant +class ConjunctionSimplificationRule : public Rule { public: - // Enqueues a single item (by copying it). - // Allocates memory if required. Only fails if memory allocation fails (or implicit - // production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0, - // or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed). - // Thread-safe. + explicit ConjunctionSimplificationRule(ExpressionRewriter &rewriter); + + unique_ptr Apply(LogicalOperator &op, vector &bindings, bool &changes_made, + bool is_root) override; + + unique_ptr RemoveExpression(BoundConjunctionExpression &conj, Expression *expr); +}; + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/rule/constant_folding.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +// Fold any constant scalar expressions into a single constant (i.e. [2 + 2] => [4], [2 = 2] => [True], etc...) +class ConstantFoldingRule : public Rule { +public: + explicit ConstantFoldingRule(ExpressionRewriter &rewriter); + + unique_ptr Apply(LogicalOperator &op, vector &bindings, bool &changes_made, + bool is_root) override; +}; + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/rule/date_part_simplification.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +// The DatePart Simplification rule rewrites date_part with a constant specifier into a specialized function (e.g. +// date_part('year', x) => year(x)) +class DatePartSimplificationRule : public Rule { +public: + explicit DatePartSimplificationRule(ExpressionRewriter &rewriter); + + unique_ptr Apply(LogicalOperator &op, vector &bindings, bool &changes_made, + bool is_root) override; +}; + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/rule/distributivity.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { + +// (X AND B) OR (X AND C) OR (X AND D) = X AND (B OR C OR D) +class DistributivityRule : public Rule { +public: + explicit DistributivityRule(ExpressionRewriter &rewriter); + + unique_ptr Apply(LogicalOperator &op, vector &bindings, bool &changes_made, + bool is_root) override; + +private: + void AddExpressionSet(Expression &expr, expression_set_t &set); + unique_ptr ExtractExpression(BoundConjunctionExpression &conj, idx_t idx, Expression &expr); +}; + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/rule/empty_needle_removal.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +// The Empty_needle_removal Optimization rule folds some foldable ConstantExpression +//(e.g.: PREFIX('xyz', '') is TRUE, PREFIX(NULL, '') is NULL, so rewrite PREFIX(x, '') to (CASE WHEN x IS NOT NULL THEN) +class EmptyNeedleRemovalRule : public Rule { +public: + explicit EmptyNeedleRemovalRule(ExpressionRewriter &rewriter); + + unique_ptr Apply(LogicalOperator &op, vector &bindings, bool &changes_made, + bool is_root) override; +}; + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/rule/like_optimizations.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { + +// The Like Optimization rule rewrites LIKE to optimized scalar functions (e.g.: prefix, suffix, and contains) +class LikeOptimizationRule : public Rule { +public: + explicit LikeOptimizationRule(ExpressionRewriter &rewriter); + + unique_ptr Apply(LogicalOperator &op, vector &bindings, bool &changes_made, + bool is_root) override; + + unique_ptr ApplyRule(BoundFunctionExpression *expr, ScalarFunction function, string pattern, + bool is_not_like); +}; + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/rule/move_constants.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +// The MoveConstantsRule moves constants to the same side of an expression, e.g. if we have an expression x + 1 = 5000 +// then this will turn it into x = 4999. +class MoveConstantsRule : public Rule { +public: + explicit MoveConstantsRule(ExpressionRewriter &rewriter); + + unique_ptr Apply(LogicalOperator &op, vector &bindings, bool &changes_made, + bool is_root) override; +}; + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/rule/enum_comparison.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +// The Enum Comparison rule rewrites cases where two Enums are compared on an equality check +class EnumComparisonRule : public Rule { +public: + explicit EnumComparisonRule(ExpressionRewriter &rewriter); + + unique_ptr Apply(LogicalOperator &op, vector &bindings, bool &changes_made, + bool is_root) override; +}; + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/statistics_propagator.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + + + + + + +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(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(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 +// +// duckdb/optimizer/topn_optimizer.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { +class LogicalOperator; +class Optimizer; + +class TopN { +public: + //! Optimize ORDER BY + LIMIT to TopN + unique_ptr Optimize(unique_ptr op); +}; + +} // namespace duckdb + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/rule/in_clause_simplification.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +// The in clause simplification rule rewrites cases where left is a column ref with a cast and right are constant values +class InClauseSimplificationRule : public Rule { +public: + explicit InClauseSimplificationRule(ExpressionRewriter &rewriter); + + unique_ptr Apply(LogicalOperator &op, vector &bindings, bool &changes_made, + bool is_root) override; +}; + +} // namespace duckdb + + +namespace duckdb { + +Optimizer::Optimizer(Binder &binder, ClientContext &context) : context(context), binder(binder), rewriter(context) { + rewriter.rules.push_back(make_unique(rewriter)); + rewriter.rules.push_back(make_unique(rewriter)); + rewriter.rules.push_back(make_unique(rewriter)); + rewriter.rules.push_back(make_unique(rewriter)); + rewriter.rules.push_back(make_unique(rewriter)); + rewriter.rules.push_back(make_unique(rewriter)); + rewriter.rules.push_back(make_unique(rewriter)); + rewriter.rules.push_back(make_unique(rewriter)); + rewriter.rules.push_back(make_unique(rewriter)); + rewriter.rules.push_back(make_unique(rewriter)); + rewriter.rules.push_back(make_unique(rewriter)); + rewriter.rules.push_back(make_unique(rewriter)); + +#ifdef DEBUG + for (auto &rule : rewriter.rules) { + // root not defined in rule + D_ASSERT(rule->root); + } +#endif +} + +void Optimizer::RunOptimizer(OptimizerType type, const std::function &callback) { + auto &config = DBConfig::GetConfig(context); + if (config.disabled_optimizers.find(type) != config.disabled_optimizers.end()) { + // optimizer is marked as disabled: skip + return; + } + auto &profiler = QueryProfiler::Get(context); + profiler.StartPhase(OptimizerTypeToString(type)); + callback(); + profiler.EndPhase(); +} + +unique_ptr Optimizer::Optimize(unique_ptr plan) { + // 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); }); + + // perform filter pullup + RunOptimizer(OptimizerType::FILTER_PULLUP, [&]() { + FilterPullup filter_pullup; + plan = filter_pullup.Rewrite(move(plan)); + }); + + // perform filter pushdown + RunOptimizer(OptimizerType::FILTER_PUSHDOWN, [&]() { + FilterPushdown filter_pushdown(*this); + plan = filter_pushdown.Rewrite(move(plan)); + }); + + RunOptimizer(OptimizerType::REGEX_RANGE, [&]() { + RegexRangeFilter regex_opt; + plan = regex_opt.Rewrite(move(plan)); + }); + + RunOptimizer(OptimizerType::IN_CLAUSE, [&]() { + InClauseRewriter rewriter(*this); + plan = rewriter.Rewrite(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)); + }); + + // removes any redundant DelimGets/DelimJoins + RunOptimizer(OptimizerType::DELIMINATOR, [&]() { + Deliminator deliminator; + plan = deliminator.Optimize(move(plan)); + }); + + RunOptimizer(OptimizerType::UNUSED_COLUMNS, [&]() { + RemoveUnusedColumns unused(binder, context, true); + unused.VisitOperator(*plan); + }); + + // perform statistics propagation + RunOptimizer(OptimizerType::STATISTICS_PROPAGATION, [&]() { + StatisticsPropagator propagator(context); + propagator.PropagateStatistics(plan); + }); + + // then we extract common subexpressions inside the different operators + RunOptimizer(OptimizerType::COMMON_SUBEXPRESSIONS, [&]() { + CommonSubExpressionOptimizer cse_optimizer(binder); + cse_optimizer.VisitOperator(*plan); + }); + + RunOptimizer(OptimizerType::COMMON_AGGREGATE, [&]() { + CommonAggregateOptimizer common_aggregate; + common_aggregate.VisitOperator(*plan); + }); + + RunOptimizer(OptimizerType::COLUMN_LIFETIME, [&]() { + ColumnLifetimeAnalyzer column_lifetime(true); + column_lifetime.VisitOperator(*plan); + }); + + // transform ORDER BY + LIMIT to TopN + RunOptimizer(OptimizerType::TOP_N, [&]() { + TopN topn; + plan = topn.Optimize(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)); + }); + + return plan; +} + +} // namespace duckdb + + +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])); + + // 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])); + } + + if (!left_pullup.filters_expr_pullup.empty()) { + return GeneratePullupFilter(move(op), left_pullup.filters_expr_pullup); + } + return op; +} + +} // namespace duckdb + + + + + + +namespace duckdb { + +unique_ptr FilterPullup::PullupFilter(unique_ptr op) { + D_ASSERT(op->type == LogicalOperatorType::LOGICAL_FILTER); + + if (can_pullup) { + unique_ptr child = move(op->children[0]); + child = Rewrite(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])); + } + return child; + } + op->children[0] = Rewrite(move(op->children[0])); + return op; +} + +} // namespace duckdb + + + + +namespace duckdb { + +unique_ptr FilterPullup::PullupFromLeft(unique_ptr op) { + D_ASSERT(op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN || + op->type == LogicalOperatorType::LOGICAL_ANY_JOIN || op->type == LogicalOperatorType::LOGICAL_EXCEPT); + + FilterPullup left_pullup(true, can_add_column); + FilterPullup right_pullup(false, can_add_column); + + op->children[0] = left_pullup.Rewrite(move(op->children[0])); + op->children[1] = right_pullup.Rewrite(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 op; +} + +} // namespace duckdb + + + + + + + +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])); + } + expressions.clear(); + filter->children.push_back(move(proj.children[0])); + proj.children[0] = move(filter); +} + +static void ReplaceExpressionBinding(vector> &proj_expressions, Expression &expr, + idx_t proj_table_idx) { + if (expr.type == ExpressionType::BOUND_COLUMN_REF) { + bool found_proj_col = false; + BoundColumnRefExpression &colref = (BoundColumnRefExpression &)expr; + // find the corresponding column index in the projection expressions + for (idx_t proj_idx = 0; proj_idx < proj_expressions.size(); proj_idx++) { + auto proj_expr = proj_expressions[proj_idx].get(); + if (proj_expr->type == ExpressionType::BOUND_COLUMN_REF) { + if (colref.Equals(proj_expr)) { + colref.binding.table_index = proj_table_idx; + colref.binding.column_index = proj_idx; + found_proj_col = true; + break; + } + } + } + if (!found_proj_col) { + // Project a new column + 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)); + } + } + ExpressionIterator::EnumerateChildren( + expr, [&](Expression &child) { return ReplaceExpressionBinding(proj_expressions, child, proj_table_idx); }); +} + +void FilterPullup::ProjectSetOperation(LogicalProjection &proj) { + vector> copy_proj_expressions; + // copying the project expressions, it's useful whether we should revert the filter pullup + for (idx_t i = 0; i < proj.expressions.size(); ++i) { + copy_proj_expressions.push_back(proj.expressions[i]->Copy()); + } + + // Replace filter expression bindings, when need we add new columns into the copied projection expression + vector> changed_filter_expressions; + 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)); + } + + /// Case new columns were added into the projection + // we must skip filter pullup because adding new columns to these operators will change the result + if (copy_proj_expressions.size() > proj.expressions.size()) { + RevertFilterPullup(proj, filters_expr_pullup); + return; + } + + // 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]); + } +} + +unique_ptr FilterPullup::PullupProjection(unique_ptr op) { + D_ASSERT(op->type == LogicalOperatorType::LOGICAL_PROJECTION); + op->children[0] = Rewrite(move(op->children[0])); + if (!filters_expr_pullup.empty()) { + auto &proj = (LogicalProjection &)*op; + // INTERSECT, EXCEPT, and DISTINCT + if (!can_add_column) { + // special treatment for operators that cannot add columns, e.g., INTERSECT, EXCEPT, and DISTINCT + ProjectSetOperation(proj); + return op; + } + + for (idx_t i = 0; i < filters_expr_pullup.size(); ++i) { + auto &expr = (Expression &)*filters_expr_pullup[i]; + ReplaceExpressionBinding(proj.expressions, expr, proj.table_index); + } + } + return op; +} + +} // namespace duckdb + + + + + +namespace duckdb { + +static void ReplaceFilterTableIndex(Expression &expr, LogicalSetOperation &setop) { + if (expr.type == ExpressionType::BOUND_COLUMN_REF) { + auto &colref = (BoundColumnRefExpression &)expr; + D_ASSERT(colref.depth == 0); + + colref.binding.table_index = setop.table_index; + return; + } + ExpressionIterator::EnumerateChildren(expr, [&](Expression &child) { ReplaceFilterTableIndex(child, setop); }); +} + +unique_ptr FilterPullup::PullupSetOperation(unique_ptr op) { + D_ASSERT(op->type == LogicalOperatorType::LOGICAL_INTERSECT || op->type == LogicalOperatorType::LOGICAL_EXCEPT); + can_add_column = false; + can_pullup = true; + if (op->type == LogicalOperatorType::LOGICAL_INTERSECT) { + op = PullupBothSide(move(op)); + } else { + // EXCEPT only pull ups from LHS + op = PullupFromLeft(move(op)); + } + if (op->type == LogicalOperatorType::LOGICAL_FILTER) { + auto &filter = (LogicalFilter &)*op; + auto &setop = (LogicalSetOperation &)*filter.children[0]; + for (idx_t i = 0; i < filter.expressions.size(); ++i) { + ReplaceFilterTableIndex(*filter.expressions[i], setop); + } + } + return op; +} + +} // namespace duckdb + + + + + + + +namespace duckdb { + +using Filter = FilterPushdown::Filter; + +static unique_ptr ReplaceGroupBindings(LogicalAggregate &proj, unique_ptr expr) { + if (expr->type == ExpressionType::BOUND_COLUMN_REF) { + auto &colref = (BoundColumnRefExpression &)*expr; + D_ASSERT(colref.binding.table_index == proj.group_index); + D_ASSERT(colref.binding.column_index < proj.groups.size()); + D_ASSERT(colref.depth == 0); + // replace the binding with a copy to the expression at the referenced index + return proj.groups[colref.binding.column_index]->Copy(); + } + ExpressionIterator::EnumerateChildren( + *expr, [&](unique_ptr &child) { child = ReplaceGroupBindings(proj, move(child)); }); + return expr; +} + +unique_ptr FilterPushdown::PushdownAggregate(unique_ptr op) { + D_ASSERT(op->type == LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY); + auto &aggr = (LogicalAggregate &)*op; + + // pushdown into AGGREGATE and GROUP BY + // we cannot push expressions that refer to the aggregate + FilterPushdown child_pushdown(optimizer); + for (idx_t i = 0; i < filters.size(); i++) { + auto &f = *filters[i]; + // check if any aggregate or GROUPING functions are in the set + if (f.bindings.find(aggr.aggregate_index) == f.bindings.end() && + f.bindings.find(aggr.groupings_index) == f.bindings.end()) { + // no aggregate! we can push this down + // rewrite any group bindings within the filter + f.filter = ReplaceGroupBindings(aggr, move(f.filter)); + // add the filter to the child node + if (child_pushdown.AddFilter(move(f.filter)) == FilterResult::UNSATISFIABLE) { + // filter statically evaluates to false, strip tree + return make_unique(move(op)); + } + // erase the filter from here + filters.erase(filters.begin() + i); + i--; + } + } + child_pushdown.GenerateFilters(); + + op->children[0] = child_pushdown.Rewrite(move(op->children[0])); + return FinishPushdown(move(op)); +} + +} // namespace duckdb + + + + +namespace duckdb { + +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; + unordered_set left_bindings, right_bindings; + if (!filters.empty()) { + // check to see into which side we should push the filters + // first get the LHS and RHS bindings + LogicalJoin::GetTableReferences(*op->children[0], left_bindings); + LogicalJoin::GetTableReferences(*op->children[1], right_bindings); + // now check the set of filters + for (auto &f : filters) { + auto side = JoinSide::GetJoinSide(f->bindings, left_bindings, right_bindings); + if (side == JoinSide::LEFT) { + // bindings match left side: push into left + left_pushdown.filters.push_back(move(f)); + } else if (side == JoinSide::RIGHT) { + // bindings match right side: push into right + right_pushdown.filters.push_back(move(f)); + } else { + D_ASSERT(side == JoinSide::BOTH); + // bindings match both: turn into join condition + join_conditions.push_back(move(f->filter)); + } + } + } + + op->children[0] = left_pushdown.Rewrite(move(op->children[0])); + op->children[1] = right_pushdown.Rewrite(move(op->children[1])); + + if (!join_conditions.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); + } else { + // no join conditions found: keep as cross product + return op; + } +} + +} // namespace duckdb + + + + +namespace duckdb { + +using Filter = FilterPushdown::Filter; + +unique_ptr FilterPushdown::PushdownFilter(unique_ptr op) { + D_ASSERT(op->type == LogicalOperatorType::LOGICAL_FILTER); + auto &filter = (LogicalFilter &)*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) { + // filter statically evaluates to false, strip tree + return make_unique(move(op)); + } + } + GenerateFilters(); + return Rewrite(move(filter.children[0])); +} + +} // namespace duckdb + + + + + + + +namespace duckdb { + +unique_ptr FilterPushdown::PushdownGet(unique_ptr op) { + D_ASSERT(op->type == LogicalOperatorType::LOGICAL_GET); + auto &get = (LogicalGet &)*op; + + if (get.function.pushdown_complex_filter) { + // for the remaining filters, check if we can push any of them into the scan as well + vector> expressions; + for (auto &filter : filters) { + expressions.push_back(move(filter->filter)); + } + filters.clear(); + + get.function.pushdown_complex_filter(optimizer.context, get, get.bind_data.get(), expressions); + + if (expressions.empty()) { + return op; + } + // re-generate the filters + for (auto &expr : expressions) { + auto f = make_unique(); + f->filter = move(expr); + f->ExtractBindings(); + filters.push_back(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)); + } + PushFilters(); + + //! We generate the table filters that will be executed during the table scan + //! Right now this only executes simple AND filters + get.table_filters = combiner.GenerateTableScanFilters(get.column_ids); + + // //! For more complex filters if all filters to a column are constants we generate a min max boundary used to + // check + // //! the zonemaps. + // auto zonemap_checks = combiner.GenerateZonemapChecks(get.column_ids, get.table_filters); + + // for (auto &f : get.table_filters) { + // f.column_index = get.column_ids[f.column_index]; + // } + + // //! Use zonemap checks as table filters for pre-processing + // for (auto &zonemap_check : zonemap_checks) { + // if (zonemap_check.column_index != COLUMN_IDENTIFIER_ROW_ID) { + // get.table_filters.push_back(zonemap_check); + // } + // } + + GenerateFilters(); + + //! Now we try to pushdown the remaining filters to perform zonemap checking + return FinishPushdown(move(op)); +} + +} // namespace duckdb + + + + + + +namespace duckdb { + +using Filter = FilterPushdown::Filter; + +unique_ptr FilterPushdown::PushdownInnerJoin(unique_ptr op, + unordered_set &left_bindings, + unordered_set &right_bindings) { + auto &join = (LogicalJoin &)*op; + D_ASSERT(join.join_type == JoinType::INNER); + D_ASSERT(op->type != LogicalOperatorType::LOGICAL_DELIM_JOIN); + // 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) { + // filter statically evaluates to false, strip tree + return make_unique(move(op)); + } + } else { + // comparison join + D_ASSERT(op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN); + auto &comp_join = (LogicalComparisonJoin &)join; + // turn the conditions into filters + for (auto &i : comp_join.conditions) { + auto condition = JoinCondition::CreateExpression(move(i)); + if (AddFilter(move(condition)) == FilterResult::UNSATISFIABLE) { + // filter statically evaluates to false, strip tree + return make_unique(move(op)); + } + } + } + GenerateFilters(); + + // turn the inner join into a cross product + auto cross_product = make_unique(); + cross_product->children.push_back(move(op->children[0])); + cross_product->children.push_back(move(op->children[1])); + // then push down cross product + return PushdownCrossProduct(move(cross_product)); +} + +} // namespace duckdb + + + + + + + + + + + +namespace duckdb { + +using Filter = FilterPushdown::Filter; + +static unique_ptr ReplaceColRefWithNull(unique_ptr expr, unordered_set &right_bindings) { + if (expr->type == ExpressionType::BOUND_COLUMN_REF) { + auto &bound_colref = (BoundColumnRefExpression &)*expr; + if (right_bindings.find(bound_colref.binding.table_index) != right_bindings.end()) { + // bound colref belongs to RHS + // replace it with a constant NULL + return make_unique(Value(expr->return_type)); + } + return expr; + } + ExpressionIterator::EnumerateChildren( + *expr, [&](unique_ptr &child) { child = ReplaceColRefWithNull(move(child), right_bindings); }); + return expr; +} + +static bool FilterRemovesNull(ExpressionRewriter &rewriter, Expression *expr, unordered_set &right_bindings) { + // 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); + + // attempt to flatten the expression by running the expression rewriter on it + auto filter = make_unique(); + filter->expressions.push_back(move(copy)); + rewriter.VisitOperator(*filter); + + // check if all expressions are foldable + for (idx_t i = 0; i < filter->expressions.size(); i++) { + if (!filter->expressions[i]->IsFoldable()) { + return false; + } + // we flattened the result into a scalar, check if it is FALSE or NULL + auto val = ExpressionExecutor::EvaluateScalar(*filter->expressions[i]).CastAs(LogicalType::BOOLEAN); + // if the result of the expression with all expressions replaced with NULL is "NULL" or "false" + // then any extra entries generated by the LEFT OUTER JOIN will be filtered out! + // hence the LEFT OUTER JOIN is equivalent to an inner join + if (val.IsNull() || !BooleanValue::Get(val)) { + return true; + } + } + return false; +} + +unique_ptr FilterPushdown::PushdownLeftJoin(unique_ptr op, + unordered_set &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); + 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 + FilterCombiner filter_combiner; + if (op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN) { + // add all comparison conditions + auto &comparison_join = (LogicalComparisonJoin &)*op; + for (auto &cond : comparison_join.conditions) { + filter_combiner.AddFilter( + make_unique(cond.comparison, cond.left->Copy(), cond.right->Copy())); + } + } + // now check the set of filters + for (idx_t i = 0; i < filters.size(); i++) { + auto side = JoinSide::GetJoinSide(filters[i]->bindings, left_bindings, right_bindings); + if (side == JoinSide::LEFT) { + // bindings match left side + // we can push the filter into the left side + if (op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN) { + // we MIGHT be able to push it down the RHS as well, but only if it is a comparison that matches the + // join predicates we use the FilterCombiner to figure this out add the expression to the FilterCombiner + filter_combiner.AddFilter(filters[i]->filter->Copy()); + } + left_pushdown.filters.push_back(move(filters[i])); + // erase the filter from the list of filters + filters.erase(filters.begin() + i); + i--; + } else { + // bindings match right side or both sides: we cannot directly push it into the right + // however, if the filter removes rows with null values from the RHS we can turn the left outer join + // in an inner join, and then push down as we would push down an inner join + if (FilterRemovesNull(optimizer.rewriter, filters[i]->filter.get(), right_bindings)) { + // the filter removes NULL values, turn it into an inner join + join.join_type = JoinType::INNER; + // now we can do more pushdown + // move all filters we added to the left_pushdown back into the filter list + for (auto &left_filter : left_pushdown.filters) { + filters.push_back(move(left_filter)); + } + // now push down the inner join + return PushdownInnerJoin(move(op), left_bindings, right_bindings); + } + } + } + // finally we check the FilterCombiner to see if there are any predicates we can push into the RHS + // we only added (1) predicates that have JoinSide::BOTH from the conditions, and + // (2) predicates that have JoinSide::LEFT from the filters + // we check now if this combination generated any new filters that are only on JoinSide::RIGHT + // this happens if, e.g. a join condition is (i=a) and there is a filter (i=500), we can then push the filter + // (a=500) into the RHS + filter_combiner.GenerateFilters([&](unique_ptr filter) { + if (JoinSide::GetJoinSide(*filter, left_bindings, right_bindings) == JoinSide::RIGHT) { + right_pushdown.AddFilter(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)); +} + +} // namespace duckdb + + + + +namespace duckdb { + +using Filter = FilterPushdown::Filter; + +unique_ptr FilterPushdown::PushdownMarkJoin(unique_ptr op, + unordered_set &left_bindings, + unordered_set &right_bindings) { + auto &join = (LogicalJoin &)*op; + auto &comp_join = (LogicalComparisonJoin &)*op; + D_ASSERT(join.join_type == JoinType::MARK); + D_ASSERT(op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN || + op->type == LogicalOperatorType::LOGICAL_DELIM_JOIN); + + right_bindings.insert(comp_join.mark_index); + FilterPushdown left_pushdown(optimizer), right_pushdown(optimizer); +#ifndef NDEBUG + bool found_mark_reference = false; +#endif + // now check the set of filters + for (idx_t i = 0; i < filters.size(); i++) { + auto side = JoinSide::GetJoinSide(filters[i]->bindings, left_bindings, right_bindings); + if (side == JoinSide::LEFT) { + // bindings match left side: push into left + left_pushdown.filters.push_back(move(filters[i])); + // erase the filter from the list of filters + filters.erase(filters.begin() + i); + i--; + } else if (side == JoinSide::RIGHT) { + // there can only be at most one filter referencing the marker +#ifndef NDEBUG + D_ASSERT(!found_mark_reference); + found_mark_reference = true; +#endif + // this filter references the marker + // we can turn this into a SEMI join if the filter is on only the marker + if (filters[i]->filter->type == ExpressionType::BOUND_COLUMN_REF) { + // filter just references the marker: turn into semi join + join.join_type = JoinType::SEMI; + filters.erase(filters.begin() + i); + i--; + continue; + } + // if the filter is on NOT(marker) AND the join conditions are all set to "null_values_are_equal" we can + // turn this into an ANTI join if all join conditions have null_values_are_equal=true, then the result of + // the MARK join is always TRUE or FALSE, and never NULL this happens in the case of a correlated EXISTS + // clause + if (filters[i]->filter->type == ExpressionType::OPERATOR_NOT) { + auto &op_expr = (BoundOperatorExpression &)*filters[i]->filter; + if (op_expr.children[0]->type == ExpressionType::BOUND_COLUMN_REF) { + // the filter is NOT(marker), check the join conditions + bool all_null_values_are_equal = true; + for (auto &cond : comp_join.conditions) { + if (!cond.null_values_are_equal) { + all_null_values_are_equal = false; + break; + } + } + if (all_null_values_are_equal) { + // all null values are equal, convert to ANTI join + join.join_type = JoinType::ANTI; + filters.erase(filters.begin() + i); + i--; + continue; + } + } + } + } + } + op->children[0] = left_pushdown.Rewrite(move(op->children[0])); + op->children[1] = right_pushdown.Rewrite(move(op->children[1])); + return FinishPushdown(move(op)); +} + +} // namespace duckdb + + + + + + +namespace duckdb { + +static unique_ptr ReplaceProjectionBindings(LogicalProjection &proj, unique_ptr expr) { + if (expr->type == ExpressionType::BOUND_COLUMN_REF) { + auto &colref = (BoundColumnRefExpression &)*expr; + D_ASSERT(colref.binding.table_index == proj.table_index); + D_ASSERT(colref.binding.column_index < proj.expressions.size()); + D_ASSERT(colref.depth == 0); + // replace the binding with a copy to the expression at the referenced index + return proj.expressions[colref.binding.column_index]->Copy(); + } + ExpressionIterator::EnumerateChildren( + *expr, [&](unique_ptr &child) { child = ReplaceProjectionBindings(proj, move(child)); }); + return expr; +} + +unique_ptr FilterPushdown::PushdownProjection(unique_ptr op) { + D_ASSERT(op->type == LogicalOperatorType::LOGICAL_PROJECTION); + auto &proj = (LogicalProjection &)*op; + // push filter through logical projection + // all the BoundColumnRefExpressions in the filter should refer to the LogicalProjection + // we can rewrite them by replacing those references with the expression of the LogicalProjection node + FilterPushdown child_pushdown(optimizer); + for (auto &filter : filters) { + auto &f = *filter; + D_ASSERT(f.bindings.size() <= 1); + // rewrite the bindings within this subquery + f.filter = ReplaceProjectionBindings(proj, move(f.filter)); + // add the filter to the child pushdown + if (child_pushdown.AddFilter(move(f.filter)) == FilterResult::UNSATISFIABLE) { + // filter statically evaluates to false, strip tree + return make_unique(move(op)); + } + } + child_pushdown.GenerateFilters(); + // now push into children + op->children[0] = child_pushdown.Rewrite(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 op; +} + +} // namespace duckdb + + + + + + + + + +namespace duckdb { + +using Filter = FilterPushdown::Filter; + +static void ReplaceSetOpBindings(vector &bindings, Filter &filter, Expression &expr, + LogicalSetOperation &setop) { + if (expr.type == ExpressionType::BOUND_COLUMN_REF) { + auto &colref = (BoundColumnRefExpression &)expr; + D_ASSERT(colref.binding.table_index == setop.table_index); + D_ASSERT(colref.depth == 0); + + // rewrite the binding by looking into the bound_tables list of the subquery + colref.binding = bindings[colref.binding.column_index]; + filter.bindings.insert(colref.binding.table_index); + return; + } + ExpressionIterator::EnumerateChildren( + expr, [&](Expression &child) { ReplaceSetOpBindings(bindings, filter, child, setop); }); +} + +unique_ptr FilterPushdown::PushdownSetOperation(unique_ptr op) { + D_ASSERT(op->type == LogicalOperatorType::LOGICAL_UNION || op->type == LogicalOperatorType::LOGICAL_EXCEPT || + op->type == LogicalOperatorType::LOGICAL_INTERSECT); + auto &setop = (LogicalSetOperation &)*op; + + D_ASSERT(op->children.size() == 2); + auto left_bindings = op->children[0]->GetColumnBindings(); + auto right_bindings = op->children[1]->GetColumnBindings(); + + // pushdown into set operation, we can duplicate the condition and pushdown the expressions into both sides + FilterPushdown left_pushdown(optimizer), right_pushdown(optimizer); + for (idx_t i = 0; i < filters.size(); i++) { + // first create a copy of the filter + auto right_filter = make_unique(); + right_filter->filter = filters[i]->filter->Copy(); + + // in the original filter, rewrite references to the result of the union into references to the left_index + ReplaceSetOpBindings(left_bindings, *filters[i], *filters[i]->filter, setop); + // in the copied filter, rewrite references to the result of the union into references to the right_index + ReplaceSetOpBindings(right_bindings, *right_filter, *right_filter->filter, setop); + + // extract bindings again + filters[i]->ExtractBindings(); + right_filter->ExtractBindings(); + + // move the filters into the child pushdown nodes + left_pushdown.filters.push_back(move(filters[i])); + right_pushdown.filters.push_back(move(right_filter)); + } + + op->children[0] = left_pushdown.Rewrite(move(op->children[0])); + op->children[1] = right_pushdown.Rewrite(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)); + } + if (left_empty) { + // left child is empty result + switch (op->type) { + case LogicalOperatorType::LOGICAL_UNION: + if (op->children[1]->type == LogicalOperatorType::LOGICAL_PROJECTION) { + // union with empty left side: return right child + auto &projection = (LogicalProjection &)*op->children[1]; + projection.table_index = setop.table_index; + return 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)); + default: + throw InternalException("Unsupported set operation"); + } + } else if (right_empty) { + // right child is empty result + switch (op->type) { + case LogicalOperatorType::LOGICAL_UNION: + case LogicalOperatorType::LOGICAL_EXCEPT: + if (op->children[0]->type == LogicalOperatorType::LOGICAL_PROJECTION) { + // union or except with empty right child: return left child + auto &projection = (LogicalProjection &)*op->children[0]; + projection.table_index = setop.table_index; + return move(op->children[0]); + } + break; + case LogicalOperatorType::LOGICAL_INTERSECT: + // intersect: if any child is empty, return empty result itself + return make_unique(move(op)); + default: + throw InternalException("Unsupported set operation"); + } + } + return op; +} + +} // namespace duckdb + + + +namespace duckdb { + +using Filter = FilterPushdown::Filter; + +unique_ptr FilterPushdown::PushdownSingleJoin(unique_ptr op, + unordered_set &left_bindings, + unordered_set &right_bindings) { + D_ASSERT(((LogicalJoin &)*op).join_type == JoinType::SINGLE); + FilterPushdown left_pushdown(optimizer), right_pushdown(optimizer); + // now check the set of filters + for (idx_t i = 0; i < filters.size(); i++) { + auto side = JoinSide::GetJoinSide(filters[i]->bindings, left_bindings, right_bindings); + if (side == JoinSide::LEFT) { + // bindings match left side: push into left + left_pushdown.filters.push_back(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)); +} + +} // namespace duckdb + + + + + + + + + + + + + + + +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])); + } + + if (op->type != LogicalOperatorType::LOGICAL_FILTER) { + return op; + } + + auto new_filter = make_unique(); + + for (auto &expr : op->expressions) { + if (expr->type == ExpressionType::BOUND_FUNCTION) { + auto &func = (BoundFunctionExpression &)*expr.get(); + if (func.function.name != "regexp_full_match" || func.children.size() != 2) { + continue; + } + auto &info = (RegexpMatchesBindData &)*func.bind_info; + if (!info.range_success) { + continue; + } + auto filter_left = make_unique( + ExpressionType::COMPARE_GREATERTHANOREQUALTO, func.children[0]->Copy(), + make_unique( + Value::BLOB((const_data_ptr_t)info.range_min.c_str(), info.range_min.size()))); + auto filter_right = make_unique( + ExpressionType::COMPARE_LESSTHANOREQUALTO, func.children[0]->Copy(), + make_unique( + 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)); + + new_filter->expressions.push_back(move(filter_expr)); + } + } + + if (!new_filter->expressions.empty()) { + new_filter->children = move(op->children); + op->children.clear(); + op->children.push_back(move(new_filter)); + } + + return op; +} + +} // namespace duckdb + + + + + + + + + + + + + + + + +#include + +namespace duckdb { + +void RemoveUnusedColumns::ReplaceBinding(ColumnBinding current_binding, ColumnBinding new_binding) { + auto colrefs = column_references.find(current_binding); + if (colrefs != column_references.end()) { + for (auto &colref : colrefs->second) { + D_ASSERT(colref->binding == current_binding); + colref->binding = new_binding; + } + } +} + +template +void RemoveUnusedColumns::ClearUnusedExpressions(vector &list, idx_t table_idx) { + idx_t offset = 0; + for (idx_t col_idx = 0; col_idx < list.size(); col_idx++) { + auto current_binding = ColumnBinding(table_idx, col_idx + offset); + auto entry = column_references.find(current_binding); + if (entry == column_references.end()) { + // this entry is not referred to, erase it from the set of expressions + list.erase(list.begin() + col_idx); + offset++; + col_idx--; + } else if (offset > 0) { + // column is used but the ColumnBinding has changed because of removed columns + ReplaceBinding(current_binding, ColumnBinding(table_idx, col_idx)); + } + } +} + +void RemoveUnusedColumns::VisitOperator(LogicalOperator &op) { + switch (op.type) { + case LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY: { + // aggregate + if (!everything_referenced) { + // FIXME: groups that are not referenced need to stay -> but they don't need to be scanned and output! + auto &aggr = (LogicalAggregate &)op; + ClearUnusedExpressions(aggr.expressions, aggr.aggregate_index); + if (aggr.expressions.empty() && aggr.groups.empty()) { + // removed all expressions from the aggregate: push a COUNT(*) + auto count_star_fun = CountStarFun::GetFunction(); + aggr.expressions.push_back( + AggregateFunction::BindAggregateFunction(context, count_star_fun, {}, nullptr, false)); + } + } + + // then recurse into the children of the aggregate + RemoveUnusedColumns remove(binder, context); + remove.VisitOperatorExpressions(op); + remove.VisitOperator(*op.children[0]); + return; + } + case LogicalOperatorType::LOGICAL_DELIM_JOIN: + case LogicalOperatorType::LOGICAL_COMPARISON_JOIN: { + if (!everything_referenced) { + auto &comp_join = (LogicalComparisonJoin &)op; + + if (comp_join.join_type != JoinType::INNER) { + break; + } + // for inner joins with equality predicates in the form of (X=Y) + // we can replace any references to the RHS (Y) to references to the LHS (X) + // this reduces the amount of columns we need to extract from the join hash table + for (auto &cond : comp_join.conditions) { + if (cond.comparison == ExpressionType::COMPARE_EQUAL) { + if (cond.left->expression_class == ExpressionClass::BOUND_COLUMN_REF && + cond.right->expression_class == ExpressionClass::BOUND_COLUMN_REF) { + // comparison join between two bound column refs + // we can replace any reference to the RHS (build-side) with a reference to the LHS (probe-side) + auto &lhs_col = (BoundColumnRefExpression &)*cond.left; + auto &rhs_col = (BoundColumnRefExpression &)*cond.right; + // if there are any columns that refer to the RHS, + auto colrefs = column_references.find(rhs_col.binding); + if (colrefs != column_references.end()) { + for (auto &entry : colrefs->second) { + entry->binding = lhs_col.binding; + column_references[lhs_col.binding].push_back(entry); + } + column_references.erase(rhs_col.binding); + } + } + } + } + } + break; + } + case LogicalOperatorType::LOGICAL_ANY_JOIN: + break; + case LogicalOperatorType::LOGICAL_UNION: + if (!everything_referenced) { + // 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) + // this happens when UNION ALL is used + auto &setop = (LogicalSetOperation &)op; + vector entries; + for (idx_t i = 0; i < setop.column_count; i++) { + entries.push_back(i); + } + ClearUnusedExpressions(entries, setop.table_index); + if (entries.size() < setop.column_count) { + if (entries.empty()) { + // no columns referenced: this happens in the case of a COUNT(*) + // extract the first column + entries.push_back(0); + } + // columns were cleared + setop.column_count = entries.size(); + + for (idx_t child_idx = 0; child_idx < op.children.size(); child_idx++) { + RemoveUnusedColumns remove(binder, context, true); + auto &child = op.children[child_idx]; + + // we push a projection under this child that references the required columns of the union + child->ResolveOperatorTypes(); + auto bindings = child->GetColumnBindings(); + vector> expressions; + expressions.reserve(entries.size()); + for (auto &column_idx : entries) { + expressions.push_back( + 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); + + remove.VisitOperator(*op.children[child_idx]); + } + return; + } + } + for (auto &child : op.children) { + RemoveUnusedColumns remove(binder, context, true); + remove.VisitOperator(*child); + } + return; + case LogicalOperatorType::LOGICAL_EXCEPT: + case LogicalOperatorType::LOGICAL_INTERSECT: + // for INTERSECT/EXCEPT operations we can't remove anything, just recursively visit the children + for (auto &child : op.children) { + RemoveUnusedColumns remove(binder, context, true); + remove.VisitOperator(*child); + } + return; + case LogicalOperatorType::LOGICAL_PROJECTION: { + if (!everything_referenced) { + auto &proj = (LogicalProjection &)op; + ClearUnusedExpressions(proj.expressions, proj.table_index); + + if (proj.expressions.empty()) { + // nothing references the projected expressions + // this happens in the case of e.g. EXISTS(SELECT * FROM ...) + // in this case we only need to project a single constant + proj.expressions.push_back(make_unique(Value::INTEGER(42))); + } + } + // then recurse into the children of this projection + RemoveUnusedColumns remove(binder, context); + remove.VisitOperatorExpressions(op); + remove.VisitOperator(*op.children[0]); + return; + } + case LogicalOperatorType::LOGICAL_GET: + LogicalOperatorVisitor::VisitOperatorExpressions(op); + if (!everything_referenced) { + auto &get = (LogicalGet &)op; + // for every table filter, push a column binding into the column references map to prevent the column from + // being projected out + for (auto &filter : get.table_filters.filters) { + idx_t index = DConstants::INVALID_INDEX; + for (idx_t i = 0; i < get.column_ids.size(); i++) { + if (get.column_ids[i] == filter.first) { + index = i; + break; + } + } + if (index == DConstants::INVALID_INDEX) { + throw InternalException("Could not find column index for table filter"); + } + ColumnBinding filter_binding(get.table_index, index); + if (column_references.find(filter_binding) == column_references.end()) { + column_references.insert(make_pair(filter_binding, vector())); + } + } + // table scan: figure out which columns are referenced + ClearUnusedExpressions(get.column_ids, get.table_index); + + if (get.column_ids.empty()) { + // this generally means we are only interested in whether or not anything exists in the table (e.g. + // EXISTS(SELECT * FROM tbl)) in this case, we just scan the row identifier column as it means we do not + // need to read any of the columns + get.column_ids.push_back(COLUMN_IDENTIFIER_ROW_ID); + } + } + 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_RECURSIVE_CTE: { + everything_referenced = true; + break; + } + case LogicalOperatorType::LOGICAL_CTE_REF: { + everything_referenced = true; + break; + } + default: + break; + } + LogicalOperatorVisitor::VisitOperatorExpressions(op); + LogicalOperatorVisitor::VisitOperatorChildren(op); +} + +unique_ptr RemoveUnusedColumns::VisitReplace(BoundColumnRefExpression &expr, + unique_ptr *expr_ptr) { + // add a column reference + column_references[expr.binding].push_back(&expr); + return nullptr; +} + +unique_ptr RemoveUnusedColumns::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 + + + + + + + +namespace duckdb { + +ArithmeticSimplificationRule::ArithmeticSimplificationRule(ExpressionRewriter &rewriter) : Rule(rewriter) { + // match on an OperatorExpression that has a ConstantExpression as child + auto op = make_unique(); + op->matchers.push_back(make_unique()); + op->matchers.push_back(make_unique()); + op->policy = SetMatcher::Policy::SOME; + // we only match on simple arithmetic expressions (+, -, *, /) + op->function = make_unique(unordered_set {"+", "-", "*", "/"}); + // and only with numeric results + op->type = make_unique(); + op->matchers[0]->type = make_unique(); + op->matchers[1]->type = make_unique(); + root = move(op); +} + +unique_ptr ArithmeticSimplificationRule::Apply(LogicalOperator &op, vector &bindings, + bool &changes_made, bool is_root) { + auto root = (BoundFunctionExpression *)bindings[0]; + auto constant = (BoundConstantExpression *)bindings[1]; + int constant_child = root->children[0].get() == constant ? 0 : 1; + D_ASSERT(root->children.size() == 2); + (void)root; + // any arithmetic operator involving NULL is always NULL + if (constant->value.IsNull()) { + return make_unique(Value(root->return_type)); + } + auto &func_name = root->function.name; + if (func_name == "+") { + 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]); + } + } 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]); + } + } else if (func_name == "*") { + if (constant->value == 1) { + // multiply with 1, replace with non-constant child + return 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]), + Value::Numeric(root->return_type, 0)); + } + } else { + D_ASSERT(func_name == "/"); + if (constant_child == 1) { + if (constant->value == 1) { + // divide by 1, replace with non-constant child + return move(root->children[1 - constant_child]); + } else if (constant->value == 0) { + // divide by 0, replace with NULL + return make_unique(Value(root->return_type)); + } + } + } + return nullptr; +} +} // namespace duckdb + + + + + +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); +} + +unique_ptr CaseSimplificationRule::Apply(LogicalOperator &op, vector &bindings, + bool &changes_made, bool is_root) { + auto root = (BoundCaseExpression *)bindings[0]; + for (idx_t i = 0; i < root->case_checks.size(); i++) { + auto &case_check = root->case_checks[i]; + if (case_check.when_expr->IsFoldable()) { + // the WHEN check is a foldable expression + // use an ExpressionExecutor to execute the expression + auto constant_value = ExpressionExecutor::EvaluateScalar(*case_check.when_expr); + + // fold based on the constant condition + auto condition = constant_value.CastAs(LogicalType::BOOLEAN); + if (condition.IsNull() || !BooleanValue::Get(condition)) { + // the condition is always false: remove this case check + root->case_checks.erase(root->case_checks.begin() + i); + i--; + } else { + // the condition is always true + // move the THEN clause to the ELSE of the case + root->else_expr = 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; + } + } + } + if (root->case_checks.empty()) { + // no case checks left: return the ELSE expression + return move(root->else_expr); + } + return nullptr; +} + +} // namespace duckdb + + + + + + +namespace duckdb { + +ComparisonSimplificationRule::ComparisonSimplificationRule(ExpressionRewriter &rewriter) : Rule(rewriter) { + // match on a ComparisonExpression that has a ConstantExpression as a check + auto op = make_unique(); + op->matchers.push_back(make_unique()); + op->policy = SetMatcher::Policy::SOME; + root = move(op); +} + +unique_ptr ComparisonSimplificationRule::Apply(LogicalOperator &op, vector &bindings, + bool &changes_made, bool is_root) { + D_ASSERT(bindings[0]->expression_class == ExpressionClass::BOUND_COMPARISON); + auto expr = (BoundComparisonExpression *)bindings[0]; + auto constant_expr = bindings[1]; + bool column_ref_left = expr->left.get() != constant_expr; + auto column_ref_expr = !column_ref_left ? expr->right.get() : expr->left.get(); + // the constant_expr is a scalar expression that we have to fold + // use an ExpressionExecutor to execute the expression + D_ASSERT(constant_expr->IsFoldable()); + Value constant_value; + if (!ExpressionExecutor::TryEvaluateScalar(*constant_expr, constant_value)) { + return nullptr; + } + if (constant_value.IsNull() && !(expr->type == ExpressionType::COMPARE_NOT_DISTINCT_FROM || + expr->type == ExpressionType::COMPARE_DISTINCT_FROM)) { + // comparison with constant NULL, return NULL + return make_unique(Value(LogicalType::BOOLEAN)); + } + if (column_ref_expr->expression_class == ExpressionClass::BOUND_CAST) { + //! Here we check if we can apply the expression on the constant side + auto cast_expression = (BoundCastExpression *)column_ref_expr; + auto target_type = cast_expression->source_type(); + if (!BoundCastExpression::CastIsInvertible(target_type, cast_expression->return_type)) { + return nullptr; + } + auto new_constant = constant_value.TryCastAs(target_type); + if (new_constant) { + auto child_expression = move(cast_expression->child); + auto new_constant_expr = make_unique(constant_value); + //! We can cast, now we change our column_ref_expression from an operator cast to a column reference + if (column_ref_left) { + expr->left = move(child_expression); + expr->right = move(new_constant_expr); + } else { + expr->left = move(new_constant_expr); + expr->right = move(child_expression); + } + } + } + return nullptr; +} + +} // namespace duckdb + + + + + + +namespace duckdb { + +ConjunctionSimplificationRule::ConjunctionSimplificationRule(ExpressionRewriter &rewriter) : Rule(rewriter) { + // match on a ComparisonExpression that has a ConstantExpression as a check + auto op = make_unique(); + op->matchers.push_back(make_unique()); + op->policy = SetMatcher::Policy::SOME; + root = move(op); +} + +unique_ptr ConjunctionSimplificationRule::RemoveExpression(BoundConjunctionExpression &conj, + Expression *expr) { + for (idx_t i = 0; i < conj.children.size(); i++) { + if (conj.children[i].get() == expr) { + // erase the expression + conj.children.erase(conj.children.begin() + i); + break; + } + } + if (conj.children.size() == 1) { + // one expression remaining: simply return that expression and erase the conjunction + return move(conj.children[0]); + } + return nullptr; +} + +unique_ptr ConjunctionSimplificationRule::Apply(LogicalOperator &op, vector &bindings, + bool &changes_made, bool is_root) { + auto conjunction = (BoundConjunctionExpression *)bindings[0]; + auto constant_expr = bindings[1]; + // the constant_expr is a scalar expression that we have to fold + // use an ExpressionExecutor to execute the expression + D_ASSERT(constant_expr->IsFoldable()); + Value constant_value; + if (!ExpressionExecutor::TryEvaluateScalar(*constant_expr, constant_value)) { + return nullptr; + } + constant_value = constant_value.CastAs(LogicalType::BOOLEAN); + if (constant_value.IsNull()) { + // we can't simplify conjunctions with a constant NULL + return nullptr; + } + if (conjunction->type == ExpressionType::CONJUNCTION_AND) { + if (!BooleanValue::Get(constant_value)) { + // FALSE in AND, result of expression is false + return make_unique(Value::BOOLEAN(false)); + } else { + // TRUE in AND, remove the expression from the set + return RemoveExpression(*conjunction, constant_expr); + } + } else { + D_ASSERT(conjunction->type == ExpressionType::CONJUNCTION_OR); + if (!BooleanValue::Get(constant_value)) { + // FALSE in OR, remove the expression from the set + return RemoveExpression(*conjunction, constant_expr); + } else { + // TRUE in OR, result of expression is true + return make_unique(Value::BOOLEAN(true)); + } + } +} + +} // namespace duckdb + + + + + + + +namespace duckdb { + +//! The ConstantFoldingExpressionMatcher matches on any scalar expression (i.e. Expression::IsFoldable is true) +class ConstantFoldingExpressionMatcher : public FoldableConstantMatcher { +public: + bool Match(Expression *expr, vector &bindings) override { + // we also do not match on ConstantExpressions, because we cannot fold those any further + if (expr->type == ExpressionType::VALUE_CONSTANT) { + return false; + } + return FoldableConstantMatcher::Match(expr, bindings); + } +}; + +ConstantFoldingRule::ConstantFoldingRule(ExpressionRewriter &rewriter) : Rule(rewriter) { + auto op = make_unique(); + root = move(op); +} + +unique_ptr ConstantFoldingRule::Apply(LogicalOperator &op, vector &bindings, + bool &changes_made, bool is_root) { + auto root = bindings[0]; + // the root is a scalar expression that we have to fold + D_ASSERT(root->IsFoldable() && root->type != ExpressionType::VALUE_CONSTANT); + + // use an ExpressionExecutor to execute the expression + Value result_value; + if (!ExpressionExecutor::TryEvaluateScalar(*root, result_value)) { + return nullptr; + } + D_ASSERT(result_value.type().InternalType() == root->return_type.InternalType()); + // now get the value from the result vector and insert it back into the plan as a constant expression + return make_unique(result_value); +} + +} // namespace duckdb + + + + + + + + + + +namespace duckdb { + +DatePartSimplificationRule::DatePartSimplificationRule(ExpressionRewriter &rewriter) : Rule(rewriter) { + auto func = make_unique(); + func->function = make_unique("date_part"); + func->matchers.push_back(make_unique()); + func->matchers.push_back(make_unique()); + func->policy = SetMatcher::Policy::ORDERED; + root = move(func); +} + +unique_ptr DatePartSimplificationRule::Apply(LogicalOperator &op, vector &bindings, + bool &changes_made, bool is_root) { + auto &date_part = (BoundFunctionExpression &)*bindings[0]; + auto &constant_expr = (BoundConstantExpression &)*bindings[1]; + auto &constant = constant_expr.value; + + if (constant.IsNull()) { + // NULL specifier: return constant NULL + return make_unique(Value(date_part.return_type)); + } + // otherwise check the specifier + auto specifier = GetDatePartSpecifier(StringValue::Get(constant)); + string new_function_name; + switch (specifier) { + case DatePartSpecifier::YEAR: + new_function_name = "year"; + break; + case DatePartSpecifier::MONTH: + new_function_name = "month"; + break; + case DatePartSpecifier::DAY: + new_function_name = "day"; + break; + case DatePartSpecifier::DECADE: + new_function_name = "decade"; + break; + case DatePartSpecifier::CENTURY: + new_function_name = "century"; + break; + case DatePartSpecifier::MILLENNIUM: + new_function_name = "millennium"; + break; + case DatePartSpecifier::QUARTER: + new_function_name = "quarter"; + break; + case DatePartSpecifier::WEEK: + new_function_name = "week"; + break; + case DatePartSpecifier::YEARWEEK: + new_function_name = "yearweek"; + break; + case DatePartSpecifier::DOW: + new_function_name = "dayofweek"; + break; + case DatePartSpecifier::ISODOW: + new_function_name = "isodow"; + break; + case DatePartSpecifier::DOY: + new_function_name = "dayofyear"; + break; + case DatePartSpecifier::EPOCH: + new_function_name = "epoch"; + break; + case DatePartSpecifier::MICROSECONDS: + new_function_name = "microsecond"; + break; + case DatePartSpecifier::MILLISECONDS: + new_function_name = "millisecond"; + break; + case DatePartSpecifier::SECOND: + new_function_name = "second"; + break; + case DatePartSpecifier::MINUTE: + new_function_name = "minute"; + break; + case DatePartSpecifier::HOUR: + new_function_name = "hour"; + break; + default: + return nullptr; + } + // found a replacement function: bind it + vector> children; + children.push_back(move(date_part.children[1])); + + string error; + auto function = ScalarFunction::BindScalarFunction(rewriter.context, DEFAULT_SCHEMA, new_function_name, + move(children), error, false); + if (!function) { + throw BinderException(error); + } + return move(function); +} + +} // namespace duckdb + + + + + + + + +namespace duckdb { + +DistributivityRule::DistributivityRule(ExpressionRewriter &rewriter) : Rule(rewriter) { + // we match on an OR expression within a LogicalFilter node + root = make_unique(); + root->expr_type = make_unique(ExpressionType::CONJUNCTION_OR); +} + +void DistributivityRule::AddExpressionSet(Expression &expr, expression_set_t &set) { + if (expr.type == ExpressionType::CONJUNCTION_AND) { + auto &and_expr = (BoundConjunctionExpression &)expr; + for (auto &child : and_expr.children) { + set.insert(child.get()); + } + } else { + set.insert(&expr); + } +} + +unique_ptr DistributivityRule::ExtractExpression(BoundConjunctionExpression &conj, idx_t idx, + Expression &expr) { + auto &child = conj.children[idx]; + unique_ptr result; + if (child->type == ExpressionType::CONJUNCTION_AND) { + // AND, remove expression from the list + 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]); + and_expr.children.erase(and_expr.children.begin() + i); + break; + } + } + if (and_expr.children.size() == 1) { + conj.children[idx] = 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); + conj.children[idx] = nullptr; + } + D_ASSERT(result); + return result; +} + +unique_ptr DistributivityRule::Apply(LogicalOperator &op, vector &bindings, + bool &changes_made, bool is_root) { + auto initial_or = (BoundConjunctionExpression *)bindings[0]; + + // we want to find expressions that occur in each of the children of the OR + // i.e. (X AND A) OR (X AND B) => X occurs in all branches + // first, for the initial child, we create an expression set of which expressions occur + // this is our initial candidate set (in the example: [X, A]) + expression_set_t candidate_set; + AddExpressionSet(*initial_or->children[0], candidate_set); + // now for each of the remaining children, we create a set again and intersect them + // in our example: the second set would be [X, B] + // the intersection would leave [X] + for (idx_t i = 1; i < initial_or->children.size(); i++) { + expression_set_t next_set; + AddExpressionSet(*initial_or->children[i], next_set); + expression_set_t intersect_result; + for (auto &expr : candidate_set) { + if (next_set.find(expr) != next_set.end()) { + intersect_result.insert(expr); + } + } + candidate_set = intersect_result; + } + if (candidate_set.empty()) { + // nothing found: abort + return nullptr; + } + // now for each of the remaining expressions in the candidate set we know that it is contained in all branches of + // the OR + auto new_root = make_unique(ExpressionType::CONJUNCTION_AND); + for (auto &expr : candidate_set) { + D_ASSERT(initial_or->children.size() > 0); + + // extract the expression from the first child of the OR + auto result = ExtractExpression(*initial_or, 0, (Expression &)*expr); + // now for the subsequent expressions, simply remove the expression + for (idx_t i = 1; i < initial_or->children.size(); i++) { + ExtractExpression(*initial_or, i, *result); + } + // now we add the expression to the new root + new_root->children.push_back(move(result)); + } + + // check if we completely erased one of the children of the OR + // this happens if we have an OR in the form of "X OR (X AND A)" + // the left child will be completely empty, as it only contains common expressions + // in this case, any other children are not useful: + // X OR (X AND A) is the same as "X" + // since (1) only tuples that do not qualify "X" will not pass this predicate + // and (2) all tuples that qualify "X" will pass this predicate + for (idx_t i = 0; i < initial_or->children.size(); i++) { + if (!initial_or->children[i]) { + if (new_root->children.size() <= 1) { + return move(new_root->children[0]); + } else { + return 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])); + } 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_root->children.push_back(move(new_or)); + } + // finally return the new root + if (new_root->children.size() == 1) { + return move(new_root->children[0]); + } + return move(new_root); +} + +} // namespace duckdb + + + + + + + + + +namespace duckdb { + +EmptyNeedleRemovalRule::EmptyNeedleRemovalRule(ExpressionRewriter &rewriter) : Rule(rewriter) { + // match on a FunctionExpression that has a foldable ConstantExpression + auto func = make_unique(); + func->matchers.push_back(make_unique()); + func->matchers.push_back(make_unique()); + func->policy = SetMatcher::Policy::SOME; + + unordered_set functions = {"prefix", "contains", "suffix"}; + func->function = make_unique(functions); + root = move(func); +} + +unique_ptr EmptyNeedleRemovalRule::Apply(LogicalOperator &op, vector &bindings, + bool &changes_made, bool is_root) { + auto root = (BoundFunctionExpression *)bindings[0]; + D_ASSERT(root->children.size() == 2); + (void)root; + auto prefix_expr = bindings[2]; + + // the constant_expr is a scalar expression that we have to fold + if (!prefix_expr->IsFoldable()) { + return nullptr; + } + D_ASSERT(root->return_type.id() == LogicalTypeId::BOOLEAN); + + auto prefix_value = ExpressionExecutor::EvaluateScalar(*prefix_expr); + + if (prefix_value.IsNull()) { + return make_unique(Value(LogicalType::BOOLEAN)); + } + + D_ASSERT(prefix_value.type() == prefix_expr->return_type); + auto &needle_string = StringValue::Get(prefix_value); + + // PREFIX('xyz', '') is TRUE + // 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 nullptr; +} + +} // namespace duckdb + + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/matcher/type_matcher_id.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +//! The TypeMatcherId class contains a set of matchers that can be used to pattern match TypeIds for Rules +class TypeMatcherId : public TypeMatcher { +public: + explicit TypeMatcherId(LogicalTypeId type_id_p) : type_id(type_id_p) { + } + + bool Match(const LogicalType &type) override { + return type.id() == this->type_id; + } + +private: + LogicalTypeId type_id; +}; + +} // namespace duckdb + + + + +namespace duckdb { + +EnumComparisonRule::EnumComparisonRule(ExpressionRewriter &rewriter) : Rule(rewriter) { + // match on a ComparisonExpression that is an Equality and has a VARCHAR and ENUM as its children + auto op = make_unique(); + // Enum requires expression to be root + op->expr_type = make_unique(ExpressionType::COMPARE_EQUAL); + for (idx_t i = 0; i < 2; i++) { + auto child = make_unique(); + child->type = make_unique(LogicalTypeId::VARCHAR); + child->matcher = make_unique(); + child->matcher->type = make_unique(LogicalTypeId::ENUM); + op->matchers.push_back(move(child)); + } + root = move(op); +} + +bool AreMatchesPossible(LogicalType &left, LogicalType &right) { + LogicalType *small_enum, *big_enum; + if (EnumType::GetSize(left) < EnumType::GetSize(right)) { + small_enum = &left; + big_enum = &right; + } else { + small_enum = &right; + big_enum = &left; + } + auto &string_vec = EnumType::GetValuesInsertOrder(*small_enum); + auto string_vec_ptr = FlatVector::GetData(string_vec); + auto size = EnumType::GetSize(*small_enum); + for (idx_t i = 0; i < size; i++) { + auto key = string_vec_ptr[i].GetString(); + if (EnumType::GetPos(*big_enum, key) != -1) { + return true; + } + } + return false; +} +unique_ptr EnumComparisonRule::Apply(LogicalOperator &op, vector &bindings, + bool &changes_made, bool is_root) { + + auto root = (BoundComparisonExpression *)bindings[0]; + auto left_child = (BoundCastExpression *)bindings[1]; + auto right_child = (BoundCastExpression *)bindings[3]; + + if (!AreMatchesPossible(left_child->child->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)); + } + + if (!is_root || op.type != LogicalOperatorType::LOGICAL_FILTER) { + return nullptr; + } + + auto cast_left_to_right = + make_unique(move(left_child->child), right_child->child->return_type); + + return make_unique(root->type, move(cast_left_to_right), move(right_child->child)); +} + +} // namespace duckdb + + + + + +namespace duckdb { + +InClauseSimplificationRule::InClauseSimplificationRule(ExpressionRewriter &rewriter) : Rule(rewriter) { + // match on InClauseExpression that has a ConstantExpression as a check + auto op = make_unique(); + op->policy = SetMatcher::Policy::SOME; + root = move(op); +} + +unique_ptr InClauseSimplificationRule::Apply(LogicalOperator &op, vector &bindings, + bool &changes_made, bool is_root) { + D_ASSERT(bindings[0]->expression_class == ExpressionClass::BOUND_OPERATOR); + auto expr = (BoundOperatorExpression *)bindings[0]; + if (expr->children[0]->expression_class != ExpressionClass::BOUND_CAST) { + return nullptr; + } + auto cast_expression = (BoundCastExpression *)expr->children[0].get(); + if (cast_expression->child->expression_class != ExpressionClass::BOUND_COLUMN_REF) { + return nullptr; + } + //! Here we check if we can apply the expression on the constant side + auto target_type = cast_expression->source_type(); + if (!BoundCastExpression::CastIsInvertible(cast_expression->return_type, target_type)) { + return nullptr; + } + vector> cast_list; + //! First check if we can cast all children + for (size_t i = 1; i < expr->children.size(); i++) { + if (expr->children[i]->expression_class != ExpressionClass::BOUND_CONSTANT) { + return nullptr; + } + D_ASSERT(expr->children[i]->IsFoldable()); + auto constant_value = ExpressionExecutor::EvaluateScalar(*expr->children[i]); + auto new_constant = constant_value.TryCastAs(target_type); + if (!new_constant) { + return nullptr; + } else { + auto new_constant_expr = make_unique(constant_value); + cast_list.push_back(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] = move(new_constant_expr); + } + //! We can cast the full list, so we move the column + expr->children[0] = move(cast_expression->child); + return nullptr; +} + +} // namespace duckdb + + + + + + + + +namespace duckdb { + +LikeOptimizationRule::LikeOptimizationRule(ExpressionRewriter &rewriter) : Rule(rewriter) { + // match on a FunctionExpression that has a foldable ConstantExpression + auto func = make_unique(); + func->matchers.push_back(make_unique()); + func->matchers.push_back(make_unique()); + func->policy = SetMatcher::Policy::ORDERED; + // we match on LIKE ("~~") and NOT LIKE ("!~~") + func->function = make_unique(unordered_set {"!~~", "~~"}); + root = move(func); +} + +static bool PatternIsConstant(const string &pattern) { + for (idx_t i = 0; i < pattern.size(); i++) { + if (pattern[i] == '%' || pattern[i] == '_') { + return false; + } + } + return true; +} + +static bool PatternIsPrefix(const string &pattern) { + idx_t i; + for (i = pattern.size(); i > 0; i--) { + if (pattern[i - 1] != '%') { + break; + } + } + if (i == pattern.size()) { + // no trailing % + // cannot be a prefix + return false; + } + // continue to look in the string + // if there is a % or _ in the string (besides at the very end) this is not a prefix match + for (; i > 0; i--) { + if (pattern[i - 1] == '%' || pattern[i - 1] == '_') { + return false; + } + } + return true; +} + +static bool PatternIsSuffix(const string &pattern) { + idx_t i; + for (i = 0; i < pattern.size(); i++) { + if (pattern[i] != '%') { + break; + } + } + if (i == 0) { + // no leading % + // cannot be a suffix + return false; + } + // continue to look in the string + // if there is a % or _ in the string (besides at the beginning) this is not a suffix match + for (; i < pattern.size(); i++) { + if (pattern[i] == '%' || pattern[i] == '_') { + return false; + } + } + return true; +} + +static bool PatternIsContains(const string &pattern) { + idx_t start; + idx_t end; + for (start = 0; start < pattern.size(); start++) { + if (pattern[start] != '%') { + break; + } + } + for (end = pattern.size(); end > 0; end--) { + if (pattern[end - 1] != '%') { + break; + } + } + if (start == 0 || end == pattern.size()) { + // contains requires both a leading AND a trailing % + return false; + } + // check if there are any other special characters in the string + // if there is a % or _ in the string (besides at the beginning/end) this is not a contains match + for (idx_t i = start; i < end; i++) { + if (pattern[i] == '%' || pattern[i] == '_') { + return false; + } + } + return true; +} + +unique_ptr LikeOptimizationRule::Apply(LogicalOperator &op, vector &bindings, + bool &changes_made, bool is_root) { + auto root = (BoundFunctionExpression *)bindings[0]; + auto constant_expr = (BoundConstantExpression *)bindings[2]; + D_ASSERT(root->children.size() == 2); + + if (constant_expr->value.IsNull()) { + return make_unique(Value(root->return_type)); + } + + // the constant_expr is a scalar expression that we have to fold + if (!constant_expr->IsFoldable()) { + return nullptr; + } + + auto constant_value = ExpressionExecutor::EvaluateScalar(*constant_expr); + D_ASSERT(constant_value.type() == constant_expr->return_type); + auto &patt_str = StringValue::Get(constant_value); + + bool is_not_like = root->function.name == "!~~"; + if (PatternIsConstant(patt_str)) { + // Pattern is constant + return make_unique(is_not_like ? ExpressionType::COMPARE_NOTEQUAL + : ExpressionType::COMPARE_EQUAL, + move(root->children[0]), move(root->children[1])); + } else if (PatternIsPrefix(patt_str)) { + // Prefix LIKE pattern : [^%_]*[%]+, ignoring underscore + return ApplyRule(root, PrefixFun::GetFunction(), patt_str, is_not_like); + } else if (PatternIsSuffix(patt_str)) { + // Suffix LIKE pattern: [%]+[^%_]*, ignoring underscore + return ApplyRule(root, SuffixFun::GetFunction(), patt_str, is_not_like); + } else if (PatternIsContains(patt_str)) { + // Contains LIKE pattern: [%]+[^%_]*[%]+, ignoring underscore + return ApplyRule(root, ContainsFun::GetFunction(), patt_str, is_not_like); + } + return nullptr; +} + +unique_ptr LikeOptimizationRule::ApplyRule(BoundFunctionExpression *expr, ScalarFunction function, + 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); + + // removing "%" from the pattern + pattern.erase(std::remove(pattern.begin(), pattern.end(), '%'), pattern.end()); + + new_function->children[1] = make_unique(Value(move(pattern))); + + result = 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); + } + + return result; +} + +} // namespace duckdb + + + + + + + + + +namespace duckdb { + +MoveConstantsRule::MoveConstantsRule(ExpressionRewriter &rewriter) : Rule(rewriter) { + auto op = make_unique(); + op->matchers.push_back(make_unique()); + op->policy = SetMatcher::Policy::UNORDERED; + + auto arithmetic = make_unique(); + // we handle multiplication, addition and subtraction because those are "easy" + // integer division makes the division case difficult + // e.g. [x / 2 = 3] means [x = 6 OR x = 7] because of truncation -> no clean rewrite rules + arithmetic->function = make_unique(unordered_set {"+", "-", "*"}); + // we match only on integral numeric types + arithmetic->type = make_unique(); + 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); +} + +unique_ptr MoveConstantsRule::Apply(LogicalOperator &op, vector &bindings, bool &changes_made, + bool is_root) { + auto comparison = (BoundComparisonExpression *)bindings[0]; + auto outer_constant = (BoundConstantExpression *)bindings[1]; + auto arithmetic = (BoundFunctionExpression *)bindings[2]; + auto inner_constant = (BoundConstantExpression *)bindings[3]; + if (!TypeIsIntegral(arithmetic->return_type.InternalType())) { + return nullptr; + } + if (inner_constant->value.IsNull() || outer_constant->value.IsNull()) { + return make_unique(Value(comparison->return_type)); + } + auto &constant_type = outer_constant->return_type; + hugeint_t outer_value = IntegralValue::Get(outer_constant->value); + hugeint_t inner_value = IntegralValue::Get(inner_constant->value); + + idx_t arithmetic_child_index = arithmetic->children[0].get() == inner_constant ? 1 : 0; + auto &op_type = arithmetic->function.name; + if (op_type == "+") { + // [x + 1 COMP 10] OR [1 + x COMP 10] + // order does not matter in addition: + // simply change right side to 10-1 (outer_constant - inner_constant) + if (!Hugeint::SubtractInPlace(outer_value, inner_value)) { + return nullptr; + } + auto result_value = Value::HUGEINT(outer_value); + if (!result_value.TryCastAs(constant_type)) { + // if the cast is not possible then the comparison is not possible + // for example, if we have x + 5 = 3, where x is an unsigned number, we will get x = -2 + // since this is not possible we can remove the entire branch here + return ExpressionRewriter::ConstantOrNull(move(arithmetic->children[arithmetic_child_index]), + Value::BOOLEAN(false)); + } + outer_constant->value = move(result_value); + } else if (op_type == "-") { + // [x - 1 COMP 10] O R [1 - x COMP 10] + // order matters in subtraction: + if (arithmetic_child_index == 0) { + // [x - 1 COMP 10] + // change right side to 10+1 (outer_constant + inner_constant) + if (!Hugeint::AddInPlace(outer_value, inner_value)) { + return nullptr; + } + auto result_value = Value::HUGEINT(outer_value); + if (!result_value.TryCastAs(constant_type)) { + // if the cast is not possible then the comparison is not possible + return ExpressionRewriter::ConstantOrNull(move(arithmetic->children[arithmetic_child_index]), + Value::BOOLEAN(false)); + } + outer_constant->value = move(result_value); + } else { + // [1 - x COMP 10] + // change right side to 1-10=-9 + if (!Hugeint::SubtractInPlace(inner_value, outer_value)) { + return nullptr; + } + auto result_value = Value::HUGEINT(inner_value); + if (!result_value.TryCastAs(constant_type)) { + // if the cast is not possible then the comparison is not possible + return ExpressionRewriter::ConstantOrNull(move(arithmetic->children[arithmetic_child_index]), + Value::BOOLEAN(false)); + } + outer_constant->value = 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); + } + } else { + D_ASSERT(op_type == "*"); + // [x * 2 COMP 10] OR [2 * x COMP 10] + // order does not matter in multiplication: + // change right side to 10/2 (outer_constant / inner_constant) + // but ONLY if outer_constant is cleanly divisible by the inner_constant + if (inner_value == 0) { + // x * 0, the result is either 0 or NULL + // we let the arithmetic_simplification rule take care of simplifying this first + return nullptr; + } + if (outer_value % inner_value != 0) { + // not cleanly divisible + bool is_equality = comparison->type == ExpressionType::COMPARE_EQUAL; + bool is_inequality = comparison->type == ExpressionType::COMPARE_NOTEQUAL; + if (is_equality || is_inequality) { + // we know the values are not equal + // the result will be either FALSE or NULL (if COMPARE_EQUAL) + // or TRUE or NULL (if COMPARE_NOTEQUAL) + return ExpressionRewriter::ConstantOrNull(move(arithmetic->children[arithmetic_child_index]), + Value::BOOLEAN(is_inequality)); + } else { + // not cleanly divisible and we are doing > >= < <=, skip the simplification for now + return nullptr; + } + } + if (inner_value < 0) { + // multiply by negative value, need to flip expression + comparison->type = FlipComparisionExpression(comparison->type); + } + // else divide the RHS by the LHS + // we need to do a range check on the cast even though we do a division + // because e.g. -128 / -1 = 128, which is out of range + auto result_value = Value::HUGEINT(outer_value / inner_value); + if (!result_value.TryCastAs(constant_type)) { + return ExpressionRewriter::ConstantOrNull(move(arithmetic->children[arithmetic_child_index]), + Value::BOOLEAN(false)); + } + outer_constant->value = move(result_value); + } + // replace left side with x + // first extract x from the arithmetic expression + auto arithmetic_child = move(arithmetic->children[arithmetic_child_index]); + // then place in the comparison + if (comparison->left.get() == outer_constant) { + comparison->right = move(arithmetic_child); + } else { + comparison->left = move(arithmetic_child); + } + changes_made = true; + return nullptr; +} + +} // namespace duckdb + + + +namespace duckdb { + +unique_ptr StatisticsPropagator::PropagateExpression(BoundAggregateExpression &aggr, + unique_ptr *expr_ptr) { + vector> stats; + stats.reserve(aggr.children.size()); + for (auto &child : aggr.children) { + stats.push_back(PropagateExpression(child)); + } + if (!aggr.function.statistics) { + return nullptr; + } + return aggr.function.statistics(context, aggr, aggr.bind_info.get(), stats, node_stats.get()); +} + +} // namespace duckdb + + + + + + + + + +namespace duckdb { + +unique_ptr CastHugeintToSmallestType(unique_ptr expr, NumericStatistics &num_stats) { + // Compute range + if (num_stats.min.IsNull() || num_stats.max.IsNull()) { + return expr; + } + + auto min_val = num_stats.min.GetValue(); + auto max_val = num_stats.max.GetValue(); + if (max_val < min_val) { + return expr; + } + + // Prevent overflow + if (min_val < NumericLimits().Minimum() && max_val > NumericLimits().Maximum()) { + return expr; + } + + // Compute range + auto range = max_val - min_val; + + // Check if this range fits in a smaller type + LogicalType cast_type; + if (range < NumericLimits().Maximum()) { + cast_type = LogicalType::UTINYINT; + } else if (range < NumericLimits().Maximum()) { + cast_type = LogicalType::USMALLINT; + } else if (range < NumericLimits().Maximum()) { + cast_type = LogicalType::UINTEGER; + } else if (range < NumericLimits().Maximum()) { + cast_type = LogicalTypeId::UBIGINT; + } else { + return expr; + } + + // Create expression to map to a smaller range + auto input_type = expr->return_type; + auto minimum_expr = make_unique(Value::CreateValue(min_val)); + vector> arguments; + arguments.push_back(move(expr)); + arguments.push_back(move(minimum_expr)); + auto minus_expr = make_unique(input_type, SubtractFun::GetFunction(input_type, input_type), + move(arguments), nullptr, true); + + // Cast to smaller type + return make_unique(move(minus_expr), cast_type); +} + +template +unique_ptr TemplatedCastToSmallestType(unique_ptr expr, NumericStatistics &num_stats) { + // Compute range + if (num_stats.min.IsNull() || num_stats.max.IsNull()) { + return expr; + } + + auto signed_min_val = num_stats.min.GetValue(); + auto signed_max_val = num_stats.max.GetValue(); + if (signed_max_val < signed_min_val) { + return expr; + } + + // Prevent signed integer overflow - we can't range map these + if (std::is_signed() && signed_min_val < -((T)1 << (sizeof(T) * 8 - 2)) && + signed_max_val > ((T)1 << (sizeof(T) * 8 - 2))) { + return expr; + } + + // Compute range, cast to unsigned to prevent comparing signed with unsigned + auto signed_range = signed_max_val - signed_min_val; + auto range = static_cast::type>(signed_range); + + // Check if this range fits in a smaller type + LogicalType cast_type; + if (range < NumericLimits().Maximum()) { + cast_type = LogicalType::UTINYINT; + } else if (sizeof(T) > sizeof(uint16_t) && range < NumericLimits().Maximum()) { + cast_type = LogicalType::USMALLINT; + } else if (sizeof(T) > sizeof(uint32_t) && range < NumericLimits().Maximum()) { + cast_type = LogicalType::UINTEGER; + } else { + return expr; + } + + // Create expression to map to a smaller range + 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)); + auto minus_expr = make_unique(input_type, SubtractFun::GetFunction(input_type, input_type), + move(arguments), nullptr, true); + + // Cast to smaller type + return make_unique(move(minus_expr), cast_type); +} + +unique_ptr CastToSmallestType(unique_ptr expr, NumericStatistics &num_stats) { + auto physical_type = expr->return_type.InternalType(); + switch (physical_type) { + case PhysicalType::UINT8: + case PhysicalType::INT8: + return expr; + case PhysicalType::UINT16: + return TemplatedCastToSmallestType(move(expr), num_stats); + case PhysicalType::INT16: + return TemplatedCastToSmallestType(move(expr), num_stats); + case PhysicalType::UINT32: + return TemplatedCastToSmallestType(move(expr), num_stats); + case PhysicalType::INT32: + return TemplatedCastToSmallestType(move(expr), num_stats); + case PhysicalType::UINT64: + return TemplatedCastToSmallestType(move(expr), num_stats); + case PhysicalType::INT64: + return TemplatedCastToSmallestType(move(expr), num_stats); + case PhysicalType::INT128: + return CastHugeintToSmallestType(move(expr), num_stats); + default: + throw NotImplementedException("Unknown integer type!"); + } +} + +void StatisticsPropagator::PropagateAndCompress(unique_ptr &expr, unique_ptr &stats) { + stats = PropagateExpression(expr); + if (stats) { + if (expr->return_type.IsIntegral()) { + expr = CastToSmallestType(move(expr), (NumericStatistics &)*stats); + } + } +} + +} // namespace duckdb + + + + + + +namespace duckdb { + +unique_ptr StatisticsPropagator::PropagateExpression(BoundBetweenExpression &between, + unique_ptr *expr_ptr) { + // propagate in all the children + auto input_stats = PropagateExpression(between.input); + auto lower_stats = PropagateExpression(between.lower); + auto upper_stats = PropagateExpression(between.upper); + if (!input_stats) { + return nullptr; + } + auto lower_comparison = between.LowerComparisonType(); + auto upper_comparison = between.UpperComparisonType(); + // propagate the comparisons + auto lower_prune = FilterPropagateResult::NO_PRUNING_POSSIBLE; + auto upper_prune = FilterPropagateResult::NO_PRUNING_POSSIBLE; + if (lower_stats) { + lower_prune = PropagateComparison(*input_stats, *lower_stats, lower_comparison); + } + if (upper_stats) { + upper_prune = PropagateComparison(*input_stats, *upper_stats, upper_comparison); + } + if (lower_prune == FilterPropagateResult::FILTER_ALWAYS_TRUE && + upper_prune == FilterPropagateResult::FILTER_ALWAYS_TRUE) { + // both filters are always true: replace the between expression with a constant true + *expr_ptr = make_unique(Value::BOOLEAN(true)); + } else if (lower_prune == FilterPropagateResult::FILTER_ALWAYS_FALSE || + upper_prune == FilterPropagateResult::FILTER_ALWAYS_FALSE) { + // either one of the filters is always false: replace the between expression with a constant false + *expr_ptr = make_unique(Value::BOOLEAN(false)); + } else if (lower_prune == FilterPropagateResult::FILTER_FALSE_OR_NULL || + 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)); + } 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)); + } 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)); + } 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)); + } + return nullptr; +} + +} // namespace duckdb + + + +namespace duckdb { + +unique_ptr StatisticsPropagator::PropagateExpression(BoundCaseExpression &bound_case, + unique_ptr *expr_ptr) { + // propagate in all the children + auto result_stats = PropagateExpression(bound_case.else_expr); + for (auto &case_check : bound_case.case_checks) { + PropagateExpression(case_check.when_expr); + auto then_stats = PropagateExpression(case_check.then_expr); + if (!then_stats) { + result_stats.reset(); + } else if (result_stats) { + result_stats->Merge(*then_stats); + } + } + return result_stats; +} + +} // namespace duckdb + + + + +namespace duckdb { + +static unique_ptr StatisticsOperationsNumericNumericCast(const BaseStatistics *input_p, + const LogicalType &target) { + auto &input = (NumericStatistics &)*input_p; + + Value min = input.min, max = input.max; + if (!min.TryCastAs(target) || !max.TryCastAs(target)) { + // overflow in cast: bailout + return nullptr; + } + auto stats = make_unique(target, move(min), move(max)); + if (input.validity_stats) { + stats->validity_stats = input.validity_stats->Copy(); + } + return move(stats); +} + +static unique_ptr StatisticsNumericCastSwitch(const BaseStatistics *input, const LogicalType &target) { + switch (target.InternalType()) { + case PhysicalType::INT8: + case PhysicalType::INT16: + case PhysicalType::INT32: + case PhysicalType::INT64: + case PhysicalType::INT128: + case PhysicalType::FLOAT: + case PhysicalType::DOUBLE: + return StatisticsOperationsNumericNumericCast(input, target); + default: + return nullptr; + } +} + +unique_ptr StatisticsPropagator::PropagateExpression(BoundCastExpression &cast, + unique_ptr *expr_ptr) { + auto child_stats = PropagateExpression(cast.child); + if (!child_stats) { + return nullptr; + } + unique_ptr result_stats; + switch (cast.child->return_type.InternalType()) { + case PhysicalType::INT8: + case PhysicalType::INT16: + case PhysicalType::INT32: + case PhysicalType::INT64: + case PhysicalType::INT128: + case PhysicalType::FLOAT: + case PhysicalType::DOUBLE: + result_stats = StatisticsNumericCastSwitch(child_stats.get(), cast.return_type); + break; + default: + return nullptr; + } + if (cast.try_cast && result_stats) { + result_stats->validity_stats = make_unique(true, true); + } + return result_stats; +} + +} // namespace duckdb + + + +namespace duckdb { + +unique_ptr StatisticsPropagator::PropagateExpression(BoundColumnRefExpression &colref, + unique_ptr *expr_ptr) { + auto stats = statistics_map.find(colref.binding); + if (stats == statistics_map.end()) { + return nullptr; + } + return stats->second->Copy(); +} + +} // namespace duckdb + + + + + + +namespace duckdb { + +FilterPropagateResult StatisticsPropagator::PropagateComparison(BaseStatistics &left, BaseStatistics &right, + ExpressionType comparison) { + // only handle numerics for now + switch (left.type.InternalType()) { + case PhysicalType::BOOL: + case PhysicalType::UINT8: + case PhysicalType::UINT16: + case PhysicalType::UINT32: + case PhysicalType::UINT64: + case PhysicalType::INT8: + case PhysicalType::INT16: + case PhysicalType::INT32: + case PhysicalType::INT64: + case PhysicalType::INT128: + case PhysicalType::FLOAT: + case PhysicalType::DOUBLE: + break; + default: + return FilterPropagateResult::NO_PRUNING_POSSIBLE; + } + auto &lstats = (NumericStatistics &)left; + auto &rstats = (NumericStatistics &)right; + if (lstats.min.IsNull() || lstats.max.IsNull() || rstats.min.IsNull() || rstats.max.IsNull()) { + // no stats available: nothing to prune + return FilterPropagateResult::NO_PRUNING_POSSIBLE; + } + // the result of the propagation depend on whether or not either side has null values + // if there are null values present, we cannot say whether or not + bool has_null = lstats.CanHaveNull() || rstats.CanHaveNull(); + switch (comparison) { + case ExpressionType::COMPARE_EQUAL: + // l = r, if l.min > r.max or r.min > l.max equality is not possible + if (lstats.min > rstats.max || rstats.min > lstats.max) { + return has_null ? FilterPropagateResult::FILTER_FALSE_OR_NULL : FilterPropagateResult::FILTER_ALWAYS_FALSE; + } else { + return FilterPropagateResult::NO_PRUNING_POSSIBLE; + } + case ExpressionType::COMPARE_GREATERTHAN: + // l > r + if (lstats.min > rstats.max) { + // if l.min > r.max, it is always true ONLY if neither side contains nulls + return has_null ? FilterPropagateResult::FILTER_TRUE_OR_NULL : FilterPropagateResult::FILTER_ALWAYS_TRUE; + } + // if r.min is bigger or equal to l.max, the filter is always false + if (rstats.min >= lstats.max) { + return has_null ? FilterPropagateResult::FILTER_FALSE_OR_NULL : FilterPropagateResult::FILTER_ALWAYS_FALSE; + } + return FilterPropagateResult::NO_PRUNING_POSSIBLE; + case ExpressionType::COMPARE_GREATERTHANOREQUALTO: + // l >= r + if (lstats.min >= rstats.max) { + // if l.min >= r.max, it is always true ONLY if neither side contains nulls + return has_null ? FilterPropagateResult::FILTER_TRUE_OR_NULL : FilterPropagateResult::FILTER_ALWAYS_TRUE; + } + // if r.min > l.max, the filter is always false + if (rstats.min > lstats.max) { + return has_null ? FilterPropagateResult::FILTER_FALSE_OR_NULL : FilterPropagateResult::FILTER_ALWAYS_FALSE; + } + return FilterPropagateResult::NO_PRUNING_POSSIBLE; + case ExpressionType::COMPARE_LESSTHAN: + // l < r + if (lstats.max < rstats.min) { + // if l.max < r.min, it is always true ONLY if neither side contains nulls + return has_null ? FilterPropagateResult::FILTER_TRUE_OR_NULL : FilterPropagateResult::FILTER_ALWAYS_TRUE; + } + // if l.min >= rstats.max, the filter is always false + if (lstats.min >= rstats.max) { + return has_null ? FilterPropagateResult::FILTER_FALSE_OR_NULL : FilterPropagateResult::FILTER_ALWAYS_FALSE; + } + return FilterPropagateResult::NO_PRUNING_POSSIBLE; + case ExpressionType::COMPARE_LESSTHANOREQUALTO: + // l <= r + if (lstats.max <= rstats.min) { + // if l.max <= r.min, it is always true ONLY if neither side contains nulls + return has_null ? FilterPropagateResult::FILTER_TRUE_OR_NULL : FilterPropagateResult::FILTER_ALWAYS_TRUE; + } + // if l.min > rstats.max, the filter is always false + if (lstats.min > rstats.max) { + return has_null ? FilterPropagateResult::FILTER_FALSE_OR_NULL : FilterPropagateResult::FILTER_ALWAYS_FALSE; + } + return FilterPropagateResult::NO_PRUNING_POSSIBLE; + default: + return FilterPropagateResult::NO_PRUNING_POSSIBLE; + } +} + +unique_ptr StatisticsPropagator::PropagateExpression(BoundComparisonExpression &expr, + unique_ptr *expr_ptr) { + auto left_stats = PropagateExpression(expr.left); + auto right_stats = PropagateExpression(expr.right); + if (!left_stats || !right_stats) { + return nullptr; + } + // propagate the statistics of the comparison operator + auto propagate_result = PropagateComparison(*left_stats, *right_stats, expr.type); + switch (propagate_result) { + case FilterPropagateResult::FILTER_ALWAYS_TRUE: + *expr_ptr = make_unique(Value::BOOLEAN(true)); + return PropagateExpression(*expr_ptr); + case FilterPropagateResult::FILTER_ALWAYS_FALSE: + *expr_ptr = make_unique(Value::BOOLEAN(false)); + 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)); + 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)); + return nullptr; + } + default: + // FIXME: we can propagate nulls here, i.e. this expression will have nulls only if left and right has nulls + return nullptr; + } +} + +} // namespace duckdb + + + + + + + + +namespace duckdb { + +unique_ptr StatisticsPropagator::StatisticsFromValue(const Value &input) { + switch (input.type().InternalType()) { + case PhysicalType::BOOL: + case PhysicalType::UINT8: + case PhysicalType::UINT16: + case PhysicalType::UINT32: + case PhysicalType::UINT64: + case PhysicalType::INT8: + case PhysicalType::INT16: + case PhysicalType::INT32: + case PhysicalType::INT64: + case PhysicalType::INT128: + case PhysicalType::FLOAT: + case PhysicalType::DOUBLE: { + auto result = make_unique(input.type(), input, input); + result->validity_stats = make_unique(input.IsNull(), !input.IsNull()); + return move(result); + } + case PhysicalType::VARCHAR: { + auto result = make_unique(input.type()); + result->validity_stats = make_unique(input.IsNull(), !input.IsNull()); + if (!input.IsNull()) { + auto &string_value = StringValue::Get(input); + result->Update(string_t(string_value)); + } + return move(result); + } + case PhysicalType::STRUCT: { + auto result = make_unique(input.type()); + result->validity_stats = make_unique(input.IsNull(), !input.IsNull()); + if (input.IsNull()) { + for (auto &child_stat : result->child_stats) { + child_stat.reset(); + } + } else { + auto &struct_children = StructValue::GetChildren(input); + D_ASSERT(result->child_stats.size() == struct_children.size()); + for (idx_t i = 0; i < result->child_stats.size(); i++) { + result->child_stats[i] = StatisticsFromValue(struct_children[i]); + } + } + return move(result); + } + case PhysicalType::LIST: { + auto result = make_unique(input.type()); + result->validity_stats = make_unique(input.IsNull(), !input.IsNull()); + if (input.IsNull()) { + result->child_stats.reset(); + } else { + auto &list_children = ListValue::GetChildren(input); + for (auto &child_element : list_children) { + auto child_element_stats = StatisticsFromValue(child_element); + if (child_element_stats) { + result->child_stats->Merge(*child_element_stats); + } else { + result->child_stats.reset(); + } + } + } + return move(result); + } + default: + return nullptr; + } +} + +unique_ptr StatisticsPropagator::PropagateExpression(BoundConstantExpression &constant, + unique_ptr *expr_ptr) { + return StatisticsFromValue(constant.value); +} + +} // namespace duckdb + + + +namespace duckdb { + +unique_ptr StatisticsPropagator::PropagateExpression(BoundFunctionExpression &func, + unique_ptr *expr_ptr) { + vector> stats; + stats.reserve(func.children.size()); + for (idx_t i = 0; i < func.children.size(); i++) { + stats.push_back(PropagateExpression(func.children[i])); + } + if (!func.function.statistics) { + return nullptr; + } + return func.function.statistics(context, func, func.bind_info.get(), stats); +} + +} // namespace duckdb + + + + +namespace duckdb { + +unique_ptr StatisticsPropagator::PropagateExpression(BoundOperatorExpression &expr, + unique_ptr *expr_ptr) { + bool all_have_stats = true; + vector> child_stats; + child_stats.reserve(expr.children.size()); + for (auto &child : expr.children) { + auto stats = PropagateExpression(child); + if (!stats) { + all_have_stats = false; + } + child_stats.push_back(move(stats)); + } + if (!all_have_stats) { + return nullptr; + } + switch (expr.type) { + case ExpressionType::OPERATOR_COALESCE: + // COALESCE, merge stats of all children + for (idx_t i = 0; i < expr.children.size(); i++) { + D_ASSERT(child_stats[i]); + if (!child_stats[i]->CanHaveNoNull()) { + // this child is always NULL, we can remove it from the coalesce + // UNLESS there is only one node remaining + if (expr.children.size() > 1) { + expr.children.erase(expr.children.begin() + i); + child_stats.erase(child_stats.begin() + i); + i--; + } + } else if (!child_stats[i]->CanHaveNull()) { + // coalesce child cannot have NULL entries + // this is the last coalesce node that influences the result + // we can erase any children after this node + if (i + 1 < expr.children.size()) { + expr.children.erase(expr.children.begin() + i + 1, expr.children.end()); + child_stats.erase(child_stats.begin() + i + 1, child_stats.end()); + } + break; + } + } + D_ASSERT(!expr.children.empty()); + 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]); + } else { + // coalesce of multiple entries + // merge the stats + for (idx_t i = 1; i < expr.children.size(); i++) { + child_stats[0]->Merge(*child_stats[i]); + } + } + return 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 + *expr_ptr = make_unique(Value::BOOLEAN(false)); + return PropagateExpression(*expr_ptr); + } + return nullptr; + case ExpressionType::OPERATOR_IS_NOT_NULL: + if (!child_stats[0]->CanHaveNull()) { + // child has no null values: x IS NOT NULL will always be true + *expr_ptr = make_unique(Value::BOOLEAN(true)); + return PropagateExpression(*expr_ptr); + } + return nullptr; + default: + return nullptr; + } +} + +} // namespace duckdb + + + + +namespace duckdb { + +unique_ptr StatisticsPropagator::PropagateStatistics(LogicalAggregate &aggr, + unique_ptr *node_ptr) { + // first propagate statistics in the child node + node_stats = PropagateStatistics(aggr.children[0]); + + // handle the groups: simply propagate statistics and assign the stats to the group binding + aggr.group_stats.resize(aggr.groups.size()); + for (idx_t group_idx = 0; group_idx < aggr.groups.size(); group_idx++) { + auto stats = PropagateExpression(aggr.groups[group_idx]); + aggr.group_stats[group_idx] = stats ? stats->Copy() : nullptr; + if (!stats) { + continue; + } + if (aggr.grouping_sets.size() > 1) { + // aggregates with multiple grouping sets can introduce NULL values to certain groups + // FIXME: actually figure out WHICH groups can have null values introduced + stats->validity_stats = make_unique(true, true); + continue; + } + ColumnBinding group_binding(aggr.group_index, group_idx); + statistics_map[group_binding] = move(stats); + } + // propagate statistics in the aggregates + for (idx_t aggregate_idx = 0; aggregate_idx < aggr.expressions.size(); aggregate_idx++) { + auto stats = PropagateExpression(aggr.expressions[aggregate_idx]); + if (!stats) { + continue; + } + ColumnBinding aggregate_binding(aggr.aggregate_index, aggregate_idx); + statistics_map[aggregate_binding] = 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); +} + +} // namespace duckdb + + + +namespace duckdb { + +unique_ptr StatisticsPropagator::PropagateStatistics(LogicalCrossProduct &cp, + unique_ptr *node_ptr) { + // first propagate statistics in the child node + auto left_stats = PropagateStatistics(cp.children[0]); + auto right_stats = PropagateStatistics(cp.children[1]); + if (!left_stats || !right_stats) { + return nullptr; + } + MultiplyCardinalities(left_stats, *right_stats); + return left_stats; +} + +} // namespace duckdb + + + + + + + + + +namespace duckdb { + +static bool IsCompareDistinct(ExpressionType type) { + return type == ExpressionType::COMPARE_DISTINCT_FROM || type == ExpressionType::COMPARE_NOT_DISTINCT_FROM; +} + +bool StatisticsPropagator::ExpressionIsConstant(Expression &expr, const Value &val) { + if (expr.GetExpressionClass() != ExpressionClass::BOUND_CONSTANT) { + return false; + } + auto &bound_constant = (BoundConstantExpression &)expr; + D_ASSERT(bound_constant.value.type() == val.type()); + return bound_constant.value == val; +} + +bool StatisticsPropagator::ExpressionIsConstantOrNull(Expression &expr, const Value &val) { + if (expr.GetExpressionClass() != ExpressionClass::BOUND_FUNCTION) { + return false; + } + auto &bound_function = (BoundFunctionExpression &)expr; + return ConstantOrNull::IsConstantOrNull(bound_function, val); +} + +void StatisticsPropagator::SetStatisticsNotNull(ColumnBinding binding) { + auto entry = statistics_map.find(binding); + if (entry == statistics_map.end()) { + return; + } + entry->second->validity_stats = make_unique(false); +} + +void StatisticsPropagator::UpdateFilterStatistics(BaseStatistics &stats, ExpressionType comparison_type, + const Value &constant) { + // regular comparisons removes all null values + if (!IsCompareDistinct(comparison_type)) { + stats.validity_stats = make_unique(false); + } + if (!stats.type.IsNumeric()) { + // don't handle non-numeric columns here (yet) + return; + } + auto &numeric_stats = (NumericStatistics &)stats; + if (numeric_stats.min.IsNull() || numeric_stats.max.IsNull()) { + // no stats available: skip this + return; + } + switch (comparison_type) { + case ExpressionType::COMPARE_LESSTHAN: + case ExpressionType::COMPARE_LESSTHANOREQUALTO: + // X < constant OR X <= constant + // max becomes the constant + numeric_stats.max = constant; + break; + case ExpressionType::COMPARE_GREATERTHAN: + case ExpressionType::COMPARE_GREATERTHANOREQUALTO: + // X > constant OR X >= constant + // min becomes the constant + numeric_stats.min = constant; + break; + case ExpressionType::COMPARE_EQUAL: + // X = constant + // both min and max become the constant + numeric_stats.min = constant; + numeric_stats.max = constant; + break; + default: + break; + } +} + +void StatisticsPropagator::UpdateFilterStatistics(BaseStatistics &lstats, BaseStatistics &rstats, + ExpressionType comparison_type) { + // regular comparisons removes all null values + if (!IsCompareDistinct(comparison_type)) { + lstats.validity_stats = make_unique(false); + rstats.validity_stats = make_unique(false); + } + D_ASSERT(lstats.type == rstats.type); + if (!lstats.type.IsNumeric()) { + // don't handle non-numeric columns here (yet) + return; + } + auto &left_stats = (NumericStatistics &)lstats; + auto &right_stats = (NumericStatistics &)rstats; + if (left_stats.min.IsNull() || left_stats.max.IsNull() || right_stats.min.IsNull() || right_stats.max.IsNull()) { + // no stats available: skip this + return; + } + switch (comparison_type) { + case ExpressionType::COMPARE_LESSTHAN: + case ExpressionType::COMPARE_LESSTHANOREQUALTO: + // LEFT < RIGHT OR LEFT <= RIGHT + // we know that every value of left is smaller (or equal to) every value in right + // i.e. if we have left = [-50, 250] and right = [-100, 100] + + // we know that left.max is AT MOST equal to right.max + // because any value in left that is BIGGER than right.max will not pass the filter + if (left_stats.max > right_stats.max) { + left_stats.max = right_stats.max; + } + + // we also know that right.min is AT MOST equal to left.min + // because any value in right that is SMALLER than left.min will not pass the filter + if (right_stats.min < left_stats.min) { + right_stats.min = left_stats.min; + } + // so in our example, the bounds get updated as follows: + // left: [-50, 100], right: [-50, 100] + break; + case ExpressionType::COMPARE_GREATERTHAN: + case ExpressionType::COMPARE_GREATERTHANOREQUALTO: + // LEFT > RIGHT OR LEFT >= RIGHT + // we know that every value of left is bigger (or equal to) every value in right + // this is essentially the inverse of the less than (or equal to) scenario + if (right_stats.max > left_stats.max) { + right_stats.max = left_stats.max; + } + if (left_stats.min < right_stats.min) { + left_stats.min = right_stats.min; + } + break; + case ExpressionType::COMPARE_EQUAL: + case ExpressionType::COMPARE_NOT_DISTINCT_FROM: + // LEFT = RIGHT + // only the tightest bounds pass + // so if we have e.g. left = [-50, 250] and right = [-100, 100] + // the tighest bounds are [-50, 100] + // select the highest min + if (left_stats.min > right_stats.min) { + right_stats.min = left_stats.min; + } else { + left_stats.min = right_stats.min; + } + // select the lowest max + if (left_stats.max < right_stats.max) { + right_stats.max = left_stats.max; + } else { + left_stats.max = right_stats.max; + } + break; + default: + break; + } +} + +void StatisticsPropagator::UpdateFilterStatistics(Expression &left, Expression &right, ExpressionType comparison_type) { + // first check if either side is a bound column ref + // any column ref involved in a comparison will not be null after the comparison + bool compare_distinct = IsCompareDistinct(comparison_type); + if (!compare_distinct && left.type == ExpressionType::BOUND_COLUMN_REF) { + SetStatisticsNotNull(((BoundColumnRefExpression &)left).binding); + } + if (!compare_distinct && right.type == ExpressionType::BOUND_COLUMN_REF) { + SetStatisticsNotNull(((BoundColumnRefExpression &)right).binding); + } + // check if this is a comparison between a constant and a column ref + BoundConstantExpression *constant = nullptr; + BoundColumnRefExpression *columnref = nullptr; + if (left.type == ExpressionType::VALUE_CONSTANT && right.type == ExpressionType::BOUND_COLUMN_REF) { + constant = (BoundConstantExpression *)&left; + columnref = (BoundColumnRefExpression *)&right; + comparison_type = FlipComparisionExpression(comparison_type); + } else if (left.type == ExpressionType::BOUND_COLUMN_REF && right.type == ExpressionType::VALUE_CONSTANT) { + columnref = (BoundColumnRefExpression *)&left; + constant = (BoundConstantExpression *)&right; + } else if (left.type == ExpressionType::BOUND_COLUMN_REF && right.type == ExpressionType::BOUND_COLUMN_REF) { + // comparison between two column refs + auto &left_column_ref = (BoundColumnRefExpression &)left; + auto &right_column_ref = (BoundColumnRefExpression &)right; + auto lentry = statistics_map.find(left_column_ref.binding); + auto rentry = statistics_map.find(right_column_ref.binding); + if (lentry == statistics_map.end() || rentry == statistics_map.end()) { + return; + } + UpdateFilterStatistics(*lentry->second, *rentry->second, comparison_type); + } else { + // unsupported filter + return; + } + if (constant && columnref) { + // comparison between columnref + auto entry = statistics_map.find(columnref->binding); + if (entry == statistics_map.end()) { + return; + } + UpdateFilterStatistics(*entry->second, comparison_type, constant->value); + } +} + +void StatisticsPropagator::UpdateFilterStatistics(Expression &condition) { + // in filters, we check for constant comparisons with bound columns + // if we find a comparison in the form of e.g. "i=3", we can update our statistics for that column + switch (condition.GetExpressionClass()) { + case ExpressionClass::BOUND_BETWEEN: { + auto &between = (BoundBetweenExpression &)condition; + UpdateFilterStatistics(*between.input, *between.lower, between.LowerComparisonType()); + UpdateFilterStatistics(*between.input, *between.upper, between.UpperComparisonType()); + break; + } + case ExpressionClass::BOUND_COMPARISON: { + auto &comparison = (BoundComparisonExpression &)condition; + UpdateFilterStatistics(*comparison.left, *comparison.right, comparison.type); + break; + } + default: + break; + } +} + +unique_ptr StatisticsPropagator::PropagateStatistics(LogicalFilter &filter, + unique_ptr *node_ptr) { + // first propagate to the child + node_stats = PropagateStatistics(filter.children[0]); + if (filter.children[0]->type == LogicalOperatorType::LOGICAL_EMPTY_RESULT) { + ReplaceWithEmptyResult(*node_ptr); + return make_unique(0, 0); + } + + // then propagate to each of the expressions + for (idx_t i = 0; i < filter.expressions.size(); i++) { + auto &condition = filter.expressions[i]; + PropagateExpression(condition); + + if (ExpressionIsConstant(*condition, Value::BOOLEAN(true))) { + // filter is always true; it is useless to execute it + // erase this condition + filter.expressions.erase(filter.expressions.begin() + i); + i--; + if (filter.expressions.empty()) { + // all conditions have been erased: remove the entire filter + *node_ptr = move(filter.children[0]); + break; + } + } else if (ExpressionIsConstant(*condition, Value::BOOLEAN(false)) || + ExpressionIsConstantOrNull(*condition, Value::BOOLEAN(false))) { + // filter is always false or null; this entire filter should be replaced by an empty result block + ReplaceWithEmptyResult(*node_ptr); + return make_unique(0, 0); + } else { + // cannot prune this filter: propagate statistics from the filter + UpdateFilterStatistics(*condition); + } + } + // the max cardinality of a filter is the cardinality of the input (i.e. no tuples get filtered) + return move(node_stats); +} + +} // namespace duckdb + + + + + + +namespace duckdb { + +FilterPropagateResult StatisticsPropagator::PropagateTableFilter(BaseStatistics &stats, TableFilter &filter) { + return filter.CheckStatistics(stats); +} + +void StatisticsPropagator::UpdateFilterStatistics(BaseStatistics &input, TableFilter &filter) { + // FIXME: update stats... + switch (filter.filter_type) { + case TableFilterType::CONJUNCTION_AND: { + auto &conjunction_and = (ConjunctionAndFilter &)filter; + for (auto &child_filter : conjunction_and.child_filters) { + UpdateFilterStatistics(input, *child_filter); + } + break; + } + case TableFilterType::CONSTANT_COMPARISON: { + auto &constant_filter = (ConstantFilter &)filter; + UpdateFilterStatistics(input, constant_filter.comparison_type, constant_filter.constant); + break; + } + default: + break; + } +} + +unique_ptr StatisticsPropagator::PropagateStatistics(LogicalGet &get, + unique_ptr *node_ptr) { + if (get.function.cardinality) { + node_stats = get.function.cardinality(context, get.bind_data.get()); + } + if (!get.function.statistics) { + // no column statistics to get + return 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))); + } + } + // push table filters into the statistics + vector column_indexes; + column_indexes.reserve(get.table_filters.filters.size()); + for (auto &kv : get.table_filters.filters) { + column_indexes.push_back(kv.first); + } + + for (auto &table_filter_column : column_indexes) { + idx_t column_index; + for (column_index = 0; column_index < get.column_ids.size(); column_index++) { + if (get.column_ids[column_index] == table_filter_column) { + break; + } + } + D_ASSERT(column_index < get.column_ids.size()); + D_ASSERT(get.column_ids[column_index] == table_filter_column); + + // find the stats + ColumnBinding stats_binding(get.table_index, column_index); + auto entry = statistics_map.find(stats_binding); + if (entry == statistics_map.end()) { + // no stats for this entry + continue; + } + auto &stats = *entry->second; + + // fetch the table filter + D_ASSERT(get.table_filters.filters.count(table_filter_column) > 0); + auto &filter = get.table_filters.filters[table_filter_column]; + auto propagate_result = PropagateTableFilter(stats, *filter); + switch (propagate_result) { + case FilterPropagateResult::FILTER_ALWAYS_TRUE: + // filter is always true; it is useless to execute it + // erase this condition + get.table_filters.filters.erase(table_filter_column); + break; + case FilterPropagateResult::FILTER_FALSE_OR_NULL: + case FilterPropagateResult::FILTER_ALWAYS_FALSE: + // filter is always false; this entire filter should be replaced by an empty result block + ReplaceWithEmptyResult(*node_ptr); + return make_unique(0, 0); + default: + // general case: filter can be true or false, update this columns' statistics + UpdateFilterStatistics(stats, *filter); + break; + } + } + return move(node_stats); +} + +} // namespace duckdb + + + + + + + + + +namespace duckdb { + +void StatisticsPropagator::PropagateStatistics(LogicalComparisonJoin &join, unique_ptr *node_ptr) { + for (idx_t i = 0; i < join.conditions.size(); i++) { + auto &condition = join.conditions[i]; + auto stats_left = PropagateExpression(condition.left); + auto stats_right = PropagateExpression(condition.right); + if (stats_left && stats_right) { + if (condition.null_values_are_equal && stats_left->CanHaveNull() && stats_right->CanHaveNull()) { + // null values are equal in this join, and both sides can have null values + // nothing to do here + continue; + } + 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)); + switch (prune_result) { + case FilterPropagateResult::FILTER_FALSE_OR_NULL: + case FilterPropagateResult::FILTER_ALWAYS_FALSE: + // filter is always false or null, none of the join conditions matter + switch (join.join_type) { + case JoinType::SEMI: + case JoinType::INNER: + // semi or inner join on false; entire node can be pruned + ReplaceWithEmptyResult(*node_ptr); + return; + case JoinType::ANTI: + // anti join: replace entire join with LHS + *node_ptr = move(join.children[0]); + return; + case JoinType::LEFT: + // anti/left outer join: replace right side with empty node + ReplaceWithEmptyResult(join.children[1]); + return; + case JoinType::RIGHT: + // right outer join: replace left side with empty node + ReplaceWithEmptyResult(join.children[0]); + return; + default: + // other join types: can't do much meaningful with this information + // full outer join requires both sides anyway; we can skip the execution of the actual join, but eh + // mark/single join requires knowing if the rhs has null values or not + break; + } + break; + case FilterPropagateResult::FILTER_ALWAYS_TRUE: + // filter is always true + if (join.conditions.size() > 1) { + // there are multiple conditions: erase this condition + join.conditions.erase(join.conditions.begin() + i); + i--; + continue; + } else { + // this is the only condition and it is always true: all conditions are true + switch (join.join_type) { + case JoinType::SEMI: + // semi join on true: replace entire join with LHS + *node_ptr = move(join.children[0]); + return; + case JoinType::INNER: + case JoinType::LEFT: + case JoinType::RIGHT: + case JoinType::OUTER: { + // 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 = make_unique(); + cross_product->children = move(join.children); + *node_ptr = move(cross_product); + return; + } + case JoinType::ANTI: + // anti join on true: empty result + ReplaceWithEmptyResult(*node_ptr); + return; + default: + // we don't handle mark/single join here yet + break; + } + } + break; + default: + break; + } + } + // after we have propagated, we can update the statistics on both sides + // note that it is fine to do this now, even if the same column is used again later + // e.g. if we have i=j AND i=k, and the stats for j and k are disjoint, we know there are no results + // so if we have e.g. i: [0, 100], j: [0, 25], k: [75, 100] + // we can set i: [0, 25] after the first comparison, and statically determine that the second comparison is fals + + // note that we can't update statistics the same for all join types + // mark and single joins don't filter any tuples -> so there is no propagation possible + // anti joins have inverse statistics propagation + // (i.e. if we have an anti join on i: [0, 100] and j: [0, 25], the resulting stats are i:[25,100]) + // for now we don't handle anti joins + if (condition.null_values_are_equal) { + // skip update when null values are equal (for now?) + continue; + } + switch (join.join_type) { + case JoinType::INNER: + case JoinType::SEMI: { + UpdateFilterStatistics(*condition.left, *condition.right, condition.comparison); + auto stats_left = PropagateExpression(condition.left); + 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); + } + break; + } + default: + break; + } + } +} + +void StatisticsPropagator::PropagateStatistics(LogicalAnyJoin &join, unique_ptr *node_ptr) { + // propagate the expression into the join condition + PropagateExpression(join.condition); +} + +void StatisticsPropagator::MultiplyCardinalities(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); + auto new_max = Hugeint::Multiply(stats->max_cardinality, new_stats.max_cardinality); + if (new_max < NumericLimits::Maximum()) { + int64_t result; + if (!Hugeint::TryCast(new_max, result)) { + throw InternalException("Overflow in cast in statistics propagation"); + } + D_ASSERT(result >= 0); + stats->max_cardinality = idx_t(result); + } else { + stats = nullptr; + } +} + +unique_ptr StatisticsPropagator::PropagateStatistics(LogicalJoin &join, + unique_ptr *node_ptr) { + // 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) { + MultiplyCardinalities(node_stats, *child_stats); + } + } + + auto join_type = join.join_type; + vector left_bindings, right_bindings; + if (IsRightOuterJoin(join_type)) { + left_bindings = join.children[0]->GetColumnBindings(); + } + if (IsLeftOuterJoin(join_type)) { + right_bindings = join.children[1]->GetColumnBindings(); + } + + // then propagate into the join conditions + switch (join.type) { + case LogicalOperatorType::LOGICAL_COMPARISON_JOIN: + PropagateStatistics((LogicalComparisonJoin &)join, node_ptr); + break; + case LogicalOperatorType::LOGICAL_ANY_JOIN: + PropagateStatistics((LogicalAnyJoin &)join, node_ptr); + break; + default: + break; + } + + // now depending on the join type, we might need to alter the statistics + // LEFT, FULL and RIGHT OUTER joins can introduce null values + // this requires us to alter the statistics after this point in the query plan + if (IsLeftOuterJoin(join_type)) { + // left or full outer join: set IsNull() to true for all rhs statistics + for (auto &binding : right_bindings) { + auto stats = statistics_map.find(binding); + if (stats != statistics_map.end()) { + stats->second->validity_stats = make_unique(true); + } + } + } + if (IsRightOuterJoin(join_type)) { + // right or full outer join: set IsNull() to true for all lhs statistics + for (auto &binding : left_bindings) { + auto stats = statistics_map.find(binding); + if (stats != statistics_map.end()) { + stats->second->validity_stats = make_unique(true); + } + } + } + return move(node_stats); +} + +} // namespace duckdb + + + +namespace duckdb { + +unique_ptr StatisticsPropagator::PropagateStatistics(LogicalLimit &limit, + unique_ptr *node_ptr) { + // propagate statistics in the child node + PropagateStatistics(limit.children[0]); + // return the node stats, with as expected cardinality the amount specified in the limit + return make_unique(limit.limit_val, limit.limit_val); +} + +} // namespace duckdb + + + + +namespace duckdb { + +unique_ptr StatisticsPropagator::PropagateStatistics(LogicalOrder &order, + unique_ptr *node_ptr) { + // first propagate to the child + node_stats = PropagateStatistics(order.children[0]); + + // then propagate to each of the order expressions + for (auto &bound_order : order.orders) { + PropagateAndCompress(bound_order.expression, bound_order.stats); + } + return move(node_stats); +} + +} // namespace duckdb + + + +namespace duckdb { + +unique_ptr StatisticsPropagator::PropagateStatistics(LogicalProjection &proj, + unique_ptr *node_ptr) { + // first propagate to the child + node_stats = PropagateStatistics(proj.children[0]); + if (proj.children[0]->type == LogicalOperatorType::LOGICAL_EMPTY_RESULT) { + ReplaceWithEmptyResult(*node_ptr); + return move(node_stats); + } + + // then propagate to each of the expressions + for (idx_t i = 0; i < proj.expressions.size(); i++) { + auto stats = PropagateExpression(proj.expressions[i]); + if (stats) { + ColumnBinding binding(proj.table_index, i); + statistics_map.insert(make_pair(binding, move(stats))); + } + } + return move(node_stats); +} + +} // namespace duckdb + + + +namespace duckdb { + +void StatisticsPropagator::AddCardinalities(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 += new_stats.estimated_cardinality; + auto new_max = Hugeint::Add(stats->max_cardinality, new_stats.max_cardinality); + if (new_max < NumericLimits::Maximum()) { + int64_t result; + if (!Hugeint::TryCast(new_max, result)) { + throw InternalException("Overflow in cast in statistics propagation"); + } + D_ASSERT(result >= 0); + stats->max_cardinality = idx_t(result); + } else { + stats = nullptr; + } +} + +unique_ptr StatisticsPropagator::PropagateStatistics(LogicalSetOperation &setop, + unique_ptr *node_ptr) { + // first propagate statistics in the child nodes + auto left_stats = PropagateStatistics(setop.children[0]); + auto right_stats = PropagateStatistics(setop.children[1]); + + // now fetch the column bindings on both sides + auto left_bindings = setop.children[0]->GetColumnBindings(); + auto right_bindings = setop.children[1]->GetColumnBindings(); + + D_ASSERT(left_bindings.size() == right_bindings.size()); + D_ASSERT(left_bindings.size() == setop.column_count); + for (idx_t i = 0; i < setop.column_count; i++) { + // for each column binding, we fetch the statistics from both the lhs and the rhs + auto left_entry = statistics_map.find(left_bindings[i]); + auto right_entry = statistics_map.find(right_bindings[i]); + if (left_entry == statistics_map.end() || right_entry == statistics_map.end()) { + // no statistics on one of the sides: can't propagate stats + continue; + } + unique_ptr new_stats; + switch (setop.type) { + case LogicalOperatorType::LOGICAL_UNION: + // union: merge the stats of the LHS and RHS together + new_stats = left_entry->second->Copy(); + new_stats->Merge(*right_entry->second); + break; + case LogicalOperatorType::LOGICAL_EXCEPT: + // except: use the stats of the LHS + new_stats = left_entry->second->Copy(); + break; + case LogicalOperatorType::LOGICAL_INTERSECT: + // intersect: intersect the two stats + // FIXME: for now we just use the stats of the LHS, as this is correct + // however, the stats can be further refined to the minimal subset of the LHS and RHS + new_stats = left_entry->second->Copy(); + break; + default: + throw InternalException("Unsupported setop type"); + } + ColumnBinding binding(setop.table_index, i); + statistics_map[binding] = move(new_stats); + } + if (!left_stats || !right_stats) { + return nullptr; + } + if (setop.type == LogicalOperatorType::LOGICAL_UNION) { + AddCardinalities(left_stats, *right_stats); + } + return left_stats; +} + +} // namespace duckdb + + + + +namespace duckdb { + +unique_ptr StatisticsPropagator::PropagateStatistics(LogicalWindow &window, + unique_ptr *node_ptr) { + // first propagate to the child + node_stats = PropagateStatistics(window.children[0]); + + // then propagate to each of the order expressions + for (auto &window_expr : window.expressions) { + auto over_expr = reinterpret_cast(window_expr.get()); + for (auto &expr : over_expr->partitions) { + over_expr->partitions_stats.push_back(PropagateExpression(expr)); + } + for (auto &bound_order : over_expr->orders) { + bound_order.stats = PropagateExpression(bound_order.expression); + } + } + return move(node_stats); +} + +} // namespace duckdb + + + + + + + +namespace duckdb { + +StatisticsPropagator::StatisticsPropagator(ClientContext &context) : context(context) { +} + +void StatisticsPropagator::ReplaceWithEmptyResult(unique_ptr &node) { + node = make_unique(move(node)); +} + +unique_ptr StatisticsPropagator::PropagateChildren(LogicalOperator &node, + unique_ptr *node_ptr) { + for (idx_t child_idx = 0; child_idx < node.children.size(); child_idx++) { + PropagateStatistics(node.children[child_idx]); + } + return nullptr; +} + +unique_ptr StatisticsPropagator::PropagateStatistics(LogicalOperator &node, + unique_ptr *node_ptr) { + switch (node.type) { + case LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY: + return PropagateStatistics((LogicalAggregate &)node, node_ptr); + case LogicalOperatorType::LOGICAL_CROSS_PRODUCT: + return PropagateStatistics((LogicalCrossProduct &)node, node_ptr); + case LogicalOperatorType::LOGICAL_FILTER: + return PropagateStatistics((LogicalFilter &)node, node_ptr); + case LogicalOperatorType::LOGICAL_GET: + return PropagateStatistics((LogicalGet &)node, node_ptr); + case LogicalOperatorType::LOGICAL_PROJECTION: + return PropagateStatistics((LogicalProjection &)node, node_ptr); + case LogicalOperatorType::LOGICAL_ANY_JOIN: + case LogicalOperatorType::LOGICAL_COMPARISON_JOIN: + case LogicalOperatorType::LOGICAL_JOIN: + return PropagateStatistics((LogicalJoin &)node, node_ptr); + case LogicalOperatorType::LOGICAL_UNION: + case LogicalOperatorType::LOGICAL_EXCEPT: + case LogicalOperatorType::LOGICAL_INTERSECT: + return PropagateStatistics((LogicalSetOperation &)node, node_ptr); + case LogicalOperatorType::LOGICAL_ORDER_BY: + return PropagateStatistics((LogicalOrder &)node, node_ptr); + case LogicalOperatorType::LOGICAL_WINDOW: + return PropagateStatistics((LogicalWindow &)node, node_ptr); + default: + return PropagateChildren(node, node_ptr); + } +} + +unique_ptr StatisticsPropagator::PropagateStatistics(unique_ptr &node_ptr) { + return PropagateStatistics(*node_ptr, &node_ptr); +} + +unique_ptr StatisticsPropagator::PropagateExpression(Expression &expr, + unique_ptr *expr_ptr) { + switch (expr.GetExpressionClass()) { + case ExpressionClass::BOUND_AGGREGATE: + return PropagateExpression((BoundAggregateExpression &)expr, expr_ptr); + case ExpressionClass::BOUND_BETWEEN: + return PropagateExpression((BoundBetweenExpression &)expr, expr_ptr); + case ExpressionClass::BOUND_CASE: + return PropagateExpression((BoundCaseExpression &)expr, expr_ptr); + case ExpressionClass::BOUND_FUNCTION: + return PropagateExpression((BoundFunctionExpression &)expr, expr_ptr); + case ExpressionClass::BOUND_CAST: + return PropagateExpression((BoundCastExpression &)expr, expr_ptr); + case ExpressionClass::BOUND_COMPARISON: + return PropagateExpression((BoundComparisonExpression &)expr, expr_ptr); + case ExpressionClass::BOUND_CONSTANT: + return PropagateExpression((BoundConstantExpression &)expr, expr_ptr); + case ExpressionClass::BOUND_COLUMN_REF: + return PropagateExpression((BoundColumnRefExpression &)expr, expr_ptr); + case ExpressionClass::BOUND_OPERATOR: + return PropagateExpression((BoundOperatorExpression &)expr, expr_ptr); + default: + break; + } + ExpressionIterator::EnumerateChildren(expr, [&](unique_ptr &child) { PropagateExpression(child); }); + return nullptr; +} + +unique_ptr StatisticsPropagator::PropagateExpression(unique_ptr &expr) { + auto stats = PropagateExpression(*expr, &expr); + if (ClientConfig::GetConfig(context).query_verification_enabled && stats) { + expr->verification_stats = stats->Copy(); + } + return stats; +} + +} // namespace duckdb + + + + + + +namespace duckdb { + +unique_ptr TopN::Optimize(unique_ptr op) { + if (op->type == LogicalOperatorType::LOGICAL_LIMIT && + op->children[0]->type == LogicalOperatorType::LOGICAL_ORDER_BY) { + auto &limit = (LogicalLimit &)*op; + auto &order_by = (LogicalOrder &)*(op->children[0]); + + // 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); + } + } else { + for (auto &child : op->children) { + child = Optimize(move(child)); + } + } + return op; +} + +} // namespace duckdb + + + + + + +namespace duckdb { + +Event::Event(Executor &executor_p) + : executor(executor_p), finished_tasks(0), total_tasks(0), finished_dependencies(0), total_dependencies(0), + finished(false) { +} + +void Event::CompleteDependency() { + idx_t current_finished = ++finished_dependencies; + D_ASSERT(current_finished <= total_dependencies); + if (current_finished == total_dependencies) { + // all dependencies have been completed: schedule the event + D_ASSERT(total_tasks == 0); + Schedule(); + if (total_tasks == 0) { + Finish(); + } + } +} + +void Event::Finish() { + D_ASSERT(!finished); + FinishEvent(); + finished = true; + // finished processing the pipeline, now we can schedule pipelines that depend on this pipeline + for (auto &parent_entry : parents) { + auto parent = parent_entry.lock(); + if (!parent) { // LCOV_EXCL_START + continue; + } // LCOV_EXCL_STOP + // mark a dependency as completed for each of the parents + parent->CompleteDependency(); + } + FinalizeFinish(); +} + +void Event::AddDependency(Event &event) { + total_dependencies++; + event.parents.push_back(weak_ptr(shared_from_this())); +} + +void Event::FinishTask() { + D_ASSERT(finished_tasks.load() < total_tasks.load()); + idx_t current_tasks = total_tasks; + idx_t current_finished = ++finished_tasks; + D_ASSERT(current_finished <= current_tasks); + if (current_finished == current_tasks) { + Finish(); + } +} + +void Event::InsertEvent(shared_ptr replacement_event) { + replacement_event->parents = move(parents); + replacement_event->AddDependency(*this); + executor.AddEvent(move(replacement_event)); +} + +void Event::SetTasks(vector> tasks) { + auto &ts = TaskScheduler::GetScheduler(executor.context); + D_ASSERT(total_tasks == 0); + D_ASSERT(!tasks.empty()); + this->total_tasks = tasks.size(); + for (auto &task : tasks) { + ts.ScheduleTask(executor.GetToken(), move(task)); + } +} + +} // namespace duckdb + + + + + + + + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parallel/pipeline_executor.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/stack.hpp +// +// +//===----------------------------------------------------------------------===// + + + +#include + +namespace duckdb { +using std::stack; +} + + +#include + +namespace duckdb { +class Executor; + +//! The Pipeline class represents an execution pipeline +class PipelineExecutor { + static constexpr const idx_t CACHE_THRESHOLD = 64; + +public: + PipelineExecutor(ClientContext &context, Pipeline &pipeline); + + //! Fully execute a pipeline with a source and a sink until the source is completely exhausted + void Execute(); + //! Execute a pipeline with a source and a sink until finished, or until max_chunks have been processed + //! Returns true if execution is finished, false if Execute should be called again + bool Execute(idx_t max_chunks); + + //! Push a single input DataChunk into the pipeline. + //! Returns either OperatorResultType::NEED_MORE_INPUT or OperatorResultType::FINISHED + //! If OperatorResultType::FINISHED is returned, more input will not change the result anymore + OperatorResultType ExecutePush(DataChunk &input); + //! Called after depleting the source: finalizes the execution of this pipeline executor + //! This should only be called once per PipelineExecutor + void PushFinalize(); + + //! Initializes a chunk with the types that will flow out of ExecutePull + void InitializeChunk(DataChunk &chunk); + //! Execute a pipeline without a sink, and retrieve a single DataChunk + //! Returns an empty chunk when finished. + void ExecutePull(DataChunk &result); + //! Called after depleting the source using ExecutePull + //! This flushes profiler states + void PullFinalize(); + +private: + //! The pipeline to process + Pipeline &pipeline; + //! The thread context of this executor + ThreadContext thread; + //! The total execution context of this executor + ExecutionContext context; + + //! Intermediate chunks for the operators + vector> intermediate_chunks; + //! Intermediate states for the operators + vector> intermediate_states; + + //! The local source state + unique_ptr local_source_state; + //! The local sink state (if any) + unique_ptr local_sink_state; + + //! The final chunk used for moving data into the sink + DataChunk final_chunk; + + //! The operators that are not yet finished executing and have data remaining + //! If the stack of in_process_operators is empty, we fetch from the source instead + stack in_process_operators; + //! Whether or not the pipeline has been finalized (used for verification only) + bool finalized = false; + //! Whether or not the pipeline has finished processing + bool finished_processing = false; + + //! Cached chunks for any operators that require caching + vector> cached_chunks; + +private: + void StartOperator(PhysicalOperator *op); + void EndOperator(PhysicalOperator *op, DataChunk *chunk); + + //! Reset the operator index to the first operator + void GoToSource(idx_t ¤t_idx, idx_t initial_idx); + void FetchFromSource(DataChunk &result); + + OperatorResultType ExecutePushInternal(DataChunk &input, idx_t initial_idx = 0); + //! Pushes a chunk through the pipeline and returns a single result chunk + //! Returns whether or not a new input chunk is needed, or whether or not we are finished + OperatorResultType Execute(DataChunk &input, DataChunk &result, idx_t initial_index = 0); + + static bool CanCacheType(const LogicalType &type); + void CacheChunk(DataChunk &input, idx_t operator_idx); +}; + +} // namespace duckdb + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parallel/pipeline_event.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { + +class PipelineEvent : public Event { +public: + PipelineEvent(shared_ptr pipeline); + + //! The pipeline that this event belongs to + shared_ptr pipeline; + +public: + void Schedule() override; + void FinishEvent() override; +}; + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parallel/pipeline_finish_event.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { +class Executor; + +class PipelineFinishEvent : public Event { +public: + PipelineFinishEvent(shared_ptr pipeline); + + //! The pipeline that this event belongs to + shared_ptr pipeline; + +public: + void Schedule() override; + void FinishEvent() override; +}; + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parallel/pipeline_complete_event.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { +class Executor; + +class PipelineCompleteEvent : public Event { +public: + PipelineCompleteEvent(Executor &executor, bool complete_pipeline_p); + + bool complete_pipeline; + +public: + void Schedule() override; + void FinalizeFinish() override; +}; + +} // namespace duckdb + + +#include + +namespace duckdb { + +Executor::Executor(ClientContext &context) : context(context) { +} + +Executor::~Executor() { +} + +Executor &Executor::Get(ClientContext &context) { + return context.GetExecutor(); +} + +void Executor::AddEvent(shared_ptr event) { + lock_guard elock(executor_lock); + events.push_back(move(event)); +} + +struct PipelineEventStack { + Event *pipeline_event; + Event *pipeline_finish_event; + Event *pipeline_complete_event; +}; + +Pipeline *Executor::ScheduleUnionPipeline(const shared_ptr &pipeline, const Pipeline *parent, + event_map_t &event_map, vector> &events) { + pipeline->Ready(); + + D_ASSERT(pipeline); + auto pipeline_event = make_shared(pipeline); + + auto parent_stack_entry = event_map.find(parent); + D_ASSERT(parent_stack_entry != event_map.end()); + + auto &parent_stack = parent_stack_entry->second; + + PipelineEventStack stack; + stack.pipeline_event = pipeline_event.get(); + stack.pipeline_finish_event = parent_stack.pipeline_finish_event; + stack.pipeline_complete_event = parent_stack.pipeline_complete_event; + + stack.pipeline_event->AddDependency(*parent_stack.pipeline_event); + parent_stack.pipeline_finish_event->AddDependency(*pipeline_event); + + events.push_back(move(pipeline_event)); + event_map.insert(make_pair(pipeline.get(), stack)); + + auto parent_pipeline = pipeline.get(); + + auto union_entry = union_pipelines.find(pipeline.get()); + if (union_entry != union_pipelines.end()) { + for (auto &entry : union_entry->second) { + parent_pipeline = ScheduleUnionPipeline(entry, parent_pipeline, event_map, events); + } + } + + return parent_pipeline; +} + +void Executor::ScheduleChildPipeline(Pipeline *parent, const shared_ptr &pipeline, event_map_t &event_map, + vector> &events) { + pipeline->Ready(); + + auto child_ptr = pipeline.get(); + auto dependencies = child_dependencies.find(child_ptr); + D_ASSERT(union_pipelines.find(child_ptr) == union_pipelines.end()); + D_ASSERT(dependencies != child_dependencies.end()); + // create the pipeline event and the event stack + auto pipeline_event = make_shared(pipeline); + + auto parent_entry = event_map.find(parent); + PipelineEventStack stack; + stack.pipeline_event = pipeline_event.get(); + stack.pipeline_finish_event = parent_entry->second.pipeline_finish_event; + stack.pipeline_complete_event = parent_entry->second.pipeline_complete_event; + + // set up the dependencies for this child pipeline + unordered_set finish_events; + for (auto &dep : dependencies->second) { + auto dep_entry = event_map.find(dep); + D_ASSERT(dep_entry != event_map.end()); + D_ASSERT(dep_entry->second.pipeline_event); + D_ASSERT(dep_entry->second.pipeline_finish_event); + + auto finish_event = dep_entry->second.pipeline_finish_event; + stack.pipeline_event->AddDependency(*dep_entry->second.pipeline_event); + if (finish_events.find(finish_event) == finish_events.end()) { + finish_event->AddDependency(*stack.pipeline_event); + finish_events.insert(finish_event); + } + } + + events.push_back(move(pipeline_event)); + event_map.insert(make_pair(child_ptr, stack)); +} + +void Executor::SchedulePipeline(const shared_ptr &pipeline, event_map_t &event_map, + vector> &events, bool complete_pipeline) { + D_ASSERT(pipeline); + + pipeline->Ready(); + + auto pipeline_event = make_shared(pipeline); + auto pipeline_finish_event = make_shared(pipeline); + auto pipeline_complete_event = make_shared(pipeline->executor, complete_pipeline); + + PipelineEventStack stack; + stack.pipeline_event = pipeline_event.get(); + stack.pipeline_finish_event = pipeline_finish_event.get(); + stack.pipeline_complete_event = pipeline_complete_event.get(); + + pipeline_finish_event->AddDependency(*pipeline_event); + pipeline_complete_event->AddDependency(*pipeline_finish_event); + + events.push_back(move(pipeline_event)); + events.push_back(move(pipeline_finish_event)); + events.push_back(move(pipeline_complete_event)); + + event_map.insert(make_pair(pipeline.get(), stack)); + + auto union_entry = union_pipelines.find(pipeline.get()); + if (union_entry != union_pipelines.end()) { + auto parent_pipeline = pipeline.get(); + for (auto &entry : union_entry->second) { + parent_pipeline = ScheduleUnionPipeline(entry, parent_pipeline, event_map, events); + } + } +} + +void Executor::ScheduleEventsInternal(const vector> &pipelines, + unordered_map>> &child_pipelines, + vector> &events, bool main_schedule) { + D_ASSERT(events.empty()); + // create all the required pipeline events + event_map_t event_map; + for (auto &pipeline : pipelines) { + SchedulePipeline(pipeline, event_map, events, main_schedule); + } + // schedule child pipelines + for (auto &entry : child_pipelines) { + // iterate in reverse order + // since child entries are added from top to bottom + // dependencies are in reverse order (bottom to top) + for (idx_t i = entry.second.size(); i > 0; i--) { + auto &child_entry = entry.second[i - 1]; + ScheduleChildPipeline(entry.first, child_entry, event_map, events); + } + } + // set up the dependencies between pipeline events + for (auto &entry : event_map) { + auto pipeline = entry.first; + for (auto &dependency : pipeline->dependencies) { + auto dep = dependency.lock(); + D_ASSERT(dep); + auto event_map_entry = event_map.find(dep.get()); + D_ASSERT(event_map_entry != event_map.end()); + auto &dep_entry = event_map_entry->second; + D_ASSERT(dep_entry.pipeline_complete_event); + entry.second.pipeline_event->AddDependency(*dep_entry.pipeline_complete_event); + } + } + // schedule the pipelines that do not have dependencies + for (auto &event : events) { + if (!event->HasDependencies()) { + event->Schedule(); + } + } +} + +void Executor::ScheduleEvents() { + ScheduleEventsInternal(pipelines, child_pipelines, events); +} + +void Executor::ReschedulePipelines(const vector> &pipelines, vector> &events) { + unordered_map>> child_pipelines; + ScheduleEventsInternal(pipelines, child_pipelines, events, false); +} + +void Executor::ExtractPipelines(shared_ptr &pipeline, vector> &result) { + pipeline->Ready(); + + auto pipeline_ptr = pipeline.get(); + result.push_back(move(pipeline)); + auto union_entry = union_pipelines.find(pipeline_ptr); + if (union_entry != union_pipelines.end()) { + auto &union_pipeline_list = union_entry->second; + for (auto &pipeline : union_pipeline_list) { + ExtractPipelines(pipeline, result); + } + union_pipelines.erase(pipeline_ptr); + } + auto child_entry = child_pipelines.find(pipeline_ptr); + if (child_entry != child_pipelines.end()) { + for (auto &entry : child_entry->second) { + ExtractPipelines(entry, result); + } + child_pipelines.erase(pipeline_ptr); + } +} + +bool Executor::NextExecutor() { + if (root_pipeline_idx >= root_pipelines.size()) { + return false; + } + root_executor = make_unique(context, *root_pipelines[root_pipeline_idx]); + root_pipeline_idx++; + return true; +} + +void Executor::VerifyPipeline(Pipeline &pipeline) { + D_ASSERT(!pipeline.ToString().empty()); + auto operators = pipeline.GetOperators(); + for (auto &other_pipeline : pipelines) { + auto other_operators = other_pipeline->GetOperators(); + for (idx_t op_idx = 0; op_idx < operators.size(); op_idx++) { + for (idx_t other_idx = 0; other_idx < other_operators.size(); other_idx++) { + auto &left = *operators[op_idx]; + auto &right = *other_operators[other_idx]; + if (left.Equals(right)) { + D_ASSERT(right.Equals(left)); + } else { + D_ASSERT(!right.Equals(left)); + } + } + } + } +} + +void Executor::VerifyPipelines() { +#ifdef DEBUG + for (auto &pipeline : pipelines) { + VerifyPipeline(*pipeline); + } + for (auto &pipeline : root_pipelines) { + VerifyPipeline(*pipeline); + } +#endif +} + +void Executor::Initialize(PhysicalOperator *plan) { + Reset(); + + auto &scheduler = TaskScheduler::GetScheduler(context); + { + lock_guard elock(executor_lock); + physical_plan = plan; + + this->profiler = context.profiler; + profiler->Initialize(physical_plan); + this->producer = scheduler.CreateProducer(); + + auto root_pipeline = make_shared(*this); + root_pipeline->sink = nullptr; + BuildPipelines(physical_plan, root_pipeline.get()); + + this->total_pipelines = pipelines.size(); + + root_pipeline_idx = 0; + ExtractPipelines(root_pipeline, root_pipelines); + + VerifyPipelines(); + + ScheduleEvents(); + } +} + +void Executor::CancelTasks() { + task.reset(); + // we do this by creating weak pointers to all pipelines + // then clearing our references to the pipelines + // and waiting until all pipelines have been destroyed + vector> weak_references; + { + lock_guard elock(executor_lock); + if (pipelines.empty()) { + return; + } + weak_references.reserve(pipelines.size()); + for (auto &pipeline : pipelines) { + weak_references.push_back(weak_ptr(pipeline)); + } + for (auto &kv : union_pipelines) { + for (auto &pipeline : kv.second) { + weak_references.push_back(weak_ptr(pipeline)); + } + } + for (auto &kv : child_pipelines) { + for (auto &pipeline : kv.second) { + weak_references.push_back(weak_ptr(pipeline)); + } + } + pipelines.clear(); + union_pipelines.clear(); + child_pipelines.clear(); + events.clear(); + } + WorkOnTasks(); + for (auto &weak_ref : weak_references) { + while (true) { + auto weak = weak_ref.lock(); + if (!weak) { + break; + } + } + } +} + +void Executor::WorkOnTasks() { + auto &scheduler = TaskScheduler::GetScheduler(context); + + unique_ptr task; + while (scheduler.GetTaskFromProducer(*producer, task)) { + task->Execute(TaskExecutionMode::PROCESS_ALL); + task.reset(); + } +} + +PendingExecutionResult Executor::ExecuteTask() { + if (execution_result != PendingExecutionResult::RESULT_NOT_READY) { + return execution_result; + } + // check if there are any incomplete pipelines + auto &scheduler = TaskScheduler::GetScheduler(context); + while (completed_pipelines < total_pipelines) { + // there are! if we don't already have a task, fetch one + if (!task) { + scheduler.GetTaskFromProducer(*producer, task); + } + if (task) { + // if we have a task, partially process it + auto result = task->Execute(TaskExecutionMode::PROCESS_PARTIAL); + if (result != TaskExecutionResult::TASK_NOT_FINISHED) { + // if the task is finished, clean it up + task.reset(); + } + } + if (!HasError()) { + // we (partially) processed a task and no exceptions were thrown + // give back control to the caller + return PendingExecutionResult::RESULT_NOT_READY; + } + execution_result = PendingExecutionResult::EXECUTION_ERROR; + + // an exception has occurred executing one of the pipelines + // we need to cancel all tasks associated with this executor + CancelTasks(); + ThrowException(); + } + D_ASSERT(!task); + + lock_guard elock(executor_lock); + pipelines.clear(); + NextExecutor(); + if (!exceptions.empty()) { // LCOV_EXCL_START + // an exception has occurred executing one of the pipelines + execution_result = PendingExecutionResult::EXECUTION_ERROR; + ThrowExceptionInternal(); + } // LCOV_EXCL_STOP + execution_result = PendingExecutionResult::RESULT_READY; + return execution_result; +} + +void Executor::Reset() { + lock_guard elock(executor_lock); + delim_join_dependencies.clear(); + recursive_cte = nullptr; + physical_plan = nullptr; + root_executor.reset(); + root_pipelines.clear(); + root_pipeline_idx = 0; + completed_pipelines = 0; + total_pipelines = 0; + exceptions.clear(); + pipelines.clear(); + events.clear(); + union_pipelines.clear(); + child_pipelines.clear(); + child_dependencies.clear(); + execution_result = PendingExecutionResult::RESULT_NOT_READY; +} + +void Executor::AddChildPipeline(Pipeline *current) { + D_ASSERT(!current->operators.empty()); + // found another operator that is a source + // schedule a child pipeline + auto child_pipeline = make_shared(*this); + auto child_pipeline_ptr = child_pipeline.get(); + child_pipeline->sink = current->sink; + child_pipeline->operators = current->operators; + child_pipeline->source = current->operators.back(); + D_ASSERT(child_pipeline->source->IsSource()); + child_pipeline->operators.pop_back(); + + vector dependencies; + dependencies.push_back(current); + auto child_entry = child_pipelines.find(current); + if (child_entry != child_pipelines.end()) { + for (auto ¤t_child : child_entry->second) { + D_ASSERT(child_dependencies.find(current_child.get()) != child_dependencies.end()); + child_dependencies[current_child.get()].push_back(child_pipeline_ptr); + } + } + D_ASSERT(child_dependencies.find(child_pipeline_ptr) == child_dependencies.end()); + child_dependencies.insert(make_pair(child_pipeline_ptr, move(dependencies))); + child_pipelines[current].push_back(move(child_pipeline)); +} + +void Executor::BuildPipelines(PhysicalOperator *op, Pipeline *current) { + D_ASSERT(current); + if (op->IsSink()) { + // operator is a sink, build a pipeline + op->sink_state.reset(); + + PhysicalOperator *pipeline_child = nullptr; + switch (op->type) { + case PhysicalOperatorType::CREATE_TABLE_AS: + case PhysicalOperatorType::INSERT: + case PhysicalOperatorType::DELETE_OPERATOR: + case PhysicalOperatorType::UPDATE: + case PhysicalOperatorType::HASH_GROUP_BY: + case PhysicalOperatorType::SIMPLE_AGGREGATE: + case PhysicalOperatorType::PERFECT_HASH_GROUP_BY: + case PhysicalOperatorType::WINDOW: + case PhysicalOperatorType::ORDER_BY: + case PhysicalOperatorType::RESERVOIR_SAMPLE: + case PhysicalOperatorType::TOP_N: + case PhysicalOperatorType::COPY_TO_FILE: + case PhysicalOperatorType::LIMIT: + case PhysicalOperatorType::LIMIT_PERCENT: + case PhysicalOperatorType::EXPLAIN_ANALYZE: + D_ASSERT(op->children.size() == 1); + // single operator: + // the operator becomes the data source of the current pipeline + current->source = op; + // we create a new pipeline starting from the child + pipeline_child = op->children[0].get(); + break; + case PhysicalOperatorType::EXPORT: + // EXPORT has an optional child + // we only need to schedule child pipelines if there is a child + current->source = op; + if (op->children.empty()) { + return; + } + D_ASSERT(op->children.size() == 1); + pipeline_child = op->children[0].get(); + break; + case PhysicalOperatorType::NESTED_LOOP_JOIN: + case PhysicalOperatorType::BLOCKWISE_NL_JOIN: + case PhysicalOperatorType::HASH_JOIN: + case PhysicalOperatorType::PIECEWISE_MERGE_JOIN: + case PhysicalOperatorType::CROSS_PRODUCT: + // regular join, create a pipeline with RHS source that sinks into this pipeline + pipeline_child = op->children[1].get(); + // on the LHS (probe child), the operator becomes a regular operator + current->operators.push_back(op); + if (op->IsSource()) { + // FULL or RIGHT outer join + // schedule a scan of the node as a child pipeline + // this scan has to be performed AFTER all the probing has happened + if (recursive_cte) { + throw NotImplementedException("FULL and RIGHT outer joins are not supported in recursive CTEs yet"); + } + AddChildPipeline(current); + } + BuildPipelines(op->children[0].get(), current); + break; + case PhysicalOperatorType::DELIM_JOIN: { + // duplicate eliminated join + // for delim joins, recurse into the actual join + pipeline_child = op->children[0].get(); + break; + } + case PhysicalOperatorType::RECURSIVE_CTE: { + auto &cte_node = (PhysicalRecursiveCTE &)*op; + + // recursive CTE + current->source = op; + // the LHS of the recursive CTE is our initial state + // we build this pipeline as normal + pipeline_child = op->children[0].get(); + // for the RHS, we gather all pipelines that depend on the recursive cte + // these pipelines need to be rerun + if (recursive_cte) { + throw InternalException("Recursive CTE detected WITHIN a recursive CTE node"); + } + recursive_cte = op; + + auto recursive_pipeline = make_shared(*this); + recursive_pipeline->sink = op; + op->sink_state.reset(); + BuildPipelines(op->children[1].get(), recursive_pipeline.get()); + + cte_node.pipelines.push_back(move(recursive_pipeline)); + + recursive_cte = nullptr; + break; + } + default: + throw InternalException("Unimplemented sink type!"); + } + // the current is dependent on this pipeline to complete + auto pipeline = make_shared(*this); + pipeline->sink = op; + current->AddDependency(pipeline); + D_ASSERT(pipeline_child); + // recurse into the pipeline child + BuildPipelines(pipeline_child, pipeline.get()); + if (op->type == PhysicalOperatorType::DELIM_JOIN) { + // for delim joins, recurse into the actual join + // any pipelines in there depend on the main pipeline + auto &delim_join = (PhysicalDelimJoin &)*op; + // any scan of the duplicate eliminated data on the RHS depends on this pipeline + // we add an entry to the mapping of (PhysicalOperator*) -> (Pipeline*) + for (auto &delim_scan : delim_join.delim_scans) { + delim_join_dependencies[delim_scan] = pipeline.get(); + } + BuildPipelines(delim_join.join.get(), current); + } + if (!recursive_cte) { + // regular pipeline: schedule it + pipelines.push_back(move(pipeline)); + } else { + // CTE pipeline! add it to the CTE pipelines + D_ASSERT(recursive_cte); + auto &cte = (PhysicalRecursiveCTE &)*recursive_cte; + cte.pipelines.push_back(move(pipeline)); + } + } else { + // operator is not a sink! recurse in children + // first check if there is any additional action we need to do depending on the type + switch (op->type) { + case PhysicalOperatorType::DELIM_SCAN: { + D_ASSERT(op->children.empty()); + auto entry = delim_join_dependencies.find(op); + D_ASSERT(entry != delim_join_dependencies.end()); + // this chunk scan introduces a dependency to the current pipeline + // namely a dependency on the duplicate elimination pipeline to finish + auto delim_dependency = entry->second->shared_from_this(); + D_ASSERT(delim_dependency->sink->type == PhysicalOperatorType::DELIM_JOIN); + auto &delim_join = (PhysicalDelimJoin &)*delim_dependency->sink; + current->AddDependency(delim_dependency); + current->source = (PhysicalOperator *)delim_join.distinct.get(); + return; + } + case PhysicalOperatorType::EXECUTE: { + // EXECUTE statement: build pipeline on child + auto &execute = (PhysicalExecute &)*op; + BuildPipelines(execute.plan, current); + return; + } + case PhysicalOperatorType::RECURSIVE_CTE_SCAN: { + if (!recursive_cte) { + throw InternalException("Recursive CTE scan found without recursive CTE node"); + } + break; + } + case PhysicalOperatorType::INDEX_JOIN: { + // index join: we only continue into the LHS + // the right side is probed by the index join + // so we don't need to do anything in the pipeline with this child + current->operators.push_back(op); + BuildPipelines(op->children[0].get(), current); + return; + } + case PhysicalOperatorType::UNION: { + if (recursive_cte) { + throw NotImplementedException("UNIONS are not supported in recursive CTEs yet"); + } + auto union_pipeline = make_shared(*this); + auto pipeline_ptr = union_pipeline.get(); + // set up dependencies for any child pipelines to this union pipeline + auto child_entry = child_pipelines.find(current); + if (child_entry != child_pipelines.end()) { + for (auto ¤t_child : child_entry->second) { + D_ASSERT(child_dependencies.find(current_child.get()) != child_dependencies.end()); + child_dependencies[current_child.get()].push_back(pipeline_ptr); + } + } + // for the current pipeline, continue building on the LHS + union_pipeline->operators = current->operators; + BuildPipelines(op->children[0].get(), current); + // insert the union pipeline as a union pipeline of the current node + union_pipelines[current].push_back(move(union_pipeline)); + + // for the union pipeline, build on the RHS + pipeline_ptr->sink = current->sink; + BuildPipelines(op->children[1].get(), pipeline_ptr); + return; + } + default: + break; + } + if (op->children.empty()) { + // source + current->source = op; + } else { + if (op->children.size() != 1) { + throw InternalException("Operator not supported yet"); + } + current->operators.push_back(op); + BuildPipelines(op->children[0].get(), current); + } + } +} + +vector Executor::GetTypes() { + D_ASSERT(physical_plan); + return physical_plan->GetTypes(); +} + +void Executor::PushError(ExceptionType type, const string &exception) { + lock_guard elock(executor_lock); + // interrupt execution of any other pipelines that belong to this executor + context.interrupted = true; + // push the exception onto the stack + exceptions.emplace_back(type, exception); +} + +bool Executor::HasError() { + lock_guard elock(executor_lock); + return !exceptions.empty(); +} + +void Executor::ThrowException() { + lock_guard elock(executor_lock); + ThrowExceptionInternal(); +} + +void Executor::ThrowExceptionInternal() { // LCOV_EXCL_START + D_ASSERT(!exceptions.empty()); + auto &entry = exceptions[0]; + switch (entry.first) { + case ExceptionType::TRANSACTION: + throw TransactionException(entry.second); + case ExceptionType::CATALOG: + throw CatalogException(entry.second); + case ExceptionType::PARSER: + throw ParserException(entry.second); + case ExceptionType::BINDER: + throw BinderException(entry.second); + case ExceptionType::INTERRUPT: + throw InterruptException(); + case ExceptionType::FATAL: + throw FatalException(entry.second); + case ExceptionType::INTERNAL: + throw InternalException(entry.second); + case ExceptionType::IO: + throw IOException(entry.second); + case ExceptionType::CONSTRAINT: + throw ConstraintException(entry.second); + case ExceptionType::CONVERSION: + throw ConversionException(entry.second); + default: + throw Exception(entry.second); + } +} // LCOV_EXCL_STOP + +void Executor::Flush(ThreadContext &tcontext) { + profiler->Flush(tcontext.profiler); +} + +bool Executor::GetPipelinesProgress(double ¤t_progress) { // LCOV_EXCL_START + lock_guard elock(executor_lock); + + if (!pipelines.empty()) { + return pipelines.back()->GetProgress(current_progress); + } else { + current_progress = -1; + return true; + } +} // LCOV_EXCL_STOP + +unique_ptr Executor::FetchChunk() { + D_ASSERT(physical_plan); + + auto chunk = make_unique(); + root_executor->InitializeChunk(*chunk); + while (true) { + root_executor->ExecutePull(*chunk); + if (chunk->size() == 0) { + root_executor->PullFinalize(); + if (NextExecutor()) { + continue; + } + break; + } else { + break; + } + } + return chunk; +} + +} // namespace duckdb + + + +namespace duckdb { + +ExecutorTask::ExecutorTask(Executor &executor_p) : executor(executor_p) { +} + +ExecutorTask::ExecutorTask(ClientContext &context) : ExecutorTask(Executor::Get(context)) { +} + +ExecutorTask::~ExecutorTask() { +} + +TaskExecutionResult ExecutorTask::Execute(TaskExecutionMode mode) { + try { + return ExecuteTask(mode); + } catch (Exception &ex) { + executor.PushError(ex.type, ex.what()); + } catch (std::exception &ex) { + executor.PushError(ExceptionType::UNKNOWN_TYPE, ex.what()); + } catch (...) { // LCOV_EXCL_START + executor.PushError(ExceptionType::UNKNOWN_TYPE, "Unknown exception in Finalize!"); + } // LCOV_EXCL_STOP + return TaskExecutionResult::TASK_ERROR; +} + +} // namespace duckdb + + + + + + + + + + + + + + + + + + + + + +namespace duckdb { + +class PipelineTask : public ExecutorTask { + static constexpr const idx_t PARTIAL_CHUNK_COUNT = 50; + +public: + explicit PipelineTask(Pipeline &pipeline_p, shared_ptr event_p) + : ExecutorTask(pipeline_p.executor), pipeline(pipeline_p), event(move(event_p)) { + } + + Pipeline &pipeline; + shared_ptr event; + unique_ptr pipeline_executor; + +public: + TaskExecutionResult ExecuteTask(TaskExecutionMode mode) override { + if (!pipeline_executor) { + pipeline_executor = make_unique(pipeline.GetClientContext(), pipeline); + } + if (mode == TaskExecutionMode::PROCESS_PARTIAL) { + bool finished = pipeline_executor->Execute(PARTIAL_CHUNK_COUNT); + if (!finished) { + return TaskExecutionResult::TASK_NOT_FINISHED; + } + } else { + pipeline_executor->Execute(); + } + event->FinishTask(); + pipeline_executor.reset(); + return TaskExecutionResult::TASK_FINISHED; + } +}; + +Pipeline::Pipeline(Executor &executor_p) : executor(executor_p), ready(false), source(nullptr), sink(nullptr) { +} + +ClientContext &Pipeline::GetClientContext() { + return executor.context; +} + +// LCOV_EXCL_START +bool Pipeline::GetProgressInternal(ClientContext &context, PhysicalOperator *op, double ¤t_percentage) { + current_percentage = -1; + switch (op->type) { + case PhysicalOperatorType::TABLE_SCAN: { + auto &get = (PhysicalTableScan &)*op; + if (get.function.table_scan_progress) { + current_percentage = get.function.table_scan_progress(context, get.bind_data.get()); + return true; + } + //! If the table_scan_progress is not implemented it means we don't support this function yet in the progress + //! bar + return false; + } + default: + return false; + } +} +// LCOV_EXCL_STOP + +bool Pipeline::GetProgress(double ¤t_percentage) { + auto &client = executor.context; + return GetProgressInternal(client, source, current_percentage); +} + +void Pipeline::ScheduleSequentialTask(shared_ptr &event) { + vector> tasks; + tasks.push_back(make_unique(*this, event)); + event->SetTasks(move(tasks)); +} + +bool Pipeline::ScheduleParallel(shared_ptr &event) { + if (!sink->ParallelSink()) { + return false; + } + if (!source->ParallelSource()) { + return false; + } + for (auto &op : operators) { + if (!op->ParallelOperator()) { + return false; + } + } + idx_t max_threads = source_state->MaxThreads(); + return LaunchScanTasks(event, max_threads); +} + +void Pipeline::Schedule(shared_ptr &event) { + D_ASSERT(ready); + D_ASSERT(sink); + if (!ScheduleParallel(event)) { + // could not parallelize this pipeline: push a sequential task instead + ScheduleSequentialTask(event); + } +} + +bool Pipeline::LaunchScanTasks(shared_ptr &event, idx_t max_threads) { + // split the scan up into parts and schedule the parts + auto &scheduler = TaskScheduler::GetScheduler(executor.context); + idx_t active_threads = scheduler.NumberOfThreads(); + if (max_threads > active_threads) { + max_threads = active_threads; + } + if (max_threads <= 1) { + // too small to parallelize + return false; + } + + // launch a task for every thread + vector> tasks; + for (idx_t i = 0; i < max_threads; i++) { + tasks.push_back(make_unique(*this, event)); + } + event->SetTasks(move(tasks)); + return true; +} + +void Pipeline::Reset() { + if (sink && !sink->sink_state) { + sink->sink_state = sink->GetGlobalSinkState(GetClientContext()); + } + ResetSource(); +} + +void Pipeline::ResetSource() { + source_state = source->GetGlobalSourceState(GetClientContext()); +} + +void Pipeline::Ready() { + if (ready) { + return; + } + ready = true; + std::reverse(operators.begin(), operators.end()); + Reset(); +} + +void Pipeline::Finalize(Event &event) { + D_ASSERT(ready); + try { + auto sink_state = sink->Finalize(*this, event, executor.context, *sink->sink_state); + sink->sink_state->state = sink_state; + } catch (Exception &ex) { // LCOV_EXCL_START + executor.PushError(ex.type, ex.what()); + } catch (std::exception &ex) { + executor.PushError(ExceptionType::UNKNOWN_TYPE, ex.what()); + } catch (...) { + executor.PushError(ExceptionType::UNKNOWN_TYPE, "Unknown exception in Finalize!"); + } // LCOV_EXCL_STOP +} + +void Pipeline::AddDependency(shared_ptr &pipeline) { + D_ASSERT(pipeline); + dependencies.push_back(weak_ptr(pipeline)); + pipeline->parents.push_back(weak_ptr(shared_from_this())); +} + +string Pipeline::ToString() const { + TreeRenderer renderer; + return renderer.ToString(*this); +} + +void Pipeline::Print() const { + Printer::Print(ToString()); +} + +vector Pipeline::GetOperators() const { + vector result; + D_ASSERT(source); + result.push_back(source); + result.insert(result.end(), operators.begin(), operators.end()); + if (sink) { + result.push_back(sink); + } + return result; +} + +} // namespace duckdb + + + +namespace duckdb { + +PipelineCompleteEvent::PipelineCompleteEvent(Executor &executor, bool complete_pipeline_p) + : Event(executor), complete_pipeline(complete_pipeline_p) { +} + +void PipelineCompleteEvent::Schedule() { +} + +void PipelineCompleteEvent::FinalizeFinish() { + if (complete_pipeline) { + executor.CompletePipeline(); + } +} + +} // namespace duckdb + + +namespace duckdb { + +PipelineEvent::PipelineEvent(shared_ptr pipeline_p) + : Event(pipeline_p->executor), pipeline(move(pipeline_p)) { +} + +void PipelineEvent::Schedule() { + auto event = shared_from_this(); + pipeline->Schedule(event); + D_ASSERT(total_tasks > 0); +} + +void PipelineEvent::FinishEvent() { +} + +} // namespace duckdb + + + +namespace duckdb { + +PipelineExecutor::PipelineExecutor(ClientContext &context_p, Pipeline &pipeline_p) + : pipeline(pipeline_p), thread(context_p), context(context_p, thread) { + D_ASSERT(pipeline.source_state); + local_source_state = pipeline.source->GetLocalSourceState(context, *pipeline.source_state); + if (pipeline.sink) { + local_sink_state = pipeline.sink->GetLocalSinkState(context); + } + intermediate_chunks.reserve(pipeline.operators.size()); + intermediate_states.reserve(pipeline.operators.size()); + cached_chunks.resize(pipeline.operators.size()); + for (idx_t i = 0; i < pipeline.operators.size(); i++) { + auto prev_operator = i == 0 ? pipeline.source : pipeline.operators[i - 1]; + auto current_operator = pipeline.operators[i]; + auto chunk = make_unique(); + chunk->Initialize(prev_operator->GetTypes()); + intermediate_chunks.push_back(move(chunk)); + intermediate_states.push_back(current_operator->GetOperatorState(context.client)); + if (pipeline.sink && !pipeline.sink->SinkOrderMatters() && current_operator->RequiresCache()) { + auto &cache_types = current_operator->GetTypes(); + bool can_cache = true; + for (auto &type : cache_types) { + if (!CanCacheType(type)) { + can_cache = false; + break; + } + } + if (!can_cache) { + continue; + } + cached_chunks[i] = make_unique(); + cached_chunks[i]->Initialize(current_operator->GetTypes()); + } + if (current_operator->IsSink() && current_operator->sink_state->state == SinkFinalizeType::NO_OUTPUT_POSSIBLE) { + // one of the operators has already figured out no output is possible + // we can skip executing the pipeline + finished_processing = true; + } + } + InitializeChunk(final_chunk); +} + +bool PipelineExecutor::Execute(idx_t max_chunks) { + D_ASSERT(pipeline.sink); + bool exhausted_source = false; + auto &source_chunk = pipeline.operators.empty() ? final_chunk : *intermediate_chunks[0]; + for (idx_t i = 0; i < max_chunks; i++) { + if (finished_processing) { + break; + } + source_chunk.Reset(); + FetchFromSource(source_chunk); + if (source_chunk.size() == 0) { + exhausted_source = true; + break; + } + auto result = ExecutePushInternal(source_chunk); + if (result == OperatorResultType::FINISHED) { + finished_processing = true; + break; + } + } + if (!exhausted_source && !finished_processing) { + return false; + } + PushFinalize(); + return true; +} + +void PipelineExecutor::Execute() { + Execute(NumericLimits::Maximum()); +} + +OperatorResultType PipelineExecutor::ExecutePush(DataChunk &input) { // LCOV_EXCL_START + return ExecutePushInternal(input); +} // LCOV_EXCL_STOP + +OperatorResultType PipelineExecutor::ExecutePushInternal(DataChunk &input, idx_t initial_idx) { + D_ASSERT(pipeline.sink); + if (input.size() == 0) { // LCOV_EXCL_START + return OperatorResultType::NEED_MORE_INPUT; + } // LCOV_EXCL_STOP + while (true) { + OperatorResultType result; + if (!pipeline.operators.empty()) { + final_chunk.Reset(); + result = Execute(input, final_chunk, initial_idx); + if (result == OperatorResultType::FINISHED) { + return OperatorResultType::FINISHED; + } + } else { + result = OperatorResultType::NEED_MORE_INPUT; + } + auto &sink_chunk = pipeline.operators.empty() ? input : final_chunk; + if (sink_chunk.size() > 0) { + StartOperator(pipeline.sink); + D_ASSERT(pipeline.sink); + D_ASSERT(pipeline.sink->sink_state); + auto sink_result = pipeline.sink->Sink(context, *pipeline.sink->sink_state, *local_sink_state, sink_chunk); + EndOperator(pipeline.sink, nullptr); + if (sink_result == SinkResultType::FINISHED) { + return OperatorResultType::FINISHED; + } + } + if (result == OperatorResultType::NEED_MORE_INPUT) { + return OperatorResultType::NEED_MORE_INPUT; + } + } + return OperatorResultType::FINISHED; +} + +void PipelineExecutor::PushFinalize() { + if (finalized) { + throw InternalException("Calling PushFinalize on a pipeline that has been finalized already"); + } + finalized = true; + // flush all caches + if (!finished_processing) { + D_ASSERT(in_process_operators.empty()); + for (idx_t i = 0; i < cached_chunks.size(); i++) { + if (cached_chunks[i] && cached_chunks[i]->size() > 0) { + ExecutePushInternal(*cached_chunks[i], i + 1); + cached_chunks[i].reset(); + } + } + } + D_ASSERT(local_sink_state); + // run the combine for the sink + pipeline.sink->Combine(context, *pipeline.sink->sink_state, *local_sink_state); + + // flush all query profiler info + for (idx_t i = 0; i < intermediate_states.size(); i++) { + intermediate_states[i]->Finalize(pipeline.operators[i], context); + } + pipeline.executor.Flush(thread); + local_sink_state.reset(); +} + +bool PipelineExecutor::CanCacheType(const LogicalType &type) { + switch (type.id()) { + case LogicalTypeId::LIST: + case LogicalTypeId::MAP: + return false; + case LogicalTypeId::STRUCT: { + auto &entries = StructType::GetChildTypes(type); + for (auto &entry : entries) { + if (!CanCacheType(entry.second)) { + return false; + } + } + return true; + } + default: + return true; + } +} + +void PipelineExecutor::CacheChunk(DataChunk ¤t_chunk, idx_t operator_idx) { +#if STANDARD_VECTOR_SIZE >= 128 + if (cached_chunks[operator_idx]) { + if (current_chunk.size() < CACHE_THRESHOLD) { + // we have filtered out a significant amount of tuples + // add this chunk to the cache and continue + auto &chunk_cache = *cached_chunks[operator_idx]; + chunk_cache.Append(current_chunk); + if (chunk_cache.size() >= (STANDARD_VECTOR_SIZE - CACHE_THRESHOLD)) { + // chunk cache full: return it + current_chunk.Move(chunk_cache); + chunk_cache.Initialize(pipeline.operators[operator_idx]->GetTypes()); + } else { + // chunk cache not full: probe again + current_chunk.Reset(); + } + } + } +#endif +} + +void PipelineExecutor::ExecutePull(DataChunk &result) { + if (finished_processing) { + return; + } + auto &executor = pipeline.executor; + try { + D_ASSERT(!pipeline.sink); + auto &source_chunk = pipeline.operators.empty() ? result : *intermediate_chunks[0]; + while (result.size() == 0) { + if (in_process_operators.empty()) { + source_chunk.Reset(); + FetchFromSource(source_chunk); + if (source_chunk.size() == 0) { + break; + } + } + if (!pipeline.operators.empty()) { + Execute(source_chunk, result); + } + } + } catch (std::exception &ex) { // LCOV_EXCL_START + if (executor.HasError()) { + executor.ThrowException(); + } + throw; + } catch (...) { + if (executor.HasError()) { + executor.ThrowException(); + } + throw; + } // LCOV_EXCL_STOP +} + +void PipelineExecutor::PullFinalize() { + if (finalized) { + throw InternalException("Calling PullFinalize on a pipeline that has been finalized already"); + } + finalized = true; + pipeline.executor.Flush(thread); +} + +void PipelineExecutor::GoToSource(idx_t ¤t_idx, idx_t initial_idx) { + // we go back to the first operator (the source) + current_idx = initial_idx; + if (!in_process_operators.empty()) { + // ... UNLESS there is an in process operator + // if there is an in-process operator, we start executing at the latest one + // for example, if we have a join operator that has tuples left, we first need to emit those tuples + current_idx = in_process_operators.top(); + in_process_operators.pop(); + } + D_ASSERT(current_idx >= initial_idx); +} + +OperatorResultType PipelineExecutor::Execute(DataChunk &input, DataChunk &result, idx_t initial_idx) { + if (input.size() == 0) { // LCOV_EXCL_START + return OperatorResultType::NEED_MORE_INPUT; + } // LCOV_EXCL_STOP + D_ASSERT(!pipeline.operators.empty()); + + idx_t current_idx; + GoToSource(current_idx, initial_idx); + if (current_idx == initial_idx) { + current_idx++; + } + if (current_idx > pipeline.operators.size()) { + result.Reference(input); + return OperatorResultType::NEED_MORE_INPUT; + } + while (true) { + if (context.client.interrupted) { + throw InterruptException(); + } + // now figure out where to put the chunk + // if current_idx is the last possible index (>= operators.size()) we write to the result + // otherwise we write to an intermediate chunk + auto current_intermediate = current_idx; + auto ¤t_chunk = + current_intermediate >= intermediate_chunks.size() ? result : *intermediate_chunks[current_intermediate]; + current_chunk.Reset(); + if (current_idx == initial_idx) { + // we went back to the source: we need more input + return OperatorResultType::NEED_MORE_INPUT; + } else { + auto &prev_chunk = + current_intermediate == initial_idx + 1 ? input : *intermediate_chunks[current_intermediate - 1]; + auto operator_idx = current_idx - 1; + auto current_operator = pipeline.operators[operator_idx]; + + // if current_idx > source_idx, we pass the previous' operators output through the Execute of the current + // operator + StartOperator(current_operator); + auto result = current_operator->Execute(context, prev_chunk, current_chunk, + *intermediate_states[current_intermediate - 1]); + EndOperator(current_operator, ¤t_chunk); + if (result == OperatorResultType::HAVE_MORE_OUTPUT) { + // more data remains in this operator + // push in-process marker + in_process_operators.push(current_idx); + } else if (result == OperatorResultType::FINISHED) { + D_ASSERT(current_chunk.size() == 0); + return OperatorResultType::FINISHED; + } + current_chunk.Verify(); + CacheChunk(current_chunk, operator_idx); + } + + if (current_chunk.size() == 0) { + // no output from this operator! + if (current_idx == initial_idx) { + // if we got no output from the scan, we are done + break; + } else { + // if we got no output from an intermediate op + // we go back and try to pull data from the source again + GoToSource(current_idx, initial_idx); + continue; + } + } else { + // we got output! continue to the next operator + current_idx++; + if (current_idx > pipeline.operators.size()) { + // if we got output and are at the last operator, we are finished executing for this output chunk + // return the data and push it into the chunk + break; + } + } + } + return in_process_operators.empty() ? OperatorResultType::NEED_MORE_INPUT : OperatorResultType::HAVE_MORE_OUTPUT; +} + +void PipelineExecutor::FetchFromSource(DataChunk &result) { + StartOperator(pipeline.source); + pipeline.source->GetData(context, result, *pipeline.source_state, *local_source_state); + EndOperator(pipeline.source, &result); +} + +void PipelineExecutor::InitializeChunk(DataChunk &chunk) { + PhysicalOperator *last_op = pipeline.operators.empty() ? pipeline.source : pipeline.operators.back(); + chunk.Initialize(last_op->GetTypes()); +} + +void PipelineExecutor::StartOperator(PhysicalOperator *op) { + if (context.client.interrupted) { + throw InterruptException(); + } + context.thread.profiler.StartOperator(op); +} + +void PipelineExecutor::EndOperator(PhysicalOperator *op, DataChunk *chunk) { + context.thread.profiler.EndOperator(chunk); + + if (chunk) { + chunk->Verify(); + } +} + +} // namespace duckdb + + + +namespace duckdb { + +PipelineFinishEvent::PipelineFinishEvent(shared_ptr pipeline_p) + : Event(pipeline_p->executor), pipeline(move(pipeline_p)) { +} + +void PipelineFinishEvent::Schedule() { +} + +void PipelineFinishEvent::FinishEvent() { + pipeline->Finalize(*this); +} + +} // namespace duckdb + + + + + + +#ifndef DUCKDB_NO_THREADS + + +// LICENSE_CHANGE_BEGIN +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// See the end of this file for a list + +// Provides a C++11 implementation of a multi-producer, multi-consumer lock-free queue. +// An overview, including benchmark results, is provided here: +// http://moodycamel.com/blog/2014/a-fast-general-purpose-lock-free-queue-for-c++ +// The full design is also described in excruciating detail at: +// http://moodycamel.com/blog/2014/detailed-design-of-a-lock-free-queue + +// Simplified BSD license: +// Copyright (c) 2013-2016, Cameron Desrochers. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// - Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +// TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + + +#if defined(__GNUC__) +// Disable -Wconversion warnings (spuriously triggered when Traits::size_t and +// Traits::index_t are set to < 32 bits, causing integer promotion, causing warnings +// upon assigning any computed values) + +#endif + +#if defined(__APPLE__) +#include +#endif + +#include // Requires C++11. Sorry VS2010. +#include +#include // for max_align_t +#include +#include +#include +#include +#include +#include +#include // for CHAR_BIT +#include +#include // partly for __WINPTHREADS_VERSION if on MinGW-w64 w/ POSIX threading + +// Platform-specific definitions of a numeric thread ID type and an invalid value +namespace duckdb_moodycamel { namespace details { + template struct thread_id_converter { + typedef thread_id_t thread_id_numeric_size_t; + typedef thread_id_t thread_id_hash_t; + static thread_id_hash_t prehash(thread_id_t const& x) { return x; } + }; +} } +#if defined(MCDBGQ_USE_RELACY) +namespace duckdb_moodycamel { namespace details { + typedef std::uint32_t thread_id_t; + static const thread_id_t invalid_thread_id = 0xFFFFFFFFU; + static const thread_id_t invalid_thread_id2 = 0xFFFFFFFEU; + static inline thread_id_t thread_id() { return rl::thread_index(); } +} } +#elif defined(_WIN32) || defined(__WINDOWS__) || defined(__WIN32__) +// No sense pulling in windows.h in a header, we'll manually declare the function +// we use and rely on backwards-compatibility for this not to break +extern "C" __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId(void); +namespace duckdb_moodycamel { namespace details { + static_assert(sizeof(unsigned long) == sizeof(std::uint32_t), "Expected size of unsigned long to be 32 bits on Windows"); + typedef std::uint32_t thread_id_t; + static const thread_id_t invalid_thread_id = 0; // See http://blogs.msdn.com/b/oldnewthing/archive/2004/02/23/78395.aspx + static const thread_id_t invalid_thread_id2 = 0xFFFFFFFFU; // Not technically guaranteed to be invalid, but is never used in practice. Note that all Win32 thread IDs are presently multiples of 4. + static inline thread_id_t thread_id() { return static_cast(::GetCurrentThreadId()); } +} } +#elif defined(__arm__) || defined(_M_ARM) || defined(__aarch64__) || (defined(__APPLE__) && TARGET_OS_IPHONE) +namespace duckdb_moodycamel { namespace details { + static_assert(sizeof(std::thread::id) == 4 || sizeof(std::thread::id) == 8, "std::thread::id is expected to be either 4 or 8 bytes"); + + typedef std::thread::id thread_id_t; + static const thread_id_t invalid_thread_id; // Default ctor creates invalid ID + + // Note we don't define a invalid_thread_id2 since std::thread::id doesn't have one; it's + // only used if MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED is defined anyway, which it won't + // be. + static inline thread_id_t thread_id() { return std::this_thread::get_id(); } + + template struct thread_id_size { }; + template<> struct thread_id_size<4> { typedef std::uint32_t numeric_t; }; + template<> struct thread_id_size<8> { typedef std::uint64_t numeric_t; }; + + template<> struct thread_id_converter { + typedef thread_id_size::numeric_t thread_id_numeric_size_t; +#ifndef __APPLE__ + typedef std::size_t thread_id_hash_t; +#else + typedef thread_id_numeric_size_t thread_id_hash_t; +#endif + + static thread_id_hash_t prehash(thread_id_t const& x) + { +#ifndef __APPLE__ + return std::hash()(x); +#else + return *reinterpret_cast(&x); +#endif + } + }; +} } +#else +// Use a nice trick from this answer: http://stackoverflow.com/a/8438730/21475 +// In order to get a numeric thread ID in a platform-independent way, we use a thread-local +// static variable's address as a thread identifier :-) +#if defined(__GNUC__) || defined(__INTEL_COMPILER) +#define MOODYCAMEL_THREADLOCAL __thread +#elif defined(_MSC_VER) +#define MOODYCAMEL_THREADLOCAL __declspec(thread) +#else +// Assume C++11 compliant compiler +#define MOODYCAMEL_THREADLOCAL thread_local +#endif +namespace duckdb_moodycamel { namespace details { + typedef std::uintptr_t thread_id_t; + static const thread_id_t invalid_thread_id = 0; // Address can't be nullptr +#ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED + static const thread_id_t invalid_thread_id2 = 1; // Member accesses off a null pointer are also generally invalid. Plus it's not aligned. +#endif + inline thread_id_t thread_id() { static MOODYCAMEL_THREADLOCAL int x; return reinterpret_cast(&x); } +} } +#endif + +// Constexpr if +#ifndef MOODYCAMEL_CONSTEXPR_IF +#if (defined(_MSC_VER) && defined(_HAS_CXX17) && _HAS_CXX17) || __cplusplus > 201402L +#define MOODYCAMEL_CONSTEXPR_IF if constexpr +#define MOODYCAMEL_MAYBE_UNUSED [[maybe_unused]] +#else +#define MOODYCAMEL_CONSTEXPR_IF if +#define MOODYCAMEL_MAYBE_UNUSED +#endif +#endif + +// Exceptions +#ifndef MOODYCAMEL_EXCEPTIONS_ENABLED +#if (defined(_MSC_VER) && defined(_CPPUNWIND)) || (defined(__GNUC__) && defined(__EXCEPTIONS)) || (!defined(_MSC_VER) && !defined(__GNUC__)) +#define MOODYCAMEL_EXCEPTIONS_ENABLED +#endif +#endif +#ifdef MOODYCAMEL_EXCEPTIONS_ENABLED +#define MOODYCAMEL_TRY try +#define MOODYCAMEL_CATCH(...) catch(__VA_ARGS__) +#define MOODYCAMEL_RETHROW throw +#define MOODYCAMEL_THROW(expr) throw (expr) +#else +#define MOODYCAMEL_TRY MOODYCAMEL_CONSTEXPR_IF (true) +#define MOODYCAMEL_CATCH(...) else MOODYCAMEL_CONSTEXPR_IF (false) +#define MOODYCAMEL_RETHROW +#define MOODYCAMEL_THROW(expr) +#endif + +#ifndef MOODYCAMEL_NOEXCEPT +#if !defined(MOODYCAMEL_EXCEPTIONS_ENABLED) +#define MOODYCAMEL_NOEXCEPT +#define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) true +#define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) true +#elif defined(_MSC_VER) && defined(_NOEXCEPT) && _MSC_VER < 1800 +// VS2012's std::is_nothrow_[move_]constructible is broken and returns true when it shouldn't :-( +// We have to assume *all* non-trivial constructors may throw on VS2012! +#define MOODYCAMEL_NOEXCEPT _NOEXCEPT +#define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) (std::is_rvalue_reference::value && std::is_move_constructible::value ? std::is_trivially_move_constructible::value : std::is_trivially_copy_constructible::value) +#define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) ((std::is_rvalue_reference::value && std::is_move_assignable::value ? std::is_trivially_move_assignable::value || std::is_nothrow_move_assignable::value : std::is_trivially_copy_assignable::value || std::is_nothrow_copy_assignable::value) && MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr)) +#elif defined(_MSC_VER) && defined(_NOEXCEPT) && _MSC_VER < 1900 +#define MOODYCAMEL_NOEXCEPT _NOEXCEPT +#define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) (std::is_rvalue_reference::value && std::is_move_constructible::value ? std::is_trivially_move_constructible::value || std::is_nothrow_move_constructible::value : std::is_trivially_copy_constructible::value || std::is_nothrow_copy_constructible::value) +#define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) ((std::is_rvalue_reference::value && std::is_move_assignable::value ? std::is_trivially_move_assignable::value || std::is_nothrow_move_assignable::value : std::is_trivially_copy_assignable::value || std::is_nothrow_copy_assignable::value) && MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr)) +#else +#define MOODYCAMEL_NOEXCEPT noexcept +#define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) noexcept(expr) +#define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) noexcept(expr) +#endif +#endif + +#ifndef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED +#ifdef MCDBGQ_USE_RELACY +#define MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED +#else +// VS2013 doesn't support `thread_local`, and MinGW-w64 w/ POSIX threading has a crippling bug: http://sourceforge.net/p/mingw-w64/bugs/445 +// g++ <=4.7 doesn't support thread_local either. +// Finally, iOS/ARM doesn't have support for it either, and g++/ARM allows it to compile but it's unconfirmed to actually work +#if (!defined(_MSC_VER) || _MSC_VER >= 1900) && (!defined(__MINGW32__) && !defined(__MINGW64__) || !defined(__WINPTHREADS_VERSION)) && (!defined(__GNUC__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) && (!defined(__APPLE__) || !TARGET_OS_IPHONE) && !defined(__arm__) && !defined(_M_ARM) && !defined(__aarch64__) +// Assume `thread_local` is fully supported in all other C++11 compilers/platforms +//#define MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED // always disabled for now since several users report having problems with it on +#endif +#endif +#endif + +// VS2012 doesn't support deleted functions. +// In this case, we declare the function normally but don't define it. A link error will be generated if the function is called. +#ifndef MOODYCAMEL_DELETE_FUNCTION +#if defined(_MSC_VER) && _MSC_VER < 1800 +#define MOODYCAMEL_DELETE_FUNCTION +#else +#define MOODYCAMEL_DELETE_FUNCTION = delete +#endif +#endif + +#ifndef MOODYCAMEL_ALIGNAS +// VS2013 doesn't support alignas or alignof +#if defined(_MSC_VER) && _MSC_VER <= 1800 +#define MOODYCAMEL_ALIGNAS(alignment) __declspec(align(alignment)) +#define MOODYCAMEL_ALIGNOF(obj) __alignof(obj) +#else +#define MOODYCAMEL_ALIGNAS(alignment) alignas(alignment) +#define MOODYCAMEL_ALIGNOF(obj) alignof(obj) +#endif +#endif + + + +// Compiler-specific likely/unlikely hints +namespace duckdb_moodycamel { namespace details { + +#if defined(__GNUC__) + static inline bool (likely)(bool x) { return __builtin_expect((x), true); } +// static inline bool (unlikely)(bool x) { return __builtin_expect((x), false); } +#else + static inline bool (likely)(bool x) { return x; } +// static inline bool (unlikely)(bool x) { return x; } +#endif +} } + +namespace duckdb_moodycamel { +namespace details { + template + struct const_numeric_max { + static_assert(std::is_integral::value, "const_numeric_max can only be used with integers"); + static const T value = std::numeric_limits::is_signed + ? (static_cast(1) << (sizeof(T) * CHAR_BIT - 1)) - static_cast(1) + : static_cast(-1); + }; + +#if defined(__GLIBCXX__) + typedef ::max_align_t std_max_align_t; // libstdc++ forgot to add it to std:: for a while +#else + typedef std::max_align_t std_max_align_t; // Others (e.g. MSVC) insist it can *only* be accessed via std:: +#endif + + // Some platforms have incorrectly set max_align_t to a type with <8 bytes alignment even while supporting + // 8-byte aligned scalar values (*cough* 32-bit iOS). Work around this with our own union. See issue #64. + typedef union { + std_max_align_t x; + long long y; + void* z; + } max_align_t; +} + +// Default traits for the ConcurrentQueue. To change some of the +// traits without re-implementing all of them, inherit from this +// struct and shadow the declarations you wish to be different; +// since the traits are used as a template type parameter, the +// shadowed declarations will be used where defined, and the defaults +// otherwise. +struct ConcurrentQueueDefaultTraits +{ + // General-purpose size type. std::size_t is strongly recommended. + typedef std::size_t size_t; + + // The type used for the enqueue and dequeue indices. Must be at least as + // large as size_t. Should be significantly larger than the number of elements + // you expect to hold at once, especially if you have a high turnover rate; + // for example, on 32-bit x86, if you expect to have over a hundred million + // elements or pump several million elements through your queue in a very + // short space of time, using a 32-bit type *may* trigger a race condition. + // A 64-bit int type is recommended in that case, and in practice will + // prevent a race condition no matter the usage of the queue. Note that + // whether the queue is lock-free with a 64-int type depends on the whether + // std::atomic is lock-free, which is platform-specific. + typedef std::size_t index_t; + + // Internally, all elements are enqueued and dequeued from multi-element + // blocks; this is the smallest controllable unit. If you expect few elements + // but many producers, a smaller block size should be favoured. For few producers + // and/or many elements, a larger block size is preferred. A sane default + // is provided. Must be a power of 2. + static const size_t BLOCK_SIZE = 32; + + // For explicit producers (i.e. when using a producer token), the block is + // checked for being empty by iterating through a list of flags, one per element. + // For large block sizes, this is too inefficient, and switching to an atomic + // counter-based approach is faster. The switch is made for block sizes strictly + // larger than this threshold. + static const size_t EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD = 32; + + // How many full blocks can be expected for a single explicit producer? This should + // reflect that number's maximum for optimal performance. Must be a power of 2. + static const size_t EXPLICIT_INITIAL_INDEX_SIZE = 32; + + // How many full blocks can be expected for a single implicit producer? This should + // reflect that number's maximum for optimal performance. Must be a power of 2. + static const size_t IMPLICIT_INITIAL_INDEX_SIZE = 32; + + // The initial size of the hash table mapping thread IDs to implicit producers. + // Note that the hash is resized every time it becomes half full. + // Must be a power of two, and either 0 or at least 1. If 0, implicit production + // (using the enqueue methods without an explicit producer token) is disabled. + static const size_t INITIAL_IMPLICIT_PRODUCER_HASH_SIZE = 32; + + // Controls the number of items that an explicit consumer (i.e. one with a token) + // must consume before it causes all consumers to rotate and move on to the next + // internal queue. + static const std::uint32_t EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE = 256; + + // The maximum number of elements (inclusive) that can be enqueued to a sub-queue. + // Enqueue operations that would cause this limit to be surpassed will fail. Note + // that this limit is enforced at the block level (for performance reasons), i.e. + // it's rounded up to the nearest block size. + static const size_t MAX_SUBQUEUE_SIZE = details::const_numeric_max::value; + + +#ifndef MCDBGQ_USE_RELACY + // Memory allocation can be customized if needed. + // malloc should return nullptr on failure, and handle alignment like std::malloc. +#if defined(malloc) || defined(free) + // Gah, this is 2015, stop defining macros that break standard code already! + // Work around malloc/free being special macros: + static inline void* WORKAROUND_malloc(size_t size) { return malloc(size); } + static inline void WORKAROUND_free(void* ptr) { return free(ptr); } + static inline void* (malloc)(size_t size) { return WORKAROUND_malloc(size); } + static inline void (free)(void* ptr) { return WORKAROUND_free(ptr); } +#else + static inline void* malloc(size_t size) { return std::malloc(size); } + static inline void free(void* ptr) { return std::free(ptr); } +#endif +#else + // Debug versions when running under the Relacy race detector (ignore + // these in user code) + static inline void* malloc(size_t size) { return rl::rl_malloc(size, $); } + static inline void free(void* ptr) { return rl::rl_free(ptr, $); } +#endif +}; + + +// When producing or consuming many elements, the most efficient way is to: +// 1) Use one of the bulk-operation methods of the queue with a token +// 2) Failing that, use the bulk-operation methods without a token +// 3) Failing that, create a token and use that with the single-item methods +// 4) Failing that, use the single-parameter methods of the queue +// Having said that, don't create tokens willy-nilly -- ideally there should be +// a maximum of one token per thread (of each kind). +struct ProducerToken; +struct ConsumerToken; + +template class ConcurrentQueue; +template class BlockingConcurrentQueue; +class ConcurrentQueueTests; + + +namespace details +{ + struct ConcurrentQueueProducerTypelessBase + { + ConcurrentQueueProducerTypelessBase* next; + std::atomic inactive; + ProducerToken* token; + + ConcurrentQueueProducerTypelessBase() + : next(nullptr), inactive(false), token(nullptr) + { + } + }; + + template struct _hash_32_or_64 { + static inline std::uint32_t hash(std::uint32_t h) + { + // MurmurHash3 finalizer -- see https://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp + // Since the thread ID is already unique, all we really want to do is propagate that + // uniqueness evenly across all the bits, so that we can use a subset of the bits while + // reducing collisions significantly + h ^= h >> 16; + h *= 0x85ebca6b; + h ^= h >> 13; + h *= 0xc2b2ae35; + return h ^ (h >> 16); + } + }; + template<> struct _hash_32_or_64<1> { + static inline std::uint64_t hash(std::uint64_t h) + { + h ^= h >> 33; + h *= 0xff51afd7ed558ccd; + h ^= h >> 33; + h *= 0xc4ceb9fe1a85ec53; + return h ^ (h >> 33); + } + }; + template struct hash_32_or_64 : public _hash_32_or_64<(size > 4)> { }; + + static inline size_t hash_thread_id(thread_id_t id) + { + static_assert(sizeof(thread_id_t) <= 8, "Expected a platform where thread IDs are at most 64-bit values"); + return static_cast(hash_32_or_64::thread_id_hash_t)>::hash( + thread_id_converter::prehash(id))); + } + + template + static inline bool circular_less_than(T a, T b) + { +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4554) +#endif + static_assert(std::is_integral::value && !std::numeric_limits::is_signed, "circular_less_than is intended to be used only with unsigned integer types"); + return static_cast(a - b) > static_cast(static_cast(1) << static_cast(sizeof(T) * CHAR_BIT - 1)); +#ifdef _MSC_VER +#pragma warning(pop) +#endif + } + + template + static inline char* align_for(char* ptr) + { + const std::size_t alignment = std::alignment_of::value; + return ptr + (alignment - (reinterpret_cast(ptr) % alignment)) % alignment; + } + + template + static inline T ceil_to_pow_2(T x) + { + static_assert(std::is_integral::value && !std::numeric_limits::is_signed, "ceil_to_pow_2 is intended to be used only with unsigned integer types"); + + // Adapted from http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 + --x; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + for (std::size_t i = 1; i < sizeof(T); i <<= 1) { + x |= x >> (i << 3); + } + ++x; + return x; + } + + template + static inline void swap_relaxed(std::atomic& left, std::atomic& right) + { + T temp = std::move(left.load(std::memory_order_relaxed)); + left.store(std::move(right.load(std::memory_order_relaxed)), std::memory_order_relaxed); + right.store(std::move(temp), std::memory_order_relaxed); + } + + template + static inline T const& nomove(T const& x) + { + return x; + } + + template + struct nomove_if + { + template + static inline T const& eval(T const& x) + { + return x; + } + }; + + template<> + struct nomove_if + { + template + static inline auto eval(U&& x) + -> decltype(std::forward(x)) + { + return std::forward(x); + } + }; + + template + static inline auto deref_noexcept(It& it) MOODYCAMEL_NOEXCEPT -> decltype(*it) + { + return *it; + } + +#if defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + template struct is_trivially_destructible : std::is_trivially_destructible { }; +#else + template struct is_trivially_destructible : std::has_trivial_destructor { }; +#endif + +#ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED +#ifdef MCDBGQ_USE_RELACY + typedef RelacyThreadExitListener ThreadExitListener; + typedef RelacyThreadExitNotifier ThreadExitNotifier; +#else + struct ThreadExitListener + { + typedef void (*callback_t)(void*); + callback_t callback; + void* userData; + + ThreadExitListener* next; // reserved for use by the ThreadExitNotifier + }; + + + class ThreadExitNotifier + { + public: + static void subscribe(ThreadExitListener* listener) + { + auto& tlsInst = instance(); + listener->next = tlsInst.tail; + tlsInst.tail = listener; + } + + static void unsubscribe(ThreadExitListener* listener) + { + auto& tlsInst = instance(); + ThreadExitListener** prev = &tlsInst.tail; + for (auto ptr = tlsInst.tail; ptr != nullptr; ptr = ptr->next) { + if (ptr == listener) { + *prev = ptr->next; + break; + } + prev = &ptr->next; + } + } + + private: + ThreadExitNotifier() : tail(nullptr) { } + ThreadExitNotifier(ThreadExitNotifier const&) MOODYCAMEL_DELETE_FUNCTION; + ThreadExitNotifier& operator=(ThreadExitNotifier const&) MOODYCAMEL_DELETE_FUNCTION; + + ~ThreadExitNotifier() + { + // This thread is about to exit, let everyone know! + assert(this == &instance() && "If this assert fails, you likely have a buggy compiler! Change the preprocessor conditions such that MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED is no longer defined."); + for (auto ptr = tail; ptr != nullptr; ptr = ptr->next) { + ptr->callback(ptr->userData); + } + } + + // Thread-local + static inline ThreadExitNotifier& instance() + { + static thread_local ThreadExitNotifier notifier; + return notifier; + } + + private: + ThreadExitListener* tail; + }; +#endif +#endif + + template struct static_is_lock_free_num { enum { value = 0 }; }; + template<> struct static_is_lock_free_num { enum { value = ATOMIC_CHAR_LOCK_FREE }; }; + template<> struct static_is_lock_free_num { enum { value = ATOMIC_SHORT_LOCK_FREE }; }; + template<> struct static_is_lock_free_num { enum { value = ATOMIC_INT_LOCK_FREE }; }; + template<> struct static_is_lock_free_num { enum { value = ATOMIC_LONG_LOCK_FREE }; }; + template<> struct static_is_lock_free_num { enum { value = ATOMIC_LLONG_LOCK_FREE }; }; + template struct static_is_lock_free : static_is_lock_free_num::type> { }; + template<> struct static_is_lock_free { enum { value = ATOMIC_BOOL_LOCK_FREE }; }; + template struct static_is_lock_free { enum { value = ATOMIC_POINTER_LOCK_FREE }; }; +} + + +struct ProducerToken +{ + template + explicit ProducerToken(ConcurrentQueue& queue); + + template + explicit ProducerToken(BlockingConcurrentQueue& queue); + + ProducerToken(ProducerToken&& other) MOODYCAMEL_NOEXCEPT + : producer(other.producer) + { + other.producer = nullptr; + if (producer != nullptr) { + producer->token = this; + } + } + + inline ProducerToken& operator=(ProducerToken&& other) MOODYCAMEL_NOEXCEPT + { + swap(other); + return *this; + } + + void swap(ProducerToken& other) MOODYCAMEL_NOEXCEPT + { + std::swap(producer, other.producer); + if (producer != nullptr) { + producer->token = this; + } + if (other.producer != nullptr) { + other.producer->token = &other; + } + } + + // A token is always valid unless: + // 1) Memory allocation failed during construction + // 2) It was moved via the move constructor + // (Note: assignment does a swap, leaving both potentially valid) + // 3) The associated queue was destroyed + // Note that if valid() returns true, that only indicates + // that the token is valid for use with a specific queue, + // but not which one; that's up to the user to track. + inline bool valid() const { return producer != nullptr; } + + ~ProducerToken() + { + if (producer != nullptr) { + producer->token = nullptr; + producer->inactive.store(true, std::memory_order_release); + } + } + + // Disable copying and assignment + ProducerToken(ProducerToken const&) MOODYCAMEL_DELETE_FUNCTION; + ProducerToken& operator=(ProducerToken const&) MOODYCAMEL_DELETE_FUNCTION; + +private: + template friend class ConcurrentQueue; + friend class ConcurrentQueueTests; + +protected: + details::ConcurrentQueueProducerTypelessBase* producer; +}; + + +struct ConsumerToken +{ + template + explicit ConsumerToken(ConcurrentQueue& q); + + template + explicit ConsumerToken(BlockingConcurrentQueue& q); + + ConsumerToken(ConsumerToken&& other) MOODYCAMEL_NOEXCEPT + : initialOffset(other.initialOffset), lastKnownGlobalOffset(other.lastKnownGlobalOffset), itemsConsumedFromCurrent(other.itemsConsumedFromCurrent), currentProducer(other.currentProducer), desiredProducer(other.desiredProducer) + { + } + + inline ConsumerToken& operator=(ConsumerToken&& other) MOODYCAMEL_NOEXCEPT + { + swap(other); + return *this; + } + + void swap(ConsumerToken& other) MOODYCAMEL_NOEXCEPT + { + std::swap(initialOffset, other.initialOffset); + std::swap(lastKnownGlobalOffset, other.lastKnownGlobalOffset); + std::swap(itemsConsumedFromCurrent, other.itemsConsumedFromCurrent); + std::swap(currentProducer, other.currentProducer); + std::swap(desiredProducer, other.desiredProducer); + } + + // Disable copying and assignment + ConsumerToken(ConsumerToken const&) MOODYCAMEL_DELETE_FUNCTION; + ConsumerToken& operator=(ConsumerToken const&) MOODYCAMEL_DELETE_FUNCTION; + +private: + template friend class ConcurrentQueue; + friend class ConcurrentQueueTests; + +private: // but shared with ConcurrentQueue + std::uint32_t initialOffset; + std::uint32_t lastKnownGlobalOffset; + std::uint32_t itemsConsumedFromCurrent; + details::ConcurrentQueueProducerTypelessBase* currentProducer; + details::ConcurrentQueueProducerTypelessBase* desiredProducer; +}; + +// Need to forward-declare this swap because it's in a namespace. +// See http://stackoverflow.com/questions/4492062/why-does-a-c-friend-class-need-a-forward-declaration-only-in-other-namespaces +template +inline void swap(typename ConcurrentQueue::ImplicitProducerKVP& a, typename ConcurrentQueue::ImplicitProducerKVP& b) MOODYCAMEL_NOEXCEPT; + + +template +class ConcurrentQueue +{ +public: + typedef ::duckdb_moodycamel::ProducerToken producer_token_t; + typedef ::duckdb_moodycamel::ConsumerToken consumer_token_t; + + typedef typename Traits::index_t index_t; + typedef typename Traits::size_t size_t; + + static const size_t BLOCK_SIZE = static_cast(Traits::BLOCK_SIZE); + static const size_t EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD = static_cast(Traits::EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD); + static const size_t EXPLICIT_INITIAL_INDEX_SIZE = static_cast(Traits::EXPLICIT_INITIAL_INDEX_SIZE); + static const size_t IMPLICIT_INITIAL_INDEX_SIZE = static_cast(Traits::IMPLICIT_INITIAL_INDEX_SIZE); + static const size_t INITIAL_IMPLICIT_PRODUCER_HASH_SIZE = static_cast(Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE); + static const std::uint32_t EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE = static_cast(Traits::EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE); +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4307) // + integral constant overflow (that's what the ternary expression is for!) +#pragma warning(disable: 4309) // static_cast: Truncation of constant value +#endif + static const size_t MAX_SUBQUEUE_SIZE = (details::const_numeric_max::value - static_cast(Traits::MAX_SUBQUEUE_SIZE) < BLOCK_SIZE) ? details::const_numeric_max::value : ((static_cast(Traits::MAX_SUBQUEUE_SIZE) + (BLOCK_SIZE - 1)) / BLOCK_SIZE * BLOCK_SIZE); +#ifdef _MSC_VER +#pragma warning(pop) +#endif + + static_assert(!std::numeric_limits::is_signed && std::is_integral::value, "Traits::size_t must be an unsigned integral type"); + static_assert(!std::numeric_limits::is_signed && std::is_integral::value, "Traits::index_t must be an unsigned integral type"); + static_assert(sizeof(index_t) >= sizeof(size_t), "Traits::index_t must be at least as wide as Traits::size_t"); + static_assert((BLOCK_SIZE > 1) && !(BLOCK_SIZE & (BLOCK_SIZE - 1)), "Traits::BLOCK_SIZE must be a power of 2 (and at least 2)"); + static_assert((EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD > 1) && !(EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD & (EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD - 1)), "Traits::EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD must be a power of 2 (and greater than 1)"); + static_assert((EXPLICIT_INITIAL_INDEX_SIZE > 1) && !(EXPLICIT_INITIAL_INDEX_SIZE & (EXPLICIT_INITIAL_INDEX_SIZE - 1)), "Traits::EXPLICIT_INITIAL_INDEX_SIZE must be a power of 2 (and greater than 1)"); + static_assert((IMPLICIT_INITIAL_INDEX_SIZE > 1) && !(IMPLICIT_INITIAL_INDEX_SIZE & (IMPLICIT_INITIAL_INDEX_SIZE - 1)), "Traits::IMPLICIT_INITIAL_INDEX_SIZE must be a power of 2 (and greater than 1)"); + static_assert((INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) || !(INITIAL_IMPLICIT_PRODUCER_HASH_SIZE & (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE - 1)), "Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE must be a power of 2"); + static_assert(INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0 || INITIAL_IMPLICIT_PRODUCER_HASH_SIZE >= 1, "Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE must be at least 1 (or 0 to disable implicit enqueueing)"); + +public: + // Creates a queue with at least `capacity` element slots; note that the + // actual number of elements that can be inserted without additional memory + // allocation depends on the number of producers and the block size (e.g. if + // the block size is equal to `capacity`, only a single block will be allocated + // up-front, which means only a single producer will be able to enqueue elements + // without an extra allocation -- blocks aren't shared between producers). + // This method is not thread safe -- it is up to the user to ensure that the + // queue is fully constructed before it starts being used by other threads (this + // includes making the memory effects of construction visible, possibly with a + // memory barrier). + explicit ConcurrentQueue(size_t capacity = 6 * BLOCK_SIZE) + : producerListTail(nullptr), + producerCount(0), + initialBlockPoolIndex(0), + nextExplicitConsumerId(0), + globalExplicitConsumerOffset(0) + { + implicitProducerHashResizeInProgress.clear(std::memory_order_relaxed); + populate_initial_implicit_producer_hash(); + populate_initial_block_list(capacity / BLOCK_SIZE + ((capacity & (BLOCK_SIZE - 1)) == 0 ? 0 : 1)); + +#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG + // Track all the producers using a fully-resolved typed list for + // each kind; this makes it possible to debug them starting from + // the root queue object (otherwise wacky casts are needed that + // don't compile in the debugger's expression evaluator). + explicitProducers.store(nullptr, std::memory_order_relaxed); + implicitProducers.store(nullptr, std::memory_order_relaxed); +#endif + } + + // Computes the correct amount of pre-allocated blocks for you based + // on the minimum number of elements you want available at any given + // time, and the maximum concurrent number of each type of producer. + ConcurrentQueue(size_t minCapacity, size_t maxExplicitProducers, size_t maxImplicitProducers) + : producerListTail(nullptr), + producerCount(0), + initialBlockPoolIndex(0), + nextExplicitConsumerId(0), + globalExplicitConsumerOffset(0) + { + implicitProducerHashResizeInProgress.clear(std::memory_order_relaxed); + populate_initial_implicit_producer_hash(); + size_t blocks = (((minCapacity + BLOCK_SIZE - 1) / BLOCK_SIZE) - 1) * (maxExplicitProducers + 1) + 2 * (maxExplicitProducers + maxImplicitProducers); + populate_initial_block_list(blocks); + +#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG + explicitProducers.store(nullptr, std::memory_order_relaxed); + implicitProducers.store(nullptr, std::memory_order_relaxed); +#endif + } + + // Note: The queue should not be accessed concurrently while it's + // being deleted. It's up to the user to synchronize this. + // This method is not thread safe. + ~ConcurrentQueue() + { + // Destroy producers + auto ptr = producerListTail.load(std::memory_order_relaxed); + while (ptr != nullptr) { + auto next = ptr->next_prod(); + if (ptr->token != nullptr) { + ptr->token->producer = nullptr; + } + destroy(ptr); + ptr = next; + } + + // Destroy implicit producer hash tables + MOODYCAMEL_CONSTEXPR_IF (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE != 0) { + auto hash = implicitProducerHash.load(std::memory_order_relaxed); + while (hash != nullptr) { + auto prev = hash->prev; + if (prev != nullptr) { // The last hash is part of this object and was not allocated dynamically + for (size_t i = 0; i != hash->capacity; ++i) { + hash->entries[i].~ImplicitProducerKVP(); + } + hash->~ImplicitProducerHash(); + (Traits::free)(hash); + } + hash = prev; + } + } + + // Destroy global free list + auto block = freeList.head_unsafe(); + while (block != nullptr) { + auto next = block->freeListNext.load(std::memory_order_relaxed); + if (block->dynamicallyAllocated) { + destroy(block); + } + block = next; + } + + // Destroy initial free list + destroy_array(initialBlockPool, initialBlockPoolSize); + } + + // Disable copying and copy assignment + ConcurrentQueue(ConcurrentQueue const&) MOODYCAMEL_DELETE_FUNCTION; + ConcurrentQueue& operator=(ConcurrentQueue const&) MOODYCAMEL_DELETE_FUNCTION; + + // Moving is supported, but note that it is *not* a thread-safe operation. + // Nobody can use the queue while it's being moved, and the memory effects + // of that move must be propagated to other threads before they can use it. + // Note: When a queue is moved, its tokens are still valid but can only be + // used with the destination queue (i.e. semantically they are moved along + // with the queue itself). + ConcurrentQueue(ConcurrentQueue&& other) MOODYCAMEL_NOEXCEPT + : producerListTail(other.producerListTail.load(std::memory_order_relaxed)), + producerCount(other.producerCount.load(std::memory_order_relaxed)), + initialBlockPoolIndex(other.initialBlockPoolIndex.load(std::memory_order_relaxed)), + initialBlockPool(other.initialBlockPool), + initialBlockPoolSize(other.initialBlockPoolSize), + freeList(std::move(other.freeList)), + nextExplicitConsumerId(other.nextExplicitConsumerId.load(std::memory_order_relaxed)), + globalExplicitConsumerOffset(other.globalExplicitConsumerOffset.load(std::memory_order_relaxed)) + { + // Move the other one into this, and leave the other one as an empty queue + implicitProducerHashResizeInProgress.clear(std::memory_order_relaxed); + populate_initial_implicit_producer_hash(); + swap_implicit_producer_hashes(other); + + other.producerListTail.store(nullptr, std::memory_order_relaxed); + other.producerCount.store(0, std::memory_order_relaxed); + other.nextExplicitConsumerId.store(0, std::memory_order_relaxed); + other.globalExplicitConsumerOffset.store(0, std::memory_order_relaxed); + +#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG + explicitProducers.store(other.explicitProducers.load(std::memory_order_relaxed), std::memory_order_relaxed); + other.explicitProducers.store(nullptr, std::memory_order_relaxed); + implicitProducers.store(other.implicitProducers.load(std::memory_order_relaxed), std::memory_order_relaxed); + other.implicitProducers.store(nullptr, std::memory_order_relaxed); +#endif + + other.initialBlockPoolIndex.store(0, std::memory_order_relaxed); + other.initialBlockPoolSize = 0; + other.initialBlockPool = nullptr; + + reown_producers(); + } + + inline ConcurrentQueue& operator=(ConcurrentQueue&& other) MOODYCAMEL_NOEXCEPT + { + return swap_internal(other); + } + + // Swaps this queue's state with the other's. Not thread-safe. + // Swapping two queues does not invalidate their tokens, however + // the tokens that were created for one queue must be used with + // only the swapped queue (i.e. the tokens are tied to the + // queue's movable state, not the object itself). + inline void swap(ConcurrentQueue& other) MOODYCAMEL_NOEXCEPT + { + swap_internal(other); + } + +private: + ConcurrentQueue& swap_internal(ConcurrentQueue& other) + { + if (this == &other) { + return *this; + } + + details::swap_relaxed(producerListTail, other.producerListTail); + details::swap_relaxed(producerCount, other.producerCount); + details::swap_relaxed(initialBlockPoolIndex, other.initialBlockPoolIndex); + std::swap(initialBlockPool, other.initialBlockPool); + std::swap(initialBlockPoolSize, other.initialBlockPoolSize); + freeList.swap(other.freeList); + details::swap_relaxed(nextExplicitConsumerId, other.nextExplicitConsumerId); + details::swap_relaxed(globalExplicitConsumerOffset, other.globalExplicitConsumerOffset); + + swap_implicit_producer_hashes(other); + + reown_producers(); + other.reown_producers(); + +#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG + details::swap_relaxed(explicitProducers, other.explicitProducers); + details::swap_relaxed(implicitProducers, other.implicitProducers); +#endif + + return *this; + } + +public: + // Enqueues a single item (by copying it). + // Allocates memory if required. Only fails if memory allocation fails (or implicit + // production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0, + // or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed). + // Thread-safe. inline bool enqueue(T const& item) { MOODYCAMEL_CONSTEXPR_IF (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false; @@ -120546,7 +131575,7 @@ inline void swap(typename ConcurrentQueue::ImplicitProducerKVP& a, ty // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #7 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 // See the end of this file for a list // Provides an efficient implementation of a semaphore (LightweightSemaphore). @@ -121078,7 +132107,11 @@ TaskScheduler::~TaskScheduler() { } TaskScheduler &TaskScheduler::GetScheduler(ClientContext &context) { - return context.db->GetScheduler(); + return TaskScheduler::GetScheduler(DatabaseInstance::GetDatabase(context)); +} + +TaskScheduler &TaskScheduler::GetScheduler(DatabaseInstance &db) { + return db.GetScheduler(); } unique_ptr TaskScheduler::CreateProducer() { @@ -121103,7 +132136,7 @@ void TaskScheduler::ExecuteForever(atomic *marker) { // wait for a signal with a timeout; the timeout allows us to periodically check queue->semaphore.wait(TASK_TIMEOUT_USECS); if (queue->q.try_dequeue(task)) { - task->Execute(); + task->Execute(TaskExecutionMode::PROCESS_ALL); task.reset(); } } @@ -121176,7 +132209,7 @@ void TaskScheduler::SetThreadsInternal(int32_t n) { namespace duckdb { -ThreadContext::ThreadContext(ClientContext &context) : profiler(context.profiler->IsEnabled()) { +ThreadContext::ThreadContext(ClientContext &context) : profiler(QueryProfiler::Get(context).IsEnabled()) { } } // namespace duckdb @@ -121210,6 +132243,13 @@ bool BaseExpression::Equals(const BaseExpression *other) const { 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, unique_ptr default_value) + : name(move(name_p)), type(move(type_p)), default_value(move(default_value)) { +} + ColumnDefinition ColumnDefinition::Copy() const { ColumnDefinition copy(name, type); copy.oid = oid; @@ -121219,15 +132259,20 @@ ColumnDefinition ColumnDefinition::Copy() const { } void ColumnDefinition::Serialize(Serializer &serializer) const { - serializer.WriteString(name); - type.Serialize(serializer); - serializer.WriteOptional(default_value); + FieldWriter writer(serializer); + writer.WriteString(name); + writer.WriteSerializable(type); + writer.WriteOptional(default_value); + writer.Finalize(); } ColumnDefinition ColumnDefinition::Deserialize(Deserializer &source) { - auto column_name = source.Read(); - auto column_type = LogicalType::Deserialize(source); - auto default_value = source.ReadOptional(); + FieldReader reader(source); + auto column_name = reader.ReadRequired(); + auto column_type = reader.ReadRequiredSerializable(); + auto default_value = reader.ReadOptional(nullptr); + reader.Finalize(); + return ColumnDefinition(column_name, column_type, move(default_value)); } @@ -121238,27 +132283,44 @@ ColumnDefinition ColumnDefinition::Deserialize(Deserializer &source) { + namespace duckdb { -void Constraint::Serialize(Serializer &serializer) { - serializer.Write(type); +Constraint::Constraint(ConstraintType type) : type(type) { +} + +Constraint::~Constraint() { +} + +void Constraint::Serialize(Serializer &serializer) const { + FieldWriter writer(serializer); + writer.WriteField(type); + Serialize(writer); + writer.Finalize(); } unique_ptr Constraint::Deserialize(Deserializer &source) { - auto type = source.Read(); + FieldReader reader(source); + auto type = reader.ReadRequired(); + unique_ptr result; switch (type) { case ConstraintType::NOT_NULL: - return NotNullConstraint::Deserialize(source); + result = NotNullConstraint::Deserialize(reader); + break; case ConstraintType::CHECK: - return CheckConstraint::Deserialize(source); + result = CheckConstraint::Deserialize(reader); + break; case ConstraintType::UNIQUE: - return UniqueConstraint::Deserialize(source); + result = UniqueConstraint::Deserialize(reader); + break; default: throw InternalException("Unrecognized constraint type for serialization"); } + reader.Finalize(); + return result; } -void Constraint::Print() { +void Constraint::Print() const { Printer::Print(ToString()); } @@ -121269,21 +132331,24 @@ void Constraint::Print() { namespace duckdb { +CheckConstraint::CheckConstraint(unique_ptr expression) + : Constraint(ConstraintType::CHECK), expression(move(expression)) { +} + string CheckConstraint::ToString() const { return "CHECK(" + expression->ToString() + ")"; } -unique_ptr CheckConstraint::Copy() { +unique_ptr CheckConstraint::Copy() const { return make_unique(expression->Copy()); } -void CheckConstraint::Serialize(Serializer &serializer) { - Constraint::Serialize(serializer); - expression->Serialize(serializer); +void CheckConstraint::Serialize(FieldWriter &writer) const { + writer.WriteSerializable(*expression); } -unique_ptr CheckConstraint::Deserialize(Deserializer &source) { - auto expression = ParsedExpression::Deserialize(source); +unique_ptr CheckConstraint::Deserialize(FieldReader &source) { + auto expression = source.ReadRequiredSerializable(); return make_unique(move(expression)); } @@ -121294,21 +132359,26 @@ unique_ptr CheckConstraint::Deserialize(Deserializer &source) { namespace duckdb { +NotNullConstraint::NotNullConstraint(column_t index) : Constraint(ConstraintType::NOT_NULL), index(index) { +} + +NotNullConstraint::~NotNullConstraint() { +} + string NotNullConstraint::ToString() const { return "NOT NULL"; } -unique_ptr NotNullConstraint::Copy() { +unique_ptr NotNullConstraint::Copy() const { return make_unique(index); } -void NotNullConstraint::Serialize(Serializer &serializer) { - Constraint::Serialize(serializer); - serializer.Write(index); +void NotNullConstraint::Serialize(FieldWriter &writer) const { + writer.WriteField(index); } -unique_ptr NotNullConstraint::Deserialize(Deserializer &source) { - auto index = source.Read(); +unique_ptr NotNullConstraint::Deserialize(FieldReader &source) { + auto index = source.ReadRequired(); return make_unique_base(index); } @@ -121321,6 +132391,14 @@ unique_ptr NotNullConstraint::Deserialize(Deserializer &source) { namespace duckdb { +UniqueConstraint::UniqueConstraint(uint64_t 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)), + is_primary_key(is_primary_key) { +} + string UniqueConstraint::ToString() const { string base = is_primary_key ? "PRIMARY KEY(" : "UNIQUE("; for (idx_t i = 0; i < columns.size(); i++) { @@ -121332,8 +132410,8 @@ string UniqueConstraint::ToString() const { return base + ")"; } -unique_ptr UniqueConstraint::Copy() { - if (index == INVALID_INDEX) { +unique_ptr UniqueConstraint::Copy() const { + if (index == DConstants::INVALID_INDEX) { return make_unique(columns, is_primary_key); } else { auto result = make_unique(index, is_primary_key); @@ -121342,28 +132420,19 @@ unique_ptr UniqueConstraint::Copy() { } } -void UniqueConstraint::Serialize(Serializer &serializer) { - Constraint::Serialize(serializer); - serializer.Write(is_primary_key); - serializer.Write(index); +void UniqueConstraint::Serialize(FieldWriter &writer) const { + writer.WriteField(is_primary_key); + writer.WriteField(index); D_ASSERT(columns.size() <= NumericLimits::Maximum()); - serializer.Write((uint32_t)columns.size()); - for (auto &column : columns) { - serializer.WriteString(column); - } + writer.WriteList(columns); } -unique_ptr UniqueConstraint::Deserialize(Deserializer &source) { - auto is_primary_key = source.Read(); - auto index = source.Read(); - auto column_count = source.Read(); - vector columns; - for (uint32_t i = 0; i < column_count; i++) { - auto column_name = source.Read(); - columns.push_back(column_name); - } +unique_ptr UniqueConstraint::Deserialize(FieldReader &source) { + auto is_primary_key = source.ReadRequired(); + auto index = source.ReadRequired(); + auto columns = source.ReadRequiredList(); - if (index != INVALID_INDEX) { + if (index != DConstants::INVALID_INDEX) { // single column parsed constraint auto result = make_unique(index, is_primary_key); result->columns = move(columns); @@ -121405,12 +132474,13 @@ class BetweenExpression : public ParsedExpression { unique_ptr Copy() const override; - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(ExpressionType type, Deserializer &source); + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(ExpressionType type, FieldReader &source); }; } // namespace duckdb + namespace duckdb { BetweenExpression::BetweenExpression(unique_ptr input_p, unique_ptr lower_p, @@ -121442,17 +132512,16 @@ unique_ptr BetweenExpression::Copy() const { return move(copy); } -void BetweenExpression::Serialize(Serializer &serializer) { - ParsedExpression::Serialize(serializer); - input->Serialize(serializer); - lower->Serialize(serializer); - upper->Serialize(serializer); +void BetweenExpression::Serialize(FieldWriter &writer) const { + writer.WriteSerializable(*input); + writer.WriteSerializable(*lower); + writer.WriteSerializable(*upper); } -unique_ptr BetweenExpression::Deserialize(ExpressionType type, Deserializer &source) { - auto input = ParsedExpression::Deserialize(source); - auto lower = ParsedExpression::Deserialize(source); - auto upper = ParsedExpression::Deserialize(source); +unique_ptr BetweenExpression::Deserialize(ExpressionType type, FieldReader &source) { + auto input = source.ReadRequiredSerializable(); + auto lower = source.ReadRequiredSerializable(); + auto upper = source.ReadRequiredSerializable(); return make_unique(move(input), move(lower), move(upper)); } @@ -121491,8 +132560,8 @@ class CaseExpression : public ParsedExpression { unique_ptr Copy() const override; - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(ExpressionType type, Deserializer &source); + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(ExpressionType type, FieldReader &source); }; } // namespace duckdb @@ -121546,26 +132615,29 @@ unique_ptr CaseExpression::Copy() const { return move(copy); } -void CaseExpression::Serialize(Serializer &serializer) { - ParsedExpression::Serialize(serializer); - serializer.Write(case_checks.size()); +void CaseExpression::Serialize(FieldWriter &writer) const { + auto &serializer = writer.GetSerializer(); + // we write a list of multiple expressions here + // in order to write this as a single field we directly use the field writers' internal serializer + writer.WriteField(case_checks.size()); for (auto &check : case_checks) { check.when_expr->Serialize(serializer); check.then_expr->Serialize(serializer); } - else_expr->Serialize(serializer); + writer.WriteSerializable(*else_expr); } -unique_ptr CaseExpression::Deserialize(ExpressionType type, Deserializer &source) { +unique_ptr CaseExpression::Deserialize(ExpressionType type, FieldReader &reader) { auto result = make_unique(); - auto count = source.Read(); + auto &source = reader.GetSource(); + auto count = reader.ReadRequired(); for (idx_t i = 0; i < count; i++) { 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->else_expr = ParsedExpression::Deserialize(source); + result->else_expr = reader.ReadRequiredSerializable(); return move(result); } @@ -121604,8 +132676,8 @@ class CastExpression : public ParsedExpression { unique_ptr Copy() const override; - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(ExpressionType type, Deserializer &source); + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(ExpressionType type, FieldReader &source); }; } // namespace duckdb @@ -121645,17 +132717,16 @@ unique_ptr CastExpression::Copy() const { return move(copy); } -void CastExpression::Serialize(Serializer &serializer) { - ParsedExpression::Serialize(serializer); - child->Serialize(serializer); - cast_type.Serialize(serializer); - serializer.Write(try_cast); +void CastExpression::Serialize(FieldWriter &writer) const { + writer.WriteSerializable(*child); + writer.WriteSerializable(cast_type); + writer.WriteField(try_cast); } -unique_ptr CastExpression::Deserialize(ExpressionType type, Deserializer &source) { - auto child = ParsedExpression::Deserialize(source); - auto cast_type = LogicalType::Deserialize(source); - auto try_cast = source.Read(); +unique_ptr CastExpression::Deserialize(ExpressionType type, FieldReader &reader) { + auto child = reader.ReadRequiredSerializable(); + auto cast_type = reader.ReadRequiredSerializable(); + auto try_cast = reader.ReadRequired(); return make_unique_base(cast_type, move(child), try_cast); } @@ -121691,8 +132762,8 @@ class CollateExpression : public ParsedExpression { unique_ptr Copy() const override; - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(ExpressionType type, Deserializer &source); + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(ExpressionType type, FieldReader &source); }; } // namespace duckdb @@ -121728,15 +132799,14 @@ unique_ptr CollateExpression::Copy() const { return move(copy); } -void CollateExpression::Serialize(Serializer &serializer) { - ParsedExpression::Serialize(serializer); - child->Serialize(serializer); - serializer.WriteString(collation); +void CollateExpression::Serialize(FieldWriter &writer) const { + writer.WriteSerializable(*child); + writer.WriteString(collation); } -unique_ptr CollateExpression::Deserialize(ExpressionType type, Deserializer &source) { - auto child = ParsedExpression::Deserialize(source); - auto collation = source.Read(); +unique_ptr CollateExpression::Deserialize(ExpressionType type, FieldReader &reader) { + auto child = reader.ReadRequiredSerializable(); + auto collation = reader.ReadRequired(); return make_unique_base(collation, move(child)); } @@ -121749,53 +132819,88 @@ unique_ptr CollateExpression::Deserialize(ExpressionType type, namespace duckdb { -//! Specify both the column and table name ColumnRefExpression::ColumnRefExpression(string column_name, string table_name) - : ParsedExpression(ExpressionType::COLUMN_REF, ExpressionClass::COLUMN_REF), column_name(move(column_name)), - table_name(move(table_name)) { + : ColumnRefExpression(table_name.empty() ? vector {move(column_name)} + : vector {move(table_name), move(column_name)}) { +} + +ColumnRefExpression::ColumnRefExpression(string column_name) : ColumnRefExpression(vector {move(column_name)}) { +} + +ColumnRefExpression::ColumnRefExpression(vector column_names_p) + : ParsedExpression(ExpressionType::COLUMN_REF, ExpressionClass::COLUMN_REF), column_names(move(column_names_p)) { +#ifdef DEBUG + for (auto &col_name : column_names) { + D_ASSERT(!col_name.empty()); + } +#endif +} + +bool ColumnRefExpression::IsQualified() const { + return column_names.size() > 1; +} + +const string &ColumnRefExpression::GetColumnName() const { + D_ASSERT(column_names.size() <= 3); + return column_names.back(); } -ColumnRefExpression::ColumnRefExpression(string column_name) : ColumnRefExpression(move(column_name), string()) { +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]; } string ColumnRefExpression::GetName() const { - return !alias.empty() ? alias : column_name; + return !alias.empty() ? alias : column_names.back(); } string ColumnRefExpression::ToString() const { - if (table_name.empty()) { - return column_name; - } else { - return table_name + "." + column_name; + string result; + for (idx_t i = 0; i < column_names.size(); i++) { + if (i > 0) { + result += "."; + } + result += column_names[i]; } + return result; } bool ColumnRefExpression::Equals(const ColumnRefExpression *a, const ColumnRefExpression *b) { - return a->column_name == b->column_name && a->table_name == b->table_name; + if (a->column_names.size() != b->column_names.size()) { + return false; + } + for (idx_t i = 0; i < a->column_names.size(); i++) { + auto lcase_a = StringUtil::Lower(a->column_names[i]); + auto lcase_b = StringUtil::Lower(b->column_names[i]); + if (lcase_a != lcase_b) { + return false; + } + } + return true; } hash_t ColumnRefExpression::Hash() const { hash_t result = ParsedExpression::Hash(); - result = CombineHash(result, duckdb::Hash(column_name.c_str())); + for (auto &column_name : column_names) { + auto lcase = StringUtil::Lower(column_name); + result = CombineHash(result, duckdb::Hash(lcase.c_str())); + } return result; } unique_ptr ColumnRefExpression::Copy() const { - auto copy = make_unique(column_name, table_name); + auto copy = make_unique(column_names); copy->CopyProperties(*this); return move(copy); } -void ColumnRefExpression::Serialize(Serializer &serializer) { - ParsedExpression::Serialize(serializer); - serializer.WriteString(table_name); - serializer.WriteString(column_name); +void ColumnRefExpression::Serialize(FieldWriter &writer) const { + writer.WriteList(column_names); } -unique_ptr ColumnRefExpression::Deserialize(ExpressionType type, Deserializer &source) { - auto table_name = source.Read(); - auto column_name = source.Read(); - auto expression = make_unique(column_name, table_name); +unique_ptr ColumnRefExpression::Deserialize(ExpressionType type, FieldReader &reader) { + auto column_names = reader.ReadRequiredList(); + auto expression = make_unique(move(column_names)); return move(expression); } @@ -121835,15 +132940,14 @@ unique_ptr ComparisonExpression::Copy() const { return move(copy); } -void ComparisonExpression::Serialize(Serializer &serializer) { - ParsedExpression::Serialize(serializer); - left->Serialize(serializer); - right->Serialize(serializer); +void ComparisonExpression::Serialize(FieldWriter &writer) const { + writer.WriteSerializable(*left); + writer.WriteSerializable(*right); } -unique_ptr ComparisonExpression::Deserialize(ExpressionType type, Deserializer &source) { - auto left_child = ParsedExpression::Deserialize(source); - auto right_child = ParsedExpression::Deserialize(source); +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)); } @@ -121942,14 +133046,13 @@ unique_ptr ConjunctionExpression::Copy() const { return move(copy); } -void ConjunctionExpression::Serialize(Serializer &serializer) { - ParsedExpression::Serialize(serializer); - serializer.WriteList(children); +void ConjunctionExpression::Serialize(FieldWriter &writer) const { + writer.WriteSerializableList(children); } -unique_ptr ConjunctionExpression::Deserialize(ExpressionType type, Deserializer &source) { +unique_ptr ConjunctionExpression::Deserialize(ExpressionType type, FieldReader &reader) { auto result = make_unique(type); - source.ReadList(result->children); + result->children = reader.ReadRequiredSerializableList(); return move(result); } @@ -121960,6 +133063,7 @@ unique_ptr ConjunctionExpression::Deserialize(ExpressionType t + namespace duckdb { ConstantExpression::ConstantExpression(Value val) @@ -121984,13 +133088,12 @@ unique_ptr ConstantExpression::Copy() const { return move(copy); } -void ConstantExpression::Serialize(Serializer &serializer) { - ParsedExpression::Serialize(serializer); - value.Serialize(serializer); +void ConstantExpression::Serialize(FieldWriter &writer) const { + writer.WriteSerializable(value); } -unique_ptr ConstantExpression::Deserialize(ExpressionType type, Deserializer &source) { - Value value = Value::Deserialize(source); +unique_ptr ConstantExpression::Deserialize(ExpressionType type, FieldReader &reader) { + Value value = reader.ReadRequiredSerializable(); return make_unique(move(value)); } @@ -122022,7 +133125,8 @@ class DefaultExpression : public ParsedExpression { unique_ptr Copy() const override; - static unique_ptr Deserialize(ExpressionType type, Deserializer &source); + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(ExpressionType type, FieldReader &source); }; } // namespace duckdb @@ -122044,7 +133148,10 @@ unique_ptr DefaultExpression::Copy() const { return move(copy); } -unique_ptr DefaultExpression::Deserialize(ExpressionType type, Deserializer &source) { +void DefaultExpression::Serialize(FieldWriter &writer) const { +} + +unique_ptr DefaultExpression::Deserialize(ExpressionType type, FieldReader &source) { return make_unique(); } @@ -122158,26 +133265,24 @@ unique_ptr FunctionExpression::Copy() const { return move(copy); } -void FunctionExpression::Serialize(Serializer &serializer) { - ParsedExpression::Serialize(serializer); - serializer.WriteString(function_name); - serializer.WriteString(schema); - serializer.WriteList(children); - serializer.WriteOptional(filter); - order_bys->Serialize(serializer); - serializer.Write(distinct); - serializer.Write(is_operator); -} - -unique_ptr FunctionExpression::Deserialize(ExpressionType type, Deserializer &source) { - vector> children; - auto function_name = source.Read(); - auto schema = source.Read(); - source.ReadList(children); - auto filter = source.ReadOptional(); - unique_ptr order_bys(static_cast(ResultModifier::Deserialize(source).release())); - auto distinct = source.Read(); - auto is_operator = source.Read(); +void FunctionExpression::Serialize(FieldWriter &writer) const { + writer.WriteString(function_name); + writer.WriteString(schema); + writer.WriteSerializableList(children); + writer.WriteOptional(filter); + writer.WriteSerializable((ResultModifier &)*order_bys); + writer.WriteField(distinct); + writer.WriteField(is_operator); +} + +unique_ptr FunctionExpression::Deserialize(ExpressionType type, FieldReader &reader) { + auto function_name = reader.ReadRequired(); + auto schema = reader.ReadRequired(); + auto children = reader.ReadRequiredSerializableList(); + auto filter = reader.ReadOptional(nullptr); + auto order_bys = unique_ptr_cast(reader.ReadRequiredSerializable()); + auto distinct = reader.ReadRequired(); + auto is_operator = reader.ReadRequired(); unique_ptr function; function = make_unique(function_name, move(children), move(filter), move(order_bys), distinct, is_operator); @@ -122218,8 +133323,8 @@ class LambdaExpression : public ParsedExpression { unique_ptr Copy() const override; - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(ExpressionType type, Deserializer &source); + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(ExpressionType type, FieldReader &source); }; } // namespace duckdb @@ -122227,7 +133332,6 @@ class LambdaExpression : public ParsedExpression { - namespace duckdb { LambdaExpression::LambdaExpression(vector parameters, unique_ptr expression) @@ -122274,24 +133378,14 @@ unique_ptr LambdaExpression::Copy() const { return make_unique(parameters, expression->Copy()); } -void LambdaExpression::Serialize(Serializer &serializer) { - ParsedExpression::Serialize(serializer); - serializer.Write(parameters.size()); - for (auto ¶meter : parameters) { - serializer.WriteString(parameter); - } - expression->Serialize(serializer); +void LambdaExpression::Serialize(FieldWriter &writer) const { + writer.WriteList(parameters); + writer.WriteSerializable(*expression); } -unique_ptr LambdaExpression::Deserialize(ExpressionType type, Deserializer &source) { - auto parameter_count = source.Read(); - vector parameters; - parameters.reserve(parameter_count); - for (size_t i = 0; i < parameter_count; i++) { - parameters.push_back(source.Read()); - } - auto expression = ParsedExpression::Deserialize(source); - +unique_ptr LambdaExpression::Deserialize(ExpressionType type, FieldReader &reader) { + auto parameters = reader.ReadRequiredList(); + auto expression = reader.ReadRequiredSerializable(); return make_unique(move(parameters), move(expression)); } @@ -122326,8 +133420,8 @@ class OperatorExpression : public ParsedExpression { unique_ptr Copy() const override; - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(ExpressionType type, Deserializer &source); + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(ExpressionType type, FieldReader &source); }; } // namespace duckdb @@ -122392,14 +133486,13 @@ unique_ptr OperatorExpression::Copy() const { return move(copy); } -void OperatorExpression::Serialize(Serializer &serializer) { - ParsedExpression::Serialize(serializer); - serializer.WriteList(children); +void OperatorExpression::Serialize(FieldWriter &writer) const { + writer.WriteSerializableList(children); } -unique_ptr OperatorExpression::Deserialize(ExpressionType type, Deserializer &source) { +unique_ptr OperatorExpression::Deserialize(ExpressionType type, FieldReader &reader) { auto expression = make_unique(type); - source.ReadList(expression->children); + expression->children = reader.ReadRequiredSerializableList(); return move(expression); } @@ -122436,8 +133529,8 @@ class ParameterExpression : public ParsedExpression { unique_ptr Copy() const override; hash_t Hash() const override; - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(ExpressionType type, Deserializer &source); + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(ExpressionType type, FieldReader &source); }; } // namespace duckdb @@ -122469,14 +133562,13 @@ hash_t ParameterExpression::Hash() const { return CombineHash(duckdb::Hash(parameter_nr), result); } -void ParameterExpression::Serialize(Serializer &serializer) { - ParsedExpression::Serialize(serializer); - serializer.Write(parameter_nr); +void ParameterExpression::Serialize(FieldWriter &writer) const { + writer.WriteField(parameter_nr); } -unique_ptr ParameterExpression::Deserialize(ExpressionType type, Deserializer &source) { +unique_ptr ParameterExpression::Deserialize(ExpressionType type, FieldReader &reader) { auto expression = make_unique(); - expression->parameter_nr = source.Read(); + expression->parameter_nr = reader.ReadRequired(); return move(expression); } @@ -122511,8 +133603,8 @@ class PositionalReferenceExpression : public ParsedExpression { unique_ptr Copy() const override; hash_t Hash() const override; - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(ExpressionType type, Deserializer &source); + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(ExpressionType type, FieldReader &source); }; } // namespace duckdb @@ -122548,13 +133640,12 @@ hash_t PositionalReferenceExpression::Hash() const { return CombineHash(duckdb::Hash(index), result); } -void PositionalReferenceExpression::Serialize(Serializer &serializer) { - ParsedExpression::Serialize(serializer); - serializer.Write(index); +void PositionalReferenceExpression::Serialize(FieldWriter &writer) const { + writer.WriteField(index); } -unique_ptr PositionalReferenceExpression::Deserialize(ExpressionType type, Deserializer &source) { - auto expression = make_unique(source.Read()); +unique_ptr PositionalReferenceExpression::Deserialize(ExpressionType type, FieldReader &reader) { + auto expression = make_unique(reader.ReadRequired()); return move(expression); } @@ -122620,28 +133711,34 @@ bool StarExpression::Equals(const StarExpression *a, const StarExpression *b) { return true; } -void StarExpression::Serialize(Serializer &serializer) { - ParsedExpression::Serialize(serializer); - serializer.WriteString(relation_name); - serializer.Write(exclude_list.size()); +void StarExpression::Serialize(FieldWriter &writer) const { + auto &serializer = writer.GetSerializer(); + + writer.WriteString(relation_name); + + // in order to write the exclude_list/replace_list as single fields we directly use the field writers' internal + // serializer + writer.WriteField(exclude_list.size()); for (auto &exclusion : exclude_list) { serializer.WriteString(exclusion); } - serializer.Write(replace_list.size()); + writer.WriteField(replace_list.size()); for (auto &entry : replace_list) { serializer.WriteString(entry.first); entry.second->Serialize(serializer); } } -unique_ptr StarExpression::Deserialize(ExpressionType type, Deserializer &source) { +unique_ptr StarExpression::Deserialize(ExpressionType type, FieldReader &reader) { + auto &source = reader.GetSource(); + auto result = make_unique(); - result->relation_name = source.Read(); - auto exclusion_count = source.Read(); + result->relation_name = reader.ReadRequired(); + auto exclusion_count = reader.ReadRequired(); for (idx_t i = 0; i < exclusion_count; i++) { result->exclude_list.insert(source.Read()); } - auto replace_count = source.Read(); + auto replace_count = reader.ReadRequired(); for (idx_t i = 0; i < replace_count; i++) { auto name = source.Read(); auto expr = ParsedExpression::Deserialize(source); @@ -122698,23 +133795,28 @@ unique_ptr SubqueryExpression::Copy() const { return move(copy); } -void SubqueryExpression::Serialize(Serializer &serializer) { - ParsedExpression::Serialize(serializer); - serializer.Write(subquery_type); +void SubqueryExpression::Serialize(FieldWriter &writer) const { + auto &serializer = writer.GetSerializer(); + + writer.WriteField(subquery_type); + // FIXME: this shouldn't use a serializer (probably)? subquery->Serialize(serializer); - serializer.WriteOptional(child); - serializer.Write(comparison_type); + writer.WriteOptional(child); + writer.WriteField(comparison_type); } -unique_ptr SubqueryExpression::Deserialize(ExpressionType type, Deserializer &source) { - auto subquery_type = source.Read(); +unique_ptr SubqueryExpression::Deserialize(ExpressionType type, FieldReader &reader) { + // FIXME: this shouldn't use a source + auto &source = reader.GetSource(); + + auto subquery_type = reader.ReadRequired(); auto subquery = SelectStatement::Deserialize(source); auto expression = make_unique(); expression->subquery_type = subquery_type; expression->subquery = move(subquery); - expression->child = source.ReadOptional(); - expression->comparison_type = source.Read(); + expression->child = reader.ReadOptional(nullptr); + expression->comparison_type = reader.ReadRequired(); return move(expression); } @@ -122729,7 +133831,7 @@ namespace duckdb { WindowExpression::WindowExpression(ExpressionType type, string schema, const string &function_name) : ParsedExpression(type, ExpressionClass::WINDOW), schema(move(schema)), - function_name(StringUtil::Lower(function_name)) { + function_name(StringUtil::Lower(function_name)), ignore_nulls(false) { switch (type) { case ExpressionType::WINDOW_AGGREGATE: case ExpressionType::WINDOW_ROW_NUMBER: @@ -122767,6 +133869,10 @@ string WindowExpression::ToString() const { result += ", "; result += default_expr->ToString(); } + // IGNORE NULLS + if (ignore_nulls) { + result += " IGNORE NULLS"; + } // Over clause result += ") OVER("; string sep; @@ -122871,6 +133977,9 @@ bool WindowExpression::Equals(const WindowExpression *a, const WindowExpression if (b->children.size() != a->children.size()) { return false; } + if (a->ignore_nulls != b->ignore_nulls) { + return false; + } for (idx_t i = 0; i < a->children.size(); i++) { if (!a->children[i]->Equals(b->children[i].get())) { return false; @@ -122933,48 +134042,54 @@ unique_ptr WindowExpression::Copy() const { new_window->end_expr = end_expr ? end_expr->Copy() : nullptr; new_window->offset_expr = offset_expr ? offset_expr->Copy() : nullptr; new_window->default_expr = default_expr ? default_expr->Copy() : nullptr; + new_window->ignore_nulls = ignore_nulls; return move(new_window); } -void WindowExpression::Serialize(Serializer &serializer) { - ParsedExpression::Serialize(serializer); - serializer.WriteString(function_name); - serializer.WriteString(schema); - serializer.WriteList(children); - serializer.WriteList(partitions); +void WindowExpression::Serialize(FieldWriter &writer) const { + auto &serializer = writer.GetSerializer(); + + writer.WriteString(function_name); + writer.WriteString(schema); + writer.WriteSerializableList(children); + writer.WriteSerializableList(partitions); + // FIXME: should not use serializer here (probably)? D_ASSERT(orders.size() <= NumericLimits::Maximum()); - serializer.Write((uint32_t)orders.size()); + writer.WriteField((uint32_t)orders.size()); for (auto &order : orders) { order.Serialize(serializer); } - serializer.Write(start); - serializer.Write(end); + writer.WriteField(start); + writer.WriteField(end); - serializer.WriteOptional(start_expr); - serializer.WriteOptional(end_expr); - serializer.WriteOptional(offset_expr); - serializer.WriteOptional(default_expr); + writer.WriteOptional(start_expr); + writer.WriteOptional(end_expr); + writer.WriteOptional(offset_expr); + writer.WriteOptional(default_expr); + writer.WriteField(ignore_nulls); } -unique_ptr WindowExpression::Deserialize(ExpressionType type, Deserializer &source) { - auto function_name = source.Read(); - auto schema = source.Read(); +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); - source.ReadList(expr->children); - source.ReadList(expr->partitions); + expr->children = reader.ReadRequiredSerializableList(); + expr->partitions = reader.ReadRequiredSerializableList(); - auto order_count = source.Read(); + auto order_count = reader.ReadRequired(); + auto &source = reader.GetSource(); for (idx_t i = 0; i < order_count; i++) { expr->orders.push_back(OrderByNode::Deserialize((source))); } - expr->start = source.Read(); - expr->end = source.Read(); + expr->start = reader.ReadRequired(); + expr->end = reader.ReadRequired(); - expr->start_expr = source.ReadOptional(); - expr->end_expr = source.ReadOptional(); - expr->offset_expr = source.ReadOptional(); - expr->default_expr = source.ReadOptional(); + expr->start_expr = reader.ReadOptional(nullptr); + expr->end_expr = reader.ReadOptional(nullptr); + expr->offset_expr = reader.ReadOptional(nullptr); + expr->default_expr = reader.ReadOptional(nullptr); + expr->ignore_nulls = reader.ReadRequired(); return move(expr); } @@ -123089,47 +134204,99 @@ string KeywordHelper::WriteOptionallyQuoted(const string &text) { namespace duckdb { -void AlterInfo::Serialize(Serializer &serializer) { - serializer.Write(type); +AlterInfo::AlterInfo(AlterType type, string schema_p, string name_p) + : type(type), schema(move(schema_p)), name(move(name_p)) { +} + +AlterInfo::~AlterInfo() { +} + +void AlterInfo::Serialize(Serializer &serializer) const { + FieldWriter writer(serializer); + writer.WriteField(type); + Serialize(writer); + writer.Finalize(); } unique_ptr AlterInfo::Deserialize(Deserializer &source) { - auto type = source.Read(); + FieldReader reader(source); + auto type = reader.ReadRequired(); + + unique_ptr result; switch (type) { case AlterType::ALTER_TABLE: - return AlterTableInfo::Deserialize(source); + result = AlterTableInfo::Deserialize(reader); + break; case AlterType::ALTER_VIEW: - return AlterViewInfo::Deserialize(source); + result = AlterViewInfo::Deserialize(reader); + break; default: throw SerializationException("Unknown alter type for deserialization!"); } + reader.Finalize(); + + return result; } -void AlterTableInfo::Serialize(Serializer &serializer) { - AlterInfo::Serialize(serializer); - serializer.Write(alter_table_type); - serializer.WriteString(schema); - serializer.WriteString(name); +//===--------------------------------------------------------------------===// +// ChangeOwnershipInfo +//===--------------------------------------------------------------------===// +ChangeOwnershipInfo::ChangeOwnershipInfo(CatalogType entry_catalog_type, string entry_schema_p, string entry_name_p, + string owner_schema_p, string owner_name_p) + : AlterInfo(AlterType::CHANGE_OWNERSHIP, move(entry_schema_p), move(entry_name_p)), + entry_catalog_type(entry_catalog_type), owner_schema(move(owner_schema_p)), owner_name(move(owner_name_p)) { } -unique_ptr AlterTableInfo::Deserialize(Deserializer &source) { - auto type = source.Read(); - auto schema = source.Read(); - auto table = source.Read(); +CatalogType ChangeOwnershipInfo::GetCatalogType() const { + return entry_catalog_type; +} + +unique_ptr ChangeOwnershipInfo::Copy() const { + return make_unique_base(entry_catalog_type, schema, name, owner_schema, owner_name); +} + +void ChangeOwnershipInfo::Serialize(FieldWriter &writer) const { + throw InternalException("ChangeOwnershipInfo cannot be serialized"); +} + +//===--------------------------------------------------------------------===// +// AlterTableInfo +//===--------------------------------------------------------------------===// +AlterTableInfo::AlterTableInfo(AlterTableType type, string schema_p, string table_p) + : AlterInfo(AlterType::ALTER_TABLE, move(move(schema_p)), move(table_p)), alter_table_type(type) { +} +AlterTableInfo::~AlterTableInfo() { +} + +CatalogType AlterTableInfo::GetCatalogType() const { + return CatalogType::TABLE_ENTRY; +} + +void AlterTableInfo::Serialize(FieldWriter &writer) const { + writer.WriteField(alter_table_type); + writer.WriteString(schema); + writer.WriteString(name); + SerializeAlterTable(writer); +} + +unique_ptr AlterTableInfo::Deserialize(FieldReader &reader) { + auto type = reader.ReadRequired(); + auto schema = reader.ReadRequired(); + auto table = reader.ReadRequired(); unique_ptr info; switch (type) { case AlterTableType::RENAME_COLUMN: - return RenameColumnInfo::Deserialize(source, schema, table); + return RenameColumnInfo::Deserialize(reader, schema, table); case AlterTableType::RENAME_TABLE: - return RenameTableInfo::Deserialize(source, schema, table); + return RenameTableInfo::Deserialize(reader, schema, table); case AlterTableType::ADD_COLUMN: - return AddColumnInfo::Deserialize(source, schema, table); + return AddColumnInfo::Deserialize(reader, schema, table); case AlterTableType::REMOVE_COLUMN: - return RemoveColumnInfo::Deserialize(source, schema, table); + return RemoveColumnInfo::Deserialize(reader, schema, table); case AlterTableType::ALTER_COLUMN_TYPE: - return ChangeColumnTypeInfo::Deserialize(source, schema, table); + return ChangeColumnTypeInfo::Deserialize(reader, schema, table); case AlterTableType::SET_DEFAULT: - return SetDefaultInfo::Deserialize(source, schema, table); + return SetDefaultInfo::Deserialize(reader, schema, table); default: throw SerializationException("Unknown alter table type for deserialization!"); } @@ -123138,94 +134305,123 @@ unique_ptr AlterTableInfo::Deserialize(Deserializer &source) { //===--------------------------------------------------------------------===// // RenameColumnInfo //===--------------------------------------------------------------------===// +RenameColumnInfo::RenameColumnInfo(string schema_p, string table_p, string old_name_p, string new_name_p) + : AlterTableInfo(AlterTableType::RENAME_COLUMN, move(schema_p), move(table_p)), old_name(move(old_name_p)), + new_name(move(new_name_p)) { +} +RenameColumnInfo::~RenameColumnInfo() { +} + unique_ptr RenameColumnInfo::Copy() const { return make_unique_base(schema, name, old_name, new_name); } -void RenameColumnInfo::Serialize(Serializer &serializer) { - AlterTableInfo::Serialize(serializer); - serializer.WriteString(old_name); - serializer.WriteString(new_name); +void RenameColumnInfo::SerializeAlterTable(FieldWriter &writer) const { + writer.WriteString(old_name); + writer.WriteString(new_name); } -unique_ptr RenameColumnInfo::Deserialize(Deserializer &source, string schema, string table) { - auto old_name = source.Read(); - auto new_name = source.Read(); +unique_ptr RenameColumnInfo::Deserialize(FieldReader &reader, string schema, string table) { + auto old_name = reader.ReadRequired(); + auto new_name = reader.ReadRequired(); return make_unique(move(schema), move(table), old_name, new_name); } //===--------------------------------------------------------------------===// // RenameTableInfo //===--------------------------------------------------------------------===// +RenameTableInfo::RenameTableInfo(string schema_p, string table_p, string new_name_p) + : AlterTableInfo(AlterTableType::RENAME_TABLE, move(schema_p), move(table_p)), new_table_name(move(new_name_p)) { +} +RenameTableInfo::~RenameTableInfo() { +} + unique_ptr RenameTableInfo::Copy() const { return make_unique_base(schema, name, new_table_name); } -void RenameTableInfo::Serialize(Serializer &serializer) { - AlterTableInfo::Serialize(serializer); - serializer.WriteString(new_table_name); +void RenameTableInfo::SerializeAlterTable(FieldWriter &writer) const { + writer.WriteString(new_table_name); } -unique_ptr RenameTableInfo::Deserialize(Deserializer &source, string schema, string table) { - auto new_name = source.Read(); +unique_ptr RenameTableInfo::Deserialize(FieldReader &reader, string schema, string table) { + auto new_name = reader.ReadRequired(); return make_unique(move(schema), move(table), new_name); } //===--------------------------------------------------------------------===// // AddColumnInfo //===--------------------------------------------------------------------===// +AddColumnInfo::AddColumnInfo(string schema_p, string table_p, ColumnDefinition new_column) + : AlterTableInfo(AlterTableType::ADD_COLUMN, move(schema_p), move(table_p)), new_column(move(new_column)) { +} +AddColumnInfo::~AddColumnInfo() { +} + unique_ptr AddColumnInfo::Copy() const { return make_unique_base(schema, name, new_column.Copy()); } -void AddColumnInfo::Serialize(Serializer &serializer) { - AlterTableInfo::Serialize(serializer); - new_column.Serialize(serializer); +void AddColumnInfo::SerializeAlterTable(FieldWriter &writer) const { + writer.WriteSerializable(new_column); } -unique_ptr AddColumnInfo::Deserialize(Deserializer &source, string schema, string table) { - auto new_column = ColumnDefinition::Deserialize(source); +unique_ptr AddColumnInfo::Deserialize(FieldReader &reader, string schema, string table) { + auto new_column = reader.ReadRequiredSerializable(); return make_unique(move(schema), move(table), move(new_column)); } //===--------------------------------------------------------------------===// // RemoveColumnInfo //===--------------------------------------------------------------------===// +RemoveColumnInfo::RemoveColumnInfo(string schema_p, string table_p, string removed_column, bool if_exists) + : AlterTableInfo(AlterTableType::REMOVE_COLUMN, move(schema_p), move(table_p)), + removed_column(move(removed_column)), if_exists(if_exists) { +} +RemoveColumnInfo::~RemoveColumnInfo() { +} + unique_ptr RemoveColumnInfo::Copy() const { return make_unique_base(schema, name, removed_column, if_exists); } -void RemoveColumnInfo::Serialize(Serializer &serializer) { - AlterTableInfo::Serialize(serializer); - serializer.WriteString(removed_column); - serializer.Write(if_exists); +void RemoveColumnInfo::SerializeAlterTable(FieldWriter &writer) const { + writer.WriteString(removed_column); + writer.WriteField(if_exists); } -unique_ptr RemoveColumnInfo::Deserialize(Deserializer &source, string schema, string table) { - auto new_name = source.Read(); - auto if_exists = source.Read(); +unique_ptr RemoveColumnInfo::Deserialize(FieldReader &reader, string schema, string table) { + auto new_name = reader.ReadRequired(); + auto if_exists = reader.ReadRequired(); return make_unique(move(schema), move(table), new_name, if_exists); } //===--------------------------------------------------------------------===// // ChangeColumnTypeInfo //===--------------------------------------------------------------------===// +ChangeColumnTypeInfo::ChangeColumnTypeInfo(string schema_p, string table_p, string column_name, LogicalType target_type, + unique_ptr expression) + : AlterTableInfo(AlterTableType::ALTER_COLUMN_TYPE, move(schema_p), move(table_p)), column_name(move(column_name)), + target_type(move(target_type)), expression(move(expression)) { +} +ChangeColumnTypeInfo::~ChangeColumnTypeInfo() { +} + unique_ptr ChangeColumnTypeInfo::Copy() const { return make_unique_base(schema, name, column_name, target_type, expression->Copy()); } -void ChangeColumnTypeInfo::Serialize(Serializer &serializer) { - AlterTableInfo::Serialize(serializer); - serializer.WriteString(column_name); - target_type.Serialize(serializer); - serializer.WriteOptional(expression); +void ChangeColumnTypeInfo::SerializeAlterTable(FieldWriter &writer) const { + writer.WriteString(column_name); + writer.WriteSerializable(target_type); + writer.WriteOptional(expression); } -unique_ptr ChangeColumnTypeInfo::Deserialize(Deserializer &source, string schema, string table) { - auto column_name = source.Read(); - auto target_type = LogicalType::Deserialize(source); - auto expression = source.ReadOptional(); +unique_ptr ChangeColumnTypeInfo::Deserialize(FieldReader &reader, string schema, string table) { + auto column_name = reader.ReadRequired(); + auto target_type = reader.ReadRequiredSerializable(); + auto expression = reader.ReadOptional(nullptr); return make_unique(move(schema), move(table), move(column_name), move(target_type), move(expression)); } @@ -123233,40 +134429,58 @@ unique_ptr ChangeColumnTypeInfo::Deserialize(Deserializer &source, st //===--------------------------------------------------------------------===// // SetDefaultInfo //===--------------------------------------------------------------------===// +SetDefaultInfo::SetDefaultInfo(string schema_p, string table_p, string column_name_p, + unique_ptr new_default) + : AlterTableInfo(AlterTableType::SET_DEFAULT, move(schema_p), move(table_p)), column_name(move(column_name_p)), + expression(move(new_default)) { +} +SetDefaultInfo::~SetDefaultInfo() { +} + unique_ptr SetDefaultInfo::Copy() const { - return make_unique_base(schema, name, column_name, expression->Copy()); + return make_unique_base(schema, name, column_name, + expression ? expression->Copy() : nullptr); } -void SetDefaultInfo::Serialize(Serializer &serializer) { - AlterTableInfo::Serialize(serializer); - serializer.WriteString(column_name); - serializer.WriteOptional(expression); +void SetDefaultInfo::SerializeAlterTable(FieldWriter &writer) const { + writer.WriteString(column_name); + writer.WriteOptional(expression); } -unique_ptr SetDefaultInfo::Deserialize(Deserializer &source, string schema, string table) { - auto column_name = source.Read(); - auto new_default = source.ReadOptional(); +unique_ptr SetDefaultInfo::Deserialize(FieldReader &reader, string schema, string table) { + auto column_name = reader.ReadRequired(); + auto new_default = reader.ReadOptional(nullptr); return make_unique(move(schema), move(table), move(column_name), move(new_default)); } //===--------------------------------------------------------------------===// // Alter View //===--------------------------------------------------------------------===// -void AlterViewInfo::Serialize(Serializer &serializer) { - AlterInfo::Serialize(serializer); - serializer.Write(alter_view_type); - serializer.WriteString(schema); - serializer.WriteString(name); +AlterViewInfo::AlterViewInfo(AlterViewType type, string schema_p, string view_p) + : AlterInfo(AlterType::ALTER_VIEW, move(schema_p), move(view_p)), alter_view_type(type) { +} +AlterViewInfo::~AlterViewInfo() { } -unique_ptr AlterViewInfo::Deserialize(Deserializer &source) { - auto type = source.Read(); - auto schema = source.Read(); - auto view = source.Read(); +CatalogType AlterViewInfo::GetCatalogType() const { + return CatalogType::VIEW_ENTRY; +} + +void AlterViewInfo::Serialize(FieldWriter &writer) const { + writer.WriteField(alter_view_type); + writer.WriteString(schema); + writer.WriteString(name); + SerializeAlterView(writer); +} + +unique_ptr AlterViewInfo::Deserialize(FieldReader &reader) { + auto type = reader.ReadRequired(); + auto schema = reader.ReadRequired(); + auto view = reader.ReadRequired(); unique_ptr info; switch (type) { case AlterViewType::RENAME_VIEW: - return RenameViewInfo::Deserialize(source, schema, view); + return RenameViewInfo::Deserialize(reader, schema, view); default: throw SerializationException("Unknown alter view type for deserialization!"); } @@ -123275,20 +134489,24 @@ unique_ptr AlterViewInfo::Deserialize(Deserializer &source) { //===--------------------------------------------------------------------===// // RenameViewInfo //===--------------------------------------------------------------------===// +RenameViewInfo::RenameViewInfo(string schema_p, string view_p, string new_name_p) + : AlterViewInfo(AlterViewType::RENAME_VIEW, move(schema_p), move(view_p)), new_view_name(move(new_name_p)) { +} +RenameViewInfo::~RenameViewInfo() { +} + unique_ptr RenameViewInfo::Copy() const { return make_unique_base(schema, name, new_view_name); } -void RenameViewInfo::Serialize(Serializer &serializer) { - AlterViewInfo::Serialize(serializer); - serializer.WriteString(new_view_name); +void RenameViewInfo::SerializeAlterView(FieldWriter &writer) const { + writer.WriteString(new_view_name); } -unique_ptr RenameViewInfo::Deserialize(Deserializer &source, string schema, string view) { - auto new_name = source.Read(); +unique_ptr RenameViewInfo::Deserialize(FieldReader &reader, string schema, string view) { + auto new_name = reader.ReadRequired(); return make_unique(move(schema), move(view), new_name); } - } // namespace duckdb @@ -123309,18 +134527,24 @@ string SampleMethodToString(SampleMethod method) { } void SampleOptions::Serialize(Serializer &serializer) { - sample_size.Serialize(serializer); - serializer.Write(is_percentage); - serializer.Write(method); - serializer.Write(seed); + FieldWriter writer(serializer); + writer.WriteSerializable(sample_size); + writer.WriteField(is_percentage); + writer.WriteField(method); + writer.WriteField(seed); + writer.Finalize(); } unique_ptr SampleOptions::Deserialize(Deserializer &source) { auto result = make_unique(); - result->sample_size = Value::Deserialize(source); - result->is_percentage = source.Read(); - result->method = source.Read(); - result->seed = source.Read(); + + FieldReader reader(source); + result->sample_size = reader.ReadRequiredSerializable(); + result->is_percentage = reader.ReadRequired(); + result->method = reader.ReadRequired(); + result->seed = reader.ReadRequired(); + reader.Finalize(); + return result; } @@ -123465,73 +134689,78 @@ hash_t ParsedExpression::Hash() const { return hash; } -void ParsedExpression::Serialize(Serializer &serializer) { - serializer.Write(GetExpressionClass()); - serializer.Write(type); - serializer.WriteString(alias); +void ParsedExpression::Serialize(Serializer &serializer) const { + FieldWriter writer(serializer); + writer.WriteField(GetExpressionClass()); + writer.WriteField(type); + writer.WriteString(alias); + Serialize(writer); + writer.Finalize(); } unique_ptr ParsedExpression::Deserialize(Deserializer &source) { - auto expression_class = source.Read(); - auto type = source.Read(); - auto alias = source.Read(); + FieldReader reader(source); + auto expression_class = reader.ReadRequired(); + auto type = reader.ReadRequired(); + auto alias = reader.ReadRequired(); unique_ptr result; switch (expression_class) { case ExpressionClass::BETWEEN: - result = BetweenExpression::Deserialize(type, source); + result = BetweenExpression::Deserialize(type, reader); break; case ExpressionClass::CASE: - result = CaseExpression::Deserialize(type, source); + result = CaseExpression::Deserialize(type, reader); break; case ExpressionClass::CAST: - result = CastExpression::Deserialize(type, source); + result = CastExpression::Deserialize(type, reader); break; case ExpressionClass::COLLATE: - result = CollateExpression::Deserialize(type, source); + result = CollateExpression::Deserialize(type, reader); break; case ExpressionClass::COLUMN_REF: - result = ColumnRefExpression::Deserialize(type, source); + result = ColumnRefExpression::Deserialize(type, reader); break; case ExpressionClass::COMPARISON: - result = ComparisonExpression::Deserialize(type, source); + result = ComparisonExpression::Deserialize(type, reader); break; case ExpressionClass::CONJUNCTION: - result = ConjunctionExpression::Deserialize(type, source); + result = ConjunctionExpression::Deserialize(type, reader); break; case ExpressionClass::CONSTANT: - result = ConstantExpression::Deserialize(type, source); + result = ConstantExpression::Deserialize(type, reader); break; case ExpressionClass::DEFAULT: - result = DefaultExpression::Deserialize(type, source); + result = DefaultExpression::Deserialize(type, reader); break; case ExpressionClass::FUNCTION: - result = FunctionExpression::Deserialize(type, source); + result = FunctionExpression::Deserialize(type, reader); break; case ExpressionClass::LAMBDA: - result = LambdaExpression::Deserialize(type, source); + result = LambdaExpression::Deserialize(type, reader); break; case ExpressionClass::OPERATOR: - result = OperatorExpression::Deserialize(type, source); + result = OperatorExpression::Deserialize(type, reader); break; case ExpressionClass::PARAMETER: - result = ParameterExpression::Deserialize(type, source); + result = ParameterExpression::Deserialize(type, reader); break; case ExpressionClass::POSITIONAL_REFERENCE: - result = PositionalReferenceExpression::Deserialize(type, source); + result = PositionalReferenceExpression::Deserialize(type, reader); break; case ExpressionClass::STAR: - result = StarExpression::Deserialize(type, source); + result = StarExpression::Deserialize(type, reader); break; case ExpressionClass::SUBQUERY: - result = SubqueryExpression::Deserialize(type, source); + result = SubqueryExpression::Deserialize(type, reader); break; case ExpressionClass::WINDOW: - result = WindowExpression::Deserialize(type, source); + result = WindowExpression::Deserialize(type, reader); break; default: throw SerializationException("Unsupported type for expression deserialization!"); } result->alias = alias; + reader.Finalize(); return result; } @@ -123540,6 +134769,94 @@ unique_ptr ParsedExpression::Deserialize(Deserializer &source) +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/query_node/recursive_cte_node.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + +namespace duckdb { + +class RecursiveCTENode : public QueryNode { +public: + RecursiveCTENode() : QueryNode(QueryNodeType::RECURSIVE_CTE_NODE) { + } + + string ctename; + bool union_all; + //! The left side of the set operation + unique_ptr left; + //! The right side of the set operation + unique_ptr right; + //! Aliases of the recursive CTE node + vector aliases; + + const vector> &GetSelectList() const override { + return left->GetSelectList(); + } + +public: + bool Equals(const QueryNode *other) const override; + //! Create a copy of this SelectNode + unique_ptr Copy() const override; + + //! Serializes a QueryNode to a stand-alone binary blob + void Serialize(FieldWriter &writer) const override; + //! Deserializes a blob back into a QueryNode + static unique_ptr Deserialize(FieldReader &reader); +}; + +} // namespace duckdb + + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/tableref/emptytableref.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { +//! Represents a cross product +class EmptyTableRef : public TableRef { +public: + EmptyTableRef() : TableRef(TableReferenceType::EMPTY) { + } + +public: + bool Equals(const TableRef *other_p) const override; + + unique_ptr Copy() override; + + //! Serializes a blob into a DummyTableRef + void Serialize(FieldWriter &serializer) const override; + //! Deserializes a blob back into a DummyTableRef + static unique_ptr Deserialize(FieldReader &source); +}; +} // namespace duckdb + + + + + + + namespace duckdb { void ParsedExpressionIterator::EnumerateChildren(const ParsedExpression &expression, @@ -123675,6 +134992,94 @@ void ParsedExpressionIterator::EnumerateChildren( } } +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++) { + for (idx_t j = 0; j < el_ref.values[i].size(); j++) { + callback(el_ref.values[i][j]); + } + } + break; + } + case TableReferenceType::JOIN: { + auto &j_ref = (JoinRef &)ref; + EnumerateTableRefChildren(*j_ref.left, callback); + EnumerateTableRefChildren(*j_ref.right, callback); + callback(j_ref.condition); + break; + } + case TableReferenceType::SUBQUERY: { + auto &sq_ref = (SubqueryRef &)ref; + EnumerateQueryNodeChildren(*sq_ref.subquery->node, callback); + break; + } + case TableReferenceType::TABLE_FUNCTION: { + auto &tf_ref = (TableFunctionRef &)ref; + callback(tf_ref.function); + break; + } + case TableReferenceType::BASE_TABLE: + case TableReferenceType::EMPTY: + // these TableRefs do not need to be unfolded + break; + default: + throw NotImplementedException("TableRef type not implemented for traversal"); + } +} + +void ParsedExpressionIterator::EnumerateQueryNodeChildren( + QueryNode &node, const std::function &child)> &callback) { + switch (node.type) { + case QueryNodeType::RECURSIVE_CTE_NODE: { + auto &rcte_node = (RecursiveCTENode &)node; + EnumerateQueryNodeChildren(*rcte_node.left, callback); + EnumerateQueryNodeChildren(*rcte_node.right, callback); + break; + } + case QueryNodeType::SELECT_NODE: { + auto &sel_node = (SelectNode &)node; + for (idx_t i = 0; i < sel_node.select_list.size(); i++) { + callback(sel_node.select_list[i]); + } + for (idx_t i = 0; i < sel_node.groups.group_expressions.size(); i++) { + callback(sel_node.groups.group_expressions[i]); + } + if (sel_node.where_clause) { + callback(sel_node.where_clause); + } + if (sel_node.having) { + callback(sel_node.having); + } + if (sel_node.qualify) { + callback(sel_node.qualify); + } + + EnumerateTableRefChildren(*sel_node.from_table.get(), callback); + break; + } + case QueryNodeType::SET_OPERATION_NODE: { + auto &setop_node = (SetOperationNode &)node; + EnumerateQueryNodeChildren(*setop_node.left, callback); + EnumerateQueryNodeChildren(*setop_node.right, callback); + break; + } + default: + throw NotImplementedException("QueryNode type not implemented for traversal"); + } + for (auto &kv : node.cte_map) { + EnumerateQueryNodeChildren(*kv.second->query->node, callback); + } +} + } // namespace duckdb @@ -123700,7 +135105,7 @@ void ParsedExpressionIterator::EnumerateChildren( // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list // this is a bit of a mess from c.h, port.h and some others. Upside is it makes the parser compile with minimal @@ -123812,7 +135217,7 @@ typedef enum PGPostgresAttributIdentityTypes { // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /*------------------------------------------------------------------------- @@ -123841,7 +135246,7 @@ typedef enum PGPostgresAttributIdentityTypes { // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /*------------------------------------------------------------------------- @@ -123952,7 +135357,7 @@ uint32_t bms_hash_value(const PGBitmapset *a); // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /*------------------------------------------------------------------------- @@ -124005,7 +135410,7 @@ typedef enum PGLockWaitPolicy { // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /*------------------------------------------------------------------------- @@ -124029,7 +135434,7 @@ typedef enum PGLockWaitPolicy { // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /*------------------------------------------------------------------------- @@ -124102,7 +135507,7 @@ typedef int16_t PGAttrNumber; // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /*------------------------------------------------------------------------- @@ -124146,7 +135551,7 @@ typedef int16_t PGAttrNumber; // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /*------------------------------------------------------------------------- @@ -124630,6 +136035,7 @@ typedef enum PGNodeTag { T_PGIntervalConstant, T_PGSampleSize, T_PGSampleOptions, + T_PGLimitPercent, T_PGPositionalReference, /* @@ -126602,7 +138008,7 @@ typedef struct PGOnConflictExpr { // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /*------------------------------------------------------------------------- @@ -126933,6 +138339,7 @@ typedef struct PGFuncCall { bool agg_within_group; /* ORDER BY appeared in WITHIN GROUP */ bool agg_star; /* argument was really '*' */ bool agg_distinct; /* arguments were labeled DISTINCT */ + bool agg_ignore_nulls; /* arguments were labeled IGNORE NULLS */ bool func_variadic; /* last argument was labeled VARIADIC */ struct PGWindowDef *over; /* OVER clause, if any */ int location; /* token location, or -1 if unknown */ @@ -127587,7 +138994,8 @@ typedef enum { GROUPING_SET_SIMPLE, GROUPING_SET_ROLLUP, GROUPING_SET_CUBE, - GROUPING_SET_SETS + GROUPING_SET_SETS, + GROUPING_SET_ALL } GroupingSetKind; typedef struct PGGroupingSet { @@ -127819,6 +139227,7 @@ typedef struct PGSelectStmt { PGList *groupClause; /* GROUP BY clauses */ PGNode *havingClause; /* HAVING conditional-expression */ PGList *windowClause; /* WINDOW window_name AS (...), ... */ + PGNode *qualifyClause; /* QUALIFY conditional-expression */ /* * In a "leaf" node representing a VALUES list, the above fields are all @@ -128437,9 +139846,14 @@ typedef struct PGViewStmt { * Load Statement * ---------------------- */ + +typedef enum PGLoadInstallType { PG_LOAD_TYPE_LOAD, PG_LOAD_TYPE_INSTALL, PG_LOAD_TYPE_FORCE_INSTALL } PGLoadInstallType; + + typedef struct PGLoadStmt { PGNodeTag type; - char *filename; /* file to load */ + const char *filename; /* file to load */ + PGLoadInstallType load_type; } PGLoadStmt; /* ---------------------- @@ -128620,6 +140034,14 @@ typedef struct PGSampleOptions { int location; /* token location, or -1 if unknown */ } PGSampleOptions; +/* ---------------------- + * Limit Percentage + * ---------------------- + */ +typedef struct PGLimitPercent { + PGNodeTag type; + PGNode* limit_percent; /* limit percent */ +} PGLimitPercent; /* ---------------------- * Lambda Function @@ -128667,6 +140089,7 @@ typedef struct PGCreateEnumStmt namespace duckdb { class ColumnDefinition; +class StackChecker; struct OrderByNode; struct CopyInfo; struct CommonTableExpressionInfo; @@ -128677,10 +140100,10 @@ struct GroupingExpressionMap; class Transformer { static constexpr const idx_t DEFAULT_MAX_EXPRESSION_DEPTH = 1000; + friend class StackChecker; + public: - explicit Transformer(Transformer *parent = nullptr, idx_t max_expression_depth_p = DEFAULT_MAX_EXPRESSION_DEPTH) - : parent(parent), max_expression_depth(parent ? parent->max_expression_depth : max_expression_depth_p) { - } + explicit Transformer(Transformer *parent = nullptr, idx_t max_expression_depth_p = DEFAULT_MAX_EXPRESSION_DEPTH); //! Transforms a Postgres parse tree into a set of SQL Statements bool TransformParseTree(duckdb_libpgquery::PGList *tree, vector> &statements); @@ -128709,6 +140132,8 @@ class Transformer { private: //! Transforms a Postgres statement into a single SQL statement unique_ptr TransformStatement(duckdb_libpgquery::PGNode *stmt); + //! Transforms a Postgres statement into a single SQL statement + unique_ptr TransformStatementInternal(duckdb_libpgquery::PGNode *stmt); //===--------------------------------------------------------------------===// // Statement transformation //===--------------------------------------------------------------------===// @@ -128734,6 +140159,8 @@ class Transformer { unique_ptr TransformCreateFunction(duckdb_libpgquery::PGNode *node); //! Transform a Postgres duckdb_libpgquery::T_PGCreateEnumStmt node into CreateStatement unique_ptr TransformCreateEnum(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 @@ -128748,7 +140175,7 @@ class Transformer { //! Transform a Postgres duckdb_libpgquery::T_PGUpdateStmt node into a UpdateStatement unique_ptr TransformUpdate(duckdb_libpgquery::PGNode *node); //! Transform a Postgres duckdb_libpgquery::T_PGPragmaStmt node into a PragmaStatement - unique_ptr TransformPragma(duckdb_libpgquery::PGNode *node); + unique_ptr TransformPragma(duckdb_libpgquery::PGNode *node); //! Transform a Postgres duckdb_libpgquery::T_PGExportStmt node into a ExportStatement unique_ptr TransformExport(duckdb_libpgquery::PGNode *node); //! Transform a Postgres duckdb_libpgquery::T_PGImportStmt node into a PragmaStatement @@ -128869,8 +140296,8 @@ class Transformer { LogicalType TransformTypeName(duckdb_libpgquery::PGTypeName *name); //! Transform a Postgres GROUP BY expression into a list of Expression - bool TransformGroupBy(duckdb_libpgquery::PGList *group, GroupByNode &result); - void TransformGroupByNode(duckdb_libpgquery::PGNode *n, GroupingExpressionMap &map, GroupByNode &result, + bool TransformGroupBy(duckdb_libpgquery::PGList *group, SelectNode &result); + void TransformGroupByNode(duckdb_libpgquery::PGNode *n, GroupingExpressionMap &map, SelectNode &result, vector &result_sets); void AddGroupByExpression(unique_ptr expression, GroupingExpressionMap &map, GroupByNode &result, vector &result_set); @@ -128890,14 +140317,23 @@ class Transformer { unique_ptr TransformSampleOptions(duckdb_libpgquery::PGNode *options); private: - //! Default stack limit of the transformer - constexpr static idx_t MAX_STACK_SIZE = 1024 * 100; - //! For iterative functions that create recursive objects, this is our default stack size per element - constexpr static idx_t DEFAULT_ENTRY_STACK_SIZE = 100; - int *root = nullptr; + //! Current stack depth + idx_t stack_depth; - void InitializeStackCheck(int *stack_check_var); - void StackCheck(idx_t extra_stack = 0); + void InitializeStackCheck(); + StackChecker StackCheck(idx_t extra_stack = 1); +}; + +class StackChecker { +public: + StackChecker(Transformer &transformer, idx_t stack_usage); + ~StackChecker(); + StackChecker(StackChecker &&) noexcept; + StackChecker(const StackChecker &) = delete; + +private: + Transformer &transformer; + idx_t stack_usage; }; } // namespace duckdb @@ -128911,7 +140347,7 @@ class Transformer { // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list //===----------------------------------------------------------------------===// @@ -128930,12 +140366,13 @@ class Transformer { // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list #include +#include namespace duckdb_libpgquery { @@ -128953,6 +140390,18 @@ struct PGSimplifiedToken { int32_t start; }; +enum class PGKeywordCategory : uint8_t { + PG_KEYWORD_RESERVED, + PG_KEYWORD_UNRESERVED, + PG_KEYWORD_TYPE_FUNC, + PG_KEYWORD_COL_NAME +}; + +struct PGKeyword { + std::string text; + PGKeywordCategory category; +}; + } @@ -128974,7 +140423,11 @@ class PostgresParser { static std::vector Tokenize(const std::string &query); static bool IsKeyword(const std::string &text); + static std::vector KeywordList(); + + static void SetPreserveIdentifierCase(bool downcase); }; + } @@ -128985,7 +140438,7 @@ class PostgresParser { // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /*------------------------------------------------------------------------- @@ -129020,6 +140473,7 @@ typedef enum PGBackslashQuoteType { PGList *raw_parser(const char *str); bool is_keyword(const char *str); +std::vector keyword_list(); std::vector tokenize(const char *str); @@ -129034,12 +140488,13 @@ PGTypeName *SystemTypeName(const char *name); namespace duckdb { -Parser::Parser() { +Parser::Parser(ParserOptions options_p) : options(options_p) { } void Parser::ParseQuery(const string &query) { Transformer transformer; { + PostgresParser::SetPreserveIdentifierCase(options.preserve_identifier_case); PostgresParser parser; parser.Parse(query); @@ -129095,6 +140550,8 @@ vector Parser::Tokenize(const string &query) { case duckdb_libpgquery::PGSimplifiedTokenType::PG_SIMPLIFIED_TOKEN_COMMENT: // LCOV_EXCL_START token.type = SimplifiedTokenType::SIMPLIFIED_TOKEN_COMMENT; break; + default: + throw InternalException("Unrecognized token category"); } // LCOV_EXCL_STOP token.start = pg_token.start; result.push_back(token); @@ -129106,11 +140563,38 @@ bool Parser::IsKeyword(const string &text) { return PostgresParser::IsKeyword(text); } -vector> Parser::ParseExpressionList(const string &select_list) { +vector Parser::KeywordList() { + auto keywords = PostgresParser::KeywordList(); + vector result; + for (auto &kw : keywords) { + ParserKeyword res; + res.name = kw.text; + switch (kw.category) { + case duckdb_libpgquery::PGKeywordCategory::PG_KEYWORD_RESERVED: + res.category = KeywordCategory::KEYWORD_RESERVED; + break; + case duckdb_libpgquery::PGKeywordCategory::PG_KEYWORD_UNRESERVED: + res.category = KeywordCategory::KEYWORD_UNRESERVED; + break; + case duckdb_libpgquery::PGKeywordCategory::PG_KEYWORD_TYPE_FUNC: + res.category = KeywordCategory::KEYWORD_TYPE_FUNC; + break; + case duckdb_libpgquery::PGKeywordCategory::PG_KEYWORD_COL_NAME: + res.category = KeywordCategory::KEYWORD_COL_NAME; + break; + default: + throw InternalException("Unrecognized keyword category"); + } + result.push_back(res); + } + return result; +} + +vector> Parser::ParseExpressionList(const string &select_list, ParserOptions options) { // construct a mock query prefixed with SELECT string mock_query = "SELECT " + select_list; // parse the query - Parser parser; + Parser parser(options); parser.ParseQuery(mock_query); // check the statements if (parser.statements.size() != 1 || parser.statements[0]->type != StatementType::SELECT_STATEMENT) { @@ -129124,11 +140608,11 @@ vector> Parser::ParseExpressionList(const string &s return move(select_node.select_list); } -vector Parser::ParseOrderList(const string &select_list) { +vector Parser::ParseOrderList(const string &select_list, ParserOptions options) { // construct a mock query string mock_query = "SELECT * FROM tbl ORDER BY " + select_list; // parse the query - Parser parser; + Parser parser(options); parser.ParseQuery(mock_query); // check the statements if (parser.statements.size() != 1 || parser.statements[0]->type != StatementType::SELECT_STATEMENT) { @@ -129148,11 +140632,11 @@ vector Parser::ParseOrderList(const string &select_list) { } void Parser::ParseUpdateList(const string &update_list, vector &update_columns, - vector> &expressions) { + vector> &expressions, ParserOptions options) { // construct a mock query string mock_query = "UPDATE tbl SET " + update_list; // parse the query - Parser parser; + Parser parser(options); parser.ParseQuery(mock_query); // check the statements if (parser.statements.size() != 1 || parser.statements[0]->type != StatementType::UPDATE_STATEMENT) { @@ -129163,11 +140647,11 @@ void Parser::ParseUpdateList(const string &update_list, vector &update_c expressions = move(update.expressions); } -vector>> Parser::ParseValuesList(const string &value_list) { +vector>> Parser::ParseValuesList(const string &value_list, ParserOptions options) { // construct a mock query string mock_query = "VALUES " + value_list; // parse the query - Parser parser; + Parser parser(options); parser.ParseQuery(mock_query); // check the statements if (parser.statements.size() != 1 || parser.statements[0]->type != StatementType::SELECT_STATEMENT) { @@ -129185,9 +140669,9 @@ vector>> Parser::ParseValuesList(const strin return move(values_list.values); } -vector Parser::ParseColumnList(const string &column_list) { +vector Parser::ParseColumnList(const string &column_list, ParserOptions options) { string mock_query = "CREATE TABLE blabla (" + column_list + ")"; - Parser parser; + Parser parser(options); parser.ParseQuery(mock_query); if (parser.statements.size() != 1 || parser.statements[0]->type != StatementType::CREATE_STATEMENT) { throw ParserException("Expected a single CREATE statement"); @@ -129322,54 +140806,9 @@ string QueryErrorContext::FormatErrorRecursive(const string &msg, vector left; - //! The right side of the set operation - unique_ptr right; - //! Aliases of the recursive CTE node - vector aliases; - - const vector> &GetSelectList() const override { - return left->GetSelectList(); - } - -public: - bool Equals(const QueryNode *other) const override; - //! Create a copy of this SelectNode - unique_ptr Copy() override; - - //! Serializes a SelectNode to a stand-alone binary blob - void Serialize(Serializer &serializer) override; - //! Deserializes a blob back into a SelectNode - static unique_ptr Deserialize(Deserializer &source); -}; - -} // namespace duckdb - - namespace duckdb { bool RecursiveCTENode::Equals(const QueryNode *other_p) const { @@ -129393,7 +140832,7 @@ bool RecursiveCTENode::Equals(const QueryNode *other_p) const { return true; } -unique_ptr RecursiveCTENode::Copy() { +unique_ptr RecursiveCTENode::Copy() const { auto result = make_unique(); result->ctename = ctename; result->union_all = union_all; @@ -129404,22 +140843,21 @@ unique_ptr RecursiveCTENode::Copy() { return move(result); } -void RecursiveCTENode::Serialize(Serializer &serializer) { - QueryNode::Serialize(serializer); - serializer.WriteString(ctename); - serializer.WriteString(union_all ? "T" : "F"); - left->Serialize(serializer); - right->Serialize(serializer); - serializer.WriteStringVector(aliases); +void RecursiveCTENode::Serialize(FieldWriter &writer) const { + writer.WriteString(ctename); + writer.WriteField(union_all); + writer.WriteSerializable(*left); + writer.WriteSerializable(*right); + writer.WriteList(aliases); } -unique_ptr RecursiveCTENode::Deserialize(Deserializer &source) { +unique_ptr RecursiveCTENode::Deserialize(FieldReader &reader) { auto result = make_unique(); - result->ctename = source.Read(); - result->union_all = source.Read() == "T" ? true : false; - result->left = QueryNode::Deserialize(source); - result->right = QueryNode::Deserialize(source); - source.ReadStringVector(result->aliases); + result->ctename = reader.ReadRequired(); + result->union_all = reader.ReadRequired(); + result->left = reader.ReadRequiredSerializable(); + result->right = reader.ReadRequiredSerializable(); + result->aliases = reader.ReadRequiredList(); return move(result); } @@ -129427,8 +140865,13 @@ unique_ptr RecursiveCTENode::Deserialize(Deserializer &source) { + namespace duckdb { +SelectNode::SelectNode() + : QueryNode(QueryNodeType::SELECT_NODE), aggregate_handling(AggregateHandling::STANDARD_HANDLING) { +} + bool SelectNode::Equals(const QueryNode *other_p) const { if (!QueryNode::Equals(other_p)) { return false; @@ -129471,10 +140914,14 @@ bool SelectNode::Equals(const QueryNode *other_p) const { if (!BaseExpression::Equals(having.get(), other->having.get())) { return false; } + // QUALIFY + if (!BaseExpression::Equals(qualify.get(), other->qualify.get())) { + return false; + } return true; } -unique_ptr SelectNode::Copy() { +unique_ptr SelectNode::Copy() const { auto result = make_unique(); for (auto &child : select_list) { result->select_list.push_back(child->Copy()); @@ -129486,45 +140933,42 @@ unique_ptr SelectNode::Copy() { result->groups.group_expressions.push_back(group->Copy()); } result->groups.grouping_sets = groups.grouping_sets; + result->aggregate_handling = aggregate_handling; result->having = having ? having->Copy() : nullptr; + result->qualify = qualify ? qualify->Copy() : nullptr; result->sample = sample ? sample->Copy() : nullptr; this->CopyProperties(*result); return move(result); } -void SelectNode::Serialize(Serializer &serializer) { - QueryNode::Serialize(serializer); - // select_list - serializer.WriteList(select_list); - // from clause - serializer.WriteOptional(from_table); - // where_clause - serializer.WriteOptional(where_clause); - // group by - serializer.WriteList(groups.group_expressions); - serializer.Write(groups.grouping_sets.size()); +void SelectNode::Serialize(FieldWriter &writer) const { + writer.WriteSerializableList(select_list); + writer.WriteOptional(from_table); + writer.WriteOptional(where_clause); + writer.WriteSerializableList(groups.group_expressions); + writer.WriteField(groups.grouping_sets.size()); + auto &serializer = writer.GetSerializer(); for (auto &grouping_set : groups.grouping_sets) { serializer.Write(grouping_set.size()); for (auto &idx : grouping_set) { serializer.Write(idx); } } - // having / sample - serializer.WriteOptional(having); - serializer.WriteOptional(sample); + writer.WriteField(aggregate_handling); + writer.WriteOptional(having); + writer.WriteOptional(sample); + writer.WriteOptional(qualify); } -unique_ptr SelectNode::Deserialize(Deserializer &source) { +unique_ptr SelectNode::Deserialize(FieldReader &reader) { auto result = make_unique(); - // select_list - source.ReadList(result->select_list); - // from clause - result->from_table = source.ReadOptional(); - // where_clause - result->where_clause = source.ReadOptional(); - // group by - source.ReadList(result->groups.group_expressions); - auto grouping_set_count = source.Read(); + result->select_list = reader.ReadRequiredSerializableList(); + result->from_table = reader.ReadOptional(nullptr); + result->where_clause = reader.ReadOptional(nullptr); + result->groups.group_expressions = reader.ReadRequiredSerializableList(); + + auto grouping_set_count = reader.ReadRequired(); + auto &source = reader.GetSource(); for (idx_t set_idx = 0; set_idx < grouping_set_count; set_idx++) { auto set_entries = source.Read(); GroupingSet grouping_set; @@ -129533,15 +140977,17 @@ unique_ptr SelectNode::Deserialize(Deserializer &source) { } result->groups.grouping_sets.push_back(grouping_set); } - // having / sample - result->having = source.ReadOptional(); - result->sample = source.ReadOptional(); + result->aggregate_handling = reader.ReadRequired(); + result->having = reader.ReadOptional(nullptr); + result->sample = reader.ReadOptional(nullptr); + result->qualify = reader.ReadOptional(nullptr); return move(result); } } // namespace duckdb + namespace duckdb { bool SetOperationNode::Equals(const QueryNode *other_p) const { @@ -129564,7 +141010,7 @@ bool SetOperationNode::Equals(const QueryNode *other_p) const { return true; } -unique_ptr SetOperationNode::Copy() { +unique_ptr SetOperationNode::Copy() const { auto result = make_unique(); result->setop_type = setop_type; result->left = left->Copy(); @@ -129573,18 +141019,17 @@ unique_ptr SetOperationNode::Copy() { return move(result); } -void SetOperationNode::Serialize(Serializer &serializer) { - QueryNode::Serialize(serializer); - serializer.Write(setop_type); - left->Serialize(serializer); - right->Serialize(serializer); +void SetOperationNode::Serialize(FieldWriter &writer) const { + writer.WriteField(setop_type); + writer.WriteSerializable(*left); + writer.WriteSerializable(*right); } -unique_ptr SetOperationNode::Deserialize(Deserializer &source) { +unique_ptr SetOperationNode::Deserialize(FieldReader &reader) { auto result = make_unique(); - result->setop_type = source.Read(); - result->left = QueryNode::Deserialize(source); - result->right = QueryNode::Deserialize(source); + result->setop_type = reader.ReadRequired(); + result->left = reader.ReadRequiredSerializable(); + result->right = reader.ReadRequiredSerializable(); return move(result); } @@ -129596,6 +141041,7 @@ unique_ptr SetOperationNode::Deserialize(Deserializer &source) { + namespace duckdb { bool QueryNode::Equals(const QueryNode *other) const { @@ -129649,32 +141095,30 @@ void QueryNode::CopyProperties(QueryNode &other) const { } } -void QueryNode::Serialize(Serializer &serializer) { - serializer.Write(type); - serializer.Write(modifiers.size()); - for (idx_t i = 0; i < modifiers.size(); i++) { - modifiers[i]->Serialize(serializer); - } +void QueryNode::Serialize(Serializer &main_serializer) const { + FieldWriter writer(main_serializer); + writer.WriteField(type); + writer.WriteSerializableList(modifiers); // cte_map - D_ASSERT(cte_map.size() <= NumericLimits::Maximum()); - serializer.Write((uint32_t)cte_map.size()); + writer.WriteField((uint32_t)cte_map.size()); + auto &serializer = writer.GetSerializer(); for (auto &cte : cte_map) { serializer.WriteString(cte.first); serializer.WriteStringVector(cte.second->aliases); cte.second->query->Serialize(serializer); } + Serialize(writer); + writer.Finalize(); } -unique_ptr QueryNode::Deserialize(Deserializer &source) { - unique_ptr result; - auto type = source.Read(); - auto modifier_count = source.Read(); - vector> modifiers; - for (idx_t i = 0; i < modifier_count; i++) { - modifiers.push_back(ResultModifier::Deserialize(source)); - } +unique_ptr QueryNode::Deserialize(Deserializer &main_source) { + FieldReader reader(main_source); + + auto type = reader.ReadRequired(); + auto modifiers = reader.ReadRequiredSerializableList(); // cte_map - auto cte_count = source.Read(); + auto cte_count = reader.ReadRequired(); + auto &source = reader.GetSource(); unordered_map> cte_map; for (idx_t i = 0; i < cte_count; i++) { auto name = source.Read(); @@ -129683,15 +141127,17 @@ unique_ptr QueryNode::Deserialize(Deserializer &source) { info->query = SelectStatement::Deserialize(source); cte_map[name] = move(info); } + + unique_ptr result; switch (type) { case QueryNodeType::SELECT_NODE: - result = SelectNode::Deserialize(source); + result = SelectNode::Deserialize(reader); break; case QueryNodeType::SET_OPERATION_NODE: - result = SetOperationNode::Deserialize(source); + result = SetOperationNode::Deserialize(reader); break; case QueryNodeType::RECURSIVE_CTE_NODE: - result = RecursiveCTENode::Deserialize(source); + result = RecursiveCTENode::Deserialize(reader); break; default: throw SerializationException("Could not deserialize Query Node: unknown type!"); @@ -129715,22 +141161,35 @@ bool ResultModifier::Equals(const ResultModifier *other) const { return type == other->type; } -void ResultModifier::Serialize(Serializer &serializer) { - serializer.Write(type); +void ResultModifier::Serialize(Serializer &serializer) const { + FieldWriter writer(serializer); + writer.WriteField(type); + Serialize(writer); + writer.Finalize(); } unique_ptr ResultModifier::Deserialize(Deserializer &source) { - auto type = source.Read(); + FieldReader reader(source); + auto type = reader.ReadRequired(); + + unique_ptr result; switch (type) { case ResultModifierType::LIMIT_MODIFIER: - return LimitModifier::Deserialize(source); + result = LimitModifier::Deserialize(reader); + break; case ResultModifierType::ORDER_MODIFIER: - return OrderModifier::Deserialize(source); + result = OrderModifier::Deserialize(reader); + break; case ResultModifierType::DISTINCT_MODIFIER: - return DistinctModifier::Deserialize(source); + result = DistinctModifier::Deserialize(reader); + break; + case ResultModifierType::LIMIT_PERCENT_MODIFIER: + result = LimitPercentModifier::Deserialize(reader); + break; default: throw InternalException("Unrecognized ResultModifierType for Deserialization"); } + return result; } bool LimitModifier::Equals(const ResultModifier *other_p) const { @@ -129747,7 +141206,7 @@ bool LimitModifier::Equals(const ResultModifier *other_p) const { return true; } -unique_ptr LimitModifier::Copy() { +unique_ptr LimitModifier::Copy() const { auto copy = make_unique(); if (limit) { copy->limit = limit->Copy(); @@ -129758,16 +141217,15 @@ unique_ptr LimitModifier::Copy() { return move(copy); } -void LimitModifier::Serialize(Serializer &serializer) { - ResultModifier::Serialize(serializer); - serializer.WriteOptional(limit); - serializer.WriteOptional(offset); +void LimitModifier::Serialize(FieldWriter &writer) const { + writer.WriteOptional(limit); + writer.WriteOptional(offset); } -unique_ptr LimitModifier::Deserialize(Deserializer &source) { +unique_ptr LimitModifier::Deserialize(FieldReader &reader) { auto mod = make_unique(); - mod->limit = source.ReadOptional(); - mod->offset = source.ReadOptional(); + mod->limit = reader.ReadOptional(nullptr); + mod->offset = reader.ReadOptional(nullptr); return move(mod); } @@ -129782,7 +141240,7 @@ bool DistinctModifier::Equals(const ResultModifier *other_p) const { return true; } -unique_ptr DistinctModifier::Copy() { +unique_ptr DistinctModifier::Copy() const { auto copy = make_unique(); for (auto &expr : distinct_on_targets) { copy->distinct_on_targets.push_back(expr->Copy()); @@ -129790,14 +141248,13 @@ unique_ptr DistinctModifier::Copy() { return move(copy); } -void DistinctModifier::Serialize(Serializer &serializer) { - ResultModifier::Serialize(serializer); - serializer.WriteList(distinct_on_targets); +void DistinctModifier::Serialize(FieldWriter &writer) const { + writer.WriteSerializableList(distinct_on_targets); } -unique_ptr DistinctModifier::Deserialize(Deserializer &source) { +unique_ptr DistinctModifier::Deserialize(FieldReader &reader) { auto mod = make_unique(); - source.ReadList(mod->distinct_on_targets); + mod->distinct_on_targets = reader.ReadRequiredSerializableList(); return move(mod); } @@ -129820,7 +141277,7 @@ bool OrderModifier::Equals(const ResultModifier *other_p) const { return true; } -unique_ptr OrderModifier::Copy() { +unique_ptr OrderModifier::Copy() const { auto copy = make_unique(); for (auto &order : orders) { copy->orders.emplace_back(order.type, order.null_order, order.expression->Copy()); @@ -129830,7 +141287,17 @@ unique_ptr OrderModifier::Copy() { string OrderByNode::ToString() const { auto str = expression->ToString(); - str += (type == OrderType::ASCENDING) ? " ASC" : " DESC"; + switch (type) { + case OrderType::ASCENDING: + str += " ASC"; + break; + case OrderType::DESCENDING: + str += " DESC"; + break; + default: + break; + } + switch (null_order) { case OrderByNullType::NULLS_FIRST: str += " NULLS FIRST"; @@ -129844,33 +141311,66 @@ string OrderByNode::ToString() const { return str; } -void OrderByNode::Serialize(Serializer &serializer) { - serializer.Write(type); - serializer.Write(null_order); - expression->Serialize(serializer); +void OrderByNode::Serialize(Serializer &serializer) const { + FieldWriter writer(serializer); + writer.WriteField(type); + writer.WriteField(null_order); + writer.WriteSerializable(*expression); + writer.Finalize(); } OrderByNode OrderByNode::Deserialize(Deserializer &source) { - auto type = source.Read(); - auto null_order = source.Read(); - auto expression = ParsedExpression::Deserialize(source); + FieldReader reader(source); + auto type = reader.ReadRequired(); + auto null_order = reader.ReadRequired(); + auto expression = reader.ReadRequiredSerializable(); return OrderByNode(type, null_order, move(expression)); } -void OrderModifier::Serialize(Serializer &serializer) { - ResultModifier::Serialize(serializer); - serializer.Write(orders.size()); - for (auto &order : orders) { - order.Serialize(serializer); - } +void OrderModifier::Serialize(FieldWriter &writer) const { + writer.WriteRegularSerializableList(orders); } -unique_ptr OrderModifier::Deserialize(Deserializer &source) { +unique_ptr OrderModifier::Deserialize(FieldReader &reader) { auto mod = make_unique(); - auto order_count = source.Read(); - for (int64_t i = 0; i < order_count; i++) { - mod->orders.push_back(OrderByNode::Deserialize((source))); + mod->orders = reader.ReadRequiredSerializableList(); + return move(mod); +} + +bool LimitPercentModifier::Equals(const ResultModifier *other_p) const { + if (!ResultModifier::Equals(other_p)) { + return false; } + auto &other = (LimitPercentModifier &)*other_p; + if (!BaseExpression::Equals(limit.get(), other.limit.get())) { + return false; + } + if (!BaseExpression::Equals(offset.get(), other.offset.get())) { + return false; + } + return true; +} + +unique_ptr LimitPercentModifier::Copy() const { + auto copy = make_unique(); + if (limit) { + copy->limit = limit->Copy(); + } + if (offset) { + copy->offset = offset->Copy(); + } + return move(copy); +} + +void LimitPercentModifier::Serialize(FieldWriter &writer) const { + writer.WriteOptional(limit); + writer.WriteOptional(offset); +} + +unique_ptr LimitPercentModifier::Deserialize(FieldReader &reader) { + auto mod = make_unique(); + mod->limit = reader.ReadOptional(nullptr); + mod->offset = reader.ReadOptional(nullptr); return move(mod); } @@ -129894,10 +141394,12 @@ namespace duckdb { class AlterStatement : public SQLStatement { public: AlterStatement(); - explicit AlterStatement(unique_ptr info); unique_ptr info; +protected: + AlterStatement(const AlterStatement &other); + public: unique_ptr Copy() const override; }; @@ -129909,13 +141411,12 @@ namespace duckdb { AlterStatement::AlterStatement() : SQLStatement(StatementType::ALTER_STATEMENT) { } -AlterStatement::AlterStatement(unique_ptr info) - : SQLStatement(StatementType::ALTER_STATEMENT), info(move(info)) { + +AlterStatement::AlterStatement(const AlterStatement &other) : SQLStatement(other), info(other.info->Copy()) { } unique_ptr AlterStatement::Copy() const { - auto result = make_unique(info->Copy()); - return move(result); + return unique_ptr(new AlterStatement(*this)); } } // namespace duckdb @@ -129941,6 +141442,9 @@ class CallStatement : public SQLStatement { unique_ptr function; +protected: + CallStatement(const CallStatement &other); + public: unique_ptr Copy() const override; }; @@ -129952,10 +141456,11 @@ namespace duckdb { CallStatement::CallStatement() : SQLStatement(StatementType::CALL_STATEMENT) { } +CallStatement::CallStatement(const CallStatement &other) : SQLStatement(other), function(other.function->Copy()) { +} + unique_ptr CallStatement::Copy() const { - auto result = make_unique(); - result->function = function->Copy(); - return move(result); + return unique_ptr(new CallStatement(*this)); } } // namespace duckdb @@ -129966,13 +141471,14 @@ namespace duckdb { CopyStatement::CopyStatement() : SQLStatement(StatementType::COPY_STATEMENT), info(make_unique()) { } -unique_ptr CopyStatement::Copy() const { - auto result = make_unique(); - result->info = info->Copy(); - if (select_statement) { - result->select_statement = select_statement->Copy(); +CopyStatement::CopyStatement(const CopyStatement &other) : SQLStatement(other), info(other.info->Copy()) { + if (other.select_statement) { + select_statement = other.select_statement->Copy(); } - return move(result); +} + +unique_ptr CopyStatement::Copy() const { + return unique_ptr(new CopyStatement(*this)); } } // namespace duckdb @@ -129983,10 +141489,11 @@ namespace duckdb { CreateStatement::CreateStatement() : SQLStatement(StatementType::CREATE_STATEMENT) { } +CreateStatement::CreateStatement(const CreateStatement &other) : SQLStatement(other), info(other.info->Copy()) { +} + unique_ptr CreateStatement::Copy() const { - auto result = make_unique(); - result->info = info->Copy(); - return move(result); + return unique_ptr(new CreateStatement(*this)); } } // namespace duckdb @@ -129997,16 +141504,17 @@ namespace duckdb { DeleteStatement::DeleteStatement() : SQLStatement(StatementType::DELETE_STATEMENT) { } -unique_ptr DeleteStatement::Copy() const { - auto result = make_unique(); - if (condition) { - result->condition = condition->Copy(); +DeleteStatement::DeleteStatement(const DeleteStatement &other) : SQLStatement(other), table(other.table->Copy()) { + if (other.condition) { + condition = other.condition->Copy(); } - result->table = table->Copy(); - for (auto &using_clause : using_clauses) { - result->using_clauses.push_back(using_clause->Copy()); + for (const auto &using_clause : other.using_clauses) { + using_clauses.push_back(using_clause->Copy()); } - return move(result); +} + +unique_ptr DeleteStatement::Copy() const { + return unique_ptr(new DeleteStatement(*this)); } } // namespace duckdb @@ -130017,10 +141525,11 @@ namespace duckdb { DropStatement::DropStatement() : SQLStatement(StatementType::DROP_STATEMENT), info(make_unique()) { } +DropStatement::DropStatement(const DropStatement &other) : SQLStatement(other), info(other.info->Copy()) { +} + unique_ptr DropStatement::Copy() const { - auto result = make_unique(); - result->info = info->Copy(); - return move(result); + return unique_ptr(new DropStatement(*this)); } } // namespace duckdb @@ -130031,13 +141540,14 @@ namespace duckdb { ExecuteStatement::ExecuteStatement() : SQLStatement(StatementType::EXECUTE_STATEMENT) { } -unique_ptr ExecuteStatement::Copy() const { - auto result = make_unique(); - result->name = name; - for (auto &value : values) { - result->values.push_back(value->Copy()); +ExecuteStatement::ExecuteStatement(const ExecuteStatement &other) : SQLStatement(other), name(other.name) { + for (const auto &value : other.values) { + values.push_back(value->Copy()); } - return move(result); +} + +unique_ptr ExecuteStatement::Copy() const { + return unique_ptr(new ExecuteStatement(*this)); } } // namespace duckdb @@ -130045,13 +141555,16 @@ unique_ptr ExecuteStatement::Copy() const { namespace duckdb { -ExplainStatement::ExplainStatement(unique_ptr stmt) - : SQLStatement(StatementType::EXPLAIN_STATEMENT), stmt(move(stmt)) { +ExplainStatement::ExplainStatement(unique_ptr stmt, ExplainType explain_type) + : SQLStatement(StatementType::EXPLAIN_STATEMENT), stmt(move(stmt)), explain_type(explain_type) { +} + +ExplainStatement::ExplainStatement(const ExplainStatement &other) + : SQLStatement(other), stmt(other.stmt->Copy()), explain_type(other.explain_type) { } unique_ptr ExplainStatement::Copy() const { - auto result = make_unique(stmt->Copy()); - return move(result); + return unique_ptr(new ExplainStatement(*this)); } } // namespace duckdb @@ -130077,6 +141590,9 @@ class ExportStatement : public SQLStatement { unique_ptr info; +protected: + ExportStatement(const ExportStatement &other); + public: unique_ptr Copy() const override; }; @@ -130090,8 +141606,11 @@ ExportStatement::ExportStatement(unique_ptr info) : SQLStatement(StatementType::EXPORT_STATEMENT), info(move(info)) { } +ExportStatement::ExportStatement(const ExportStatement &other) : SQLStatement(other), info(other.info->Copy()) { +} + unique_ptr ExportStatement::Copy() const { - return make_unique_base(info->Copy()); + return unique_ptr(new ExportStatement(*this)); } } // namespace duckdb @@ -130102,20 +141621,21 @@ namespace duckdb { InsertStatement::InsertStatement() : SQLStatement(StatementType::INSERT_STATEMENT), schema(DEFAULT_SCHEMA) { } +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) { +} + unique_ptr InsertStatement::Copy() const { - auto result = make_unique(); - result->select_statement = unique_ptr_cast(select_statement->Copy()); - result->columns = columns; - result->table = table; - result->schema = schema; - return move(result); + return unique_ptr(new InsertStatement(*this)); } } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/parser/statement/set_statement.hpp +// duckdb/parser/statement/load_statement.hpp // // //===----------------------------------------------------------------------===// @@ -130131,6 +141651,9 @@ class LoadStatement : public SQLStatement { public: LoadStatement(); +protected: + LoadStatement(const LoadStatement &other); + public: unique_ptr Copy() const override; @@ -130144,10 +141667,11 @@ namespace duckdb { LoadStatement::LoadStatement() : SQLStatement(StatementType::LOAD_STATEMENT) { } +LoadStatement::LoadStatement(const LoadStatement &other) : SQLStatement(other), info(other.info->Copy()) { +} + unique_ptr LoadStatement::Copy() const { - auto result = make_unique(); - result->info = info->Copy(); - return move(result); + return unique_ptr(new LoadStatement(*this)); } } // namespace duckdb @@ -130158,10 +141682,11 @@ namespace duckdb { PragmaStatement::PragmaStatement() : SQLStatement(StatementType::PRAGMA_STATEMENT), info(make_unique()) { } +PragmaStatement::PragmaStatement(const PragmaStatement &other) : SQLStatement(other), info(other.info->Copy()) { +} + unique_ptr PragmaStatement::Copy() const { - auto result = make_unique(); - result->info = info->Copy(); - return move(result); + return unique_ptr(new PragmaStatement(*this)); } } // namespace duckdb @@ -130172,11 +141697,12 @@ namespace duckdb { PrepareStatement::PrepareStatement() : SQLStatement(StatementType::PREPARE_STATEMENT), statement(nullptr), name("") { } +PrepareStatement::PrepareStatement(const PrepareStatement &other) + : SQLStatement(other), statement(other.statement->Copy()), name(other.name) { +} + unique_ptr PrepareStatement::Copy() const { - auto result = make_unique(); - result->statement = statement->Copy(); - result->name = name; - return move(result); + return unique_ptr(new PrepareStatement(*this)); } } // namespace duckdb @@ -130189,8 +141715,7 @@ RelationStatement::RelationStatement(shared_ptr relation) } unique_ptr RelationStatement::Copy() const { - auto result = make_unique(relation); - return move(result); + return unique_ptr(new RelationStatement(*this)); } } // namespace duckdb @@ -130200,13 +141725,14 @@ unique_ptr RelationStatement::Copy() const { namespace duckdb { +SelectStatement::SelectStatement(const SelectStatement &other) : SQLStatement(other), node(other.node->Copy()) { +} + unique_ptr SelectStatement::Copy() const { - auto result = make_unique(); - result->node = node->Copy(); - return move(result); + return unique_ptr(new SelectStatement(*this)); } -void SelectStatement::Serialize(Serializer &serializer) { +void SelectStatement::Serialize(Serializer &serializer) const { node->Serialize(serializer); } @@ -130245,6 +141771,9 @@ class SetStatement : public SQLStatement { public: SetStatement(std::string name_p, Value value_p, SetScope scope_p); +protected: + SetStatement(const SetStatement &other) = default; + public: unique_ptr Copy() const override; @@ -130262,7 +141791,7 @@ SetStatement::SetStatement(std::string name_p, Value value_p, SetScope scope_p) } unique_ptr SetStatement::Copy() const { - return make_unique(name, value, scope); + return unique_ptr(new SetStatement(*this)); } } // namespace duckdb @@ -130287,6 +141816,9 @@ class ShowStatement : public SQLStatement { unique_ptr info; +protected: + ShowStatement(const ShowStatement &other); + public: unique_ptr Copy() const override; }; @@ -130299,10 +141831,11 @@ namespace duckdb { ShowStatement::ShowStatement() : SQLStatement(StatementType::SHOW_STATEMENT), info(make_unique()) { } +ShowStatement::ShowStatement(const ShowStatement &other) : SQLStatement(other), info(other.info->Copy()) { +} + unique_ptr ShowStatement::Copy() const { - auto result = make_unique(); - result->info = info->Copy(); - return move(result); + return unique_ptr(new ShowStatement(*this)); } } // namespace duckdb @@ -130327,6 +141860,9 @@ class TransactionStatement : public SQLStatement { unique_ptr info; +protected: + TransactionStatement(const TransactionStatement &other); + public: unique_ptr Copy() const override; }; @@ -130339,8 +141875,12 @@ TransactionStatement::TransactionStatement(TransactionType type) : SQLStatement(StatementType::TRANSACTION_STATEMENT), info(make_unique(type)) { } +TransactionStatement::TransactionStatement(const TransactionStatement &other) + : SQLStatement(other), info(make_unique(other.info->type)) { +} + unique_ptr TransactionStatement::Copy() const { - return make_unique_base(info->type); + return unique_ptr(new TransactionStatement(*this)); } } // namespace duckdb @@ -130351,20 +141891,21 @@ namespace duckdb { UpdateStatement::UpdateStatement() : SQLStatement(StatementType::UPDATE_STATEMENT) { } -unique_ptr UpdateStatement::Copy() const { - auto result = make_unique(); - if (condition) { - result->condition = condition->Copy(); +UpdateStatement::UpdateStatement(const UpdateStatement &other) + : SQLStatement(other), table(other.table->Copy()), columns(other.columns) { + if (other.condition) { + condition = other.condition->Copy(); } - result->table = table->Copy(); - if (from_table) { - result->from_table = from_table->Copy(); + if (other.from_table) { + from_table = other.from_table->Copy(); } - result->columns = columns; - for (auto &expr : expressions) { - result->expressions.push_back(expr->Copy()); + for (auto &expr : other.expressions) { + expressions.emplace_back(expr->Copy()); } - return move(result); +} + +unique_ptr UpdateStatement::Copy() const { + return unique_ptr(new UpdateStatement(*this)); } } // namespace duckdb @@ -130390,6 +141931,9 @@ class VacuumStatement : public SQLStatement { unique_ptr info; +protected: + VacuumStatement(const VacuumStatement &other) : SQLStatement(other) {}; + public: unique_ptr Copy() const override; }; @@ -130403,7 +141947,7 @@ VacuumStatement::VacuumStatement() : SQLStatement(StatementType::VACUUM_STATEMEN } unique_ptr VacuumStatement::Copy() const { - return make_unique(); + return unique_ptr(new VacuumStatement(*this)); } } // namespace duckdb @@ -130426,20 +141970,18 @@ bool BaseTableRef::Equals(const TableRef *other_p) const { column_name_alias == other->column_name_alias; } -void BaseTableRef::Serialize(Serializer &serializer) { - TableRef::Serialize(serializer); - - serializer.WriteString(schema_name); - serializer.WriteString(table_name); - serializer.WriteStringVector(column_name_alias); +void BaseTableRef::Serialize(FieldWriter &writer) const { + writer.WriteString(schema_name); + writer.WriteString(table_name); + writer.WriteList(column_name_alias); } -unique_ptr BaseTableRef::Deserialize(Deserializer &source) { +unique_ptr BaseTableRef::Deserialize(FieldReader &reader) { auto result = make_unique(); - result->schema_name = source.Read(); - result->table_name = source.Read(); - source.ReadStringVector(result->column_name_alias); + result->schema_name = reader.ReadRequired(); + result->table_name = reader.ReadRequired(); + result->column_name_alias = reader.ReadRequiredList(); return move(result); } @@ -130455,41 +141997,6 @@ unique_ptr BaseTableRef::Copy() { return move(copy); } } // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/tableref/crossproductref.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -namespace duckdb { -//! Represents a cross product -class CrossProductRef : public TableRef { -public: - CrossProductRef() : TableRef(TableReferenceType::CROSS_PRODUCT) { - } - - //! The left hand side of the cross product - unique_ptr left; - //! The right hand side of the cross product - unique_ptr right; - -public: - bool Equals(const TableRef *other_p) const override; - - unique_ptr Copy() override; - - //! Serializes a blob into a CrossProductRef - void Serialize(Serializer &serializer) override; - //! Deserializes a blob back into a CrossProductRef - static unique_ptr Deserialize(Deserializer &source); -}; -} // namespace duckdb @@ -130512,57 +142019,23 @@ unique_ptr CrossProductRef::Copy() { return move(copy); } -void CrossProductRef::Serialize(Serializer &serializer) { - TableRef::Serialize(serializer); - - left->Serialize(serializer); - right->Serialize(serializer); +void CrossProductRef::Serialize(FieldWriter &writer) const { + writer.WriteSerializable(*left); + writer.WriteSerializable(*right); } -unique_ptr CrossProductRef::Deserialize(Deserializer &source) { +unique_ptr CrossProductRef::Deserialize(FieldReader &reader) { auto result = make_unique(); - result->left = TableRef::Deserialize(source); - result->right = TableRef::Deserialize(source); - - if (!result->left || !result->right) { - return nullptr; - } + result->left = reader.ReadRequiredSerializable(); + result->right = reader.ReadRequiredSerializable(); + D_ASSERT(result->left); + D_ASSERT(result->right); return move(result); } } // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/tableref/emptytableref.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -namespace duckdb { -//! Represents a cross product -class EmptyTableRef : public TableRef { -public: - EmptyTableRef() : TableRef(TableReferenceType::EMPTY) { - } - -public: - bool Equals(const TableRef *other_p) const override; - - unique_ptr Copy() override; - - //! Serializes a blob into a DummyTableRef - void Serialize(Serializer &serializer) override; - //! Deserializes a blob back into a DummyTableRef - static unique_ptr Deserialize(Deserializer &source); -}; -} // namespace duckdb @@ -130577,11 +142050,10 @@ unique_ptr EmptyTableRef::Copy() { return make_unique(); } -void EmptyTableRef::Serialize(Serializer &serializer) { - TableRef::Serialize(serializer); +void EmptyTableRef::Serialize(FieldWriter &writer) const { } -unique_ptr EmptyTableRef::Deserialize(Deserializer &source) { +unique_ptr EmptyTableRef::Deserialize(FieldReader &reader) { return make_unique(); } @@ -130630,34 +142102,23 @@ unique_ptr ExpressionListRef::Copy() { return move(result); } -void ExpressionListRef::Serialize(Serializer &serializer) { - TableRef::Serialize(serializer); - serializer.Write(expected_names.size()); - for (idx_t i = 0; i < expected_names.size(); i++) { - serializer.WriteString(expected_names[i]); - } - serializer.Write(expected_types.size()); - for (idx_t i = 0; i < expected_types.size(); i++) { - expected_types[i].Serialize(serializer); - } - serializer.Write(values.size()); +void ExpressionListRef::Serialize(FieldWriter &writer) const { + writer.WriteList(expected_names); + writer.WriteRegularSerializableList(expected_types); + auto &serializer = writer.GetSerializer(); + writer.WriteField(values.size()); for (idx_t i = 0; i < values.size(); i++) { serializer.WriteList(values[i]); } } -unique_ptr ExpressionListRef::Deserialize(Deserializer &source) { +unique_ptr ExpressionListRef::Deserialize(FieldReader &reader) { auto result = make_unique(); // value list - auto name_count = source.Read(); - for (idx_t i = 0; i < name_count; i++) { - result->expected_names.push_back(source.Read()); - } - auto type_count = source.Read(); - for (idx_t i = 0; i < type_count; i++) { - result->expected_types.push_back(LogicalType::Deserialize(source)); - } - idx_t value_list_size = source.Read(); + result->expected_names = reader.ReadRequiredList(); + result->expected_types = reader.ReadRequiredSerializableList(); + idx_t value_list_size = reader.ReadRequired(); + auto &source = reader.GetSource(); for (idx_t i = 0; i < value_list_size; i++) { vector> value_list; source.ReadList(value_list); @@ -130705,33 +142166,23 @@ unique_ptr JoinRef::Copy() { return move(copy); } -void JoinRef::Serialize(Serializer &serializer) { - TableRef::Serialize(serializer); - - left->Serialize(serializer); - right->Serialize(serializer); - serializer.WriteOptional(condition); - serializer.Write(type); - serializer.Write(is_natural); - D_ASSERT(using_columns.size() <= NumericLimits::Maximum()); - serializer.Write((uint32_t)using_columns.size()); - for (auto &using_column : using_columns) { - serializer.WriteString(using_column); - } +void JoinRef::Serialize(FieldWriter &writer) const { + writer.WriteSerializable(*left); + writer.WriteSerializable(*right); + writer.WriteOptional(condition); + writer.WriteField(type); + writer.WriteField(is_natural); + writer.WriteList(using_columns); } -unique_ptr JoinRef::Deserialize(Deserializer &source) { +unique_ptr JoinRef::Deserialize(FieldReader &reader) { auto result = make_unique(); - - result->left = TableRef::Deserialize(source); - result->right = TableRef::Deserialize(source); - result->condition = source.ReadOptional(); - result->type = source.Read(); - result->is_natural = source.Read(); - auto count = source.Read(); - for (idx_t i = 0; i < count; i++) { - result->using_columns.push_back(source.Read()); - } + result->left = reader.ReadRequiredSerializable(); + result->right = reader.ReadRequiredSerializable(); + result->condition = reader.ReadOptional(nullptr); + result->type = reader.ReadRequired(); + result->is_natural = reader.ReadRequired(); + result->using_columns = reader.ReadRequiredList(); return move(result); } @@ -130763,19 +142214,15 @@ unique_ptr SubqueryRef::Copy() { return move(copy); } -void SubqueryRef::Serialize(Serializer &serializer) { - TableRef::Serialize(serializer); - subquery->Serialize(serializer); - serializer.WriteStringVector(column_name_alias); +void SubqueryRef::Serialize(FieldWriter &writer) const { + writer.WriteSerializable(*subquery); + writer.WriteList(column_name_alias); } -unique_ptr SubqueryRef::Deserialize(Deserializer &source) { - auto subquery = SelectStatement::Deserialize(source); - if (!subquery) { - return nullptr; - } +unique_ptr SubqueryRef::Deserialize(FieldReader &reader) { + auto subquery = reader.ReadRequiredSerializable(); auto result = make_unique(move(subquery)); - source.ReadStringVector(result->column_name_alias); + result->column_name_alias = reader.ReadRequiredList(); return move(result); } @@ -130798,20 +142245,17 @@ bool TableFunctionRef::Equals(const TableRef *other_p) const { return function->Equals(other->function.get()); } -void TableFunctionRef::Serialize(Serializer &serializer) { - TableRef::Serialize(serializer); - function->Serialize(serializer); - serializer.WriteString(alias); - serializer.WriteStringVector(column_name_alias); +void TableFunctionRef::Serialize(FieldWriter &writer) const { + writer.WriteSerializable(*function); + writer.WriteString(alias); + writer.WriteList(column_name_alias); } -unique_ptr TableFunctionRef::Deserialize(Deserializer &source) { +unique_ptr TableFunctionRef::Deserialize(FieldReader &reader) { auto result = make_unique(); - - result->function = ParsedExpression::Deserialize(source); - result->alias = source.Read(); - source.ReadStringVector(result->column_name_alias); - + result->function = reader.ReadRequiredSerializable(); + result->alias = reader.ReadRequired(); + result->column_name_alias = reader.ReadRequiredList(); return move(result); } @@ -130832,13 +142276,6 @@ unique_ptr TableFunctionRef::Copy() { - - - - - - - namespace duckdb { string TableRef::ToString() const { @@ -130850,44 +142287,50 @@ bool TableRef::Equals(const TableRef *other) const { SampleOptions::Equals(sample.get(), other->sample.get()); } -void TableRef::Serialize(Serializer &serializer) { - serializer.Write(type); - serializer.WriteString(alias); - serializer.WriteOptional(sample); +void TableRef::Serialize(Serializer &serializer) const { + FieldWriter writer(serializer); + writer.WriteField(type); + writer.WriteString(alias); + writer.WriteOptional(sample); + Serialize(writer); + writer.Finalize(); } -//! Deserializes a blob back into an TableRef unique_ptr TableRef::Deserialize(Deserializer &source) { - auto type = source.Read(); - auto alias = source.Read(); - auto sample = source.ReadOptional(); + FieldReader reader(source); + + auto type = reader.ReadRequired(); + auto alias = reader.ReadRequired(); + auto sample = reader.ReadOptional(nullptr); unique_ptr result; switch (type) { case TableReferenceType::BASE_TABLE: - result = BaseTableRef::Deserialize(source); + result = BaseTableRef::Deserialize(reader); break; case TableReferenceType::CROSS_PRODUCT: - result = CrossProductRef::Deserialize(source); + result = CrossProductRef::Deserialize(reader); break; case TableReferenceType::JOIN: - result = JoinRef::Deserialize(source); + result = JoinRef::Deserialize(reader); break; case TableReferenceType::SUBQUERY: - result = SubqueryRef::Deserialize(source); + result = SubqueryRef::Deserialize(reader); break; case TableReferenceType::TABLE_FUNCTION: - result = TableFunctionRef::Deserialize(source); + result = TableFunctionRef::Deserialize(reader); break; case TableReferenceType::EMPTY: - result = EmptyTableRef::Deserialize(source); + result = EmptyTableRef::Deserialize(reader); break; case TableReferenceType::EXPRESSION_LIST: - result = ExpressionListRef::Deserialize(source); + result = ExpressionListRef::Deserialize(reader); break; case TableReferenceType::CTE: case TableReferenceType::INVALID: throw InternalException("Unsupported type for TableRef::Deserialize"); } + reader.Finalize(); + result->alias = alias; result->sample = move(sample); return result; @@ -131023,7 +142466,7 @@ unique_ptr Transformer::TransformArrayAccess(duckdb_libpgquery throw NotImplementedException("Unimplemented subscript type"); } list_size++; - StackCheck(list_size * DEFAULT_ENTRY_STACK_SIZE); + StackCheck(list_size); } return result; } @@ -131219,28 +142662,13 @@ unique_ptr Transformer::TransformColumnRef(duckdb_libpgquery:: if (fields->length < 1) { throw InternalException("Unexpected field length"); } - string column_name, table_name; - if (fields->length == 1) { - column_name = string(reinterpret_cast(fields->head->data.ptr_value)->val.str); - auto colref = make_unique(column_name, table_name); - colref->query_location = root->location; - return move(colref); - } else if (fields->length == 2) { - table_name = string(reinterpret_cast(fields->head->data.ptr_value)->val.str); - auto col_node = reinterpret_cast(fields->head->next->data.ptr_value); - switch (col_node->type) { - case duckdb_libpgquery::T_PGString: { - column_name = string(reinterpret_cast(col_node)->val.str); - auto colref = make_unique(column_name, table_name); - colref->query_location = root->location; - return move(colref); - } - default: - throw NotImplementedException("ColumnRef not implemented!"); - } - } else { - throw NotImplementedException("ColumnRef not implemented!"); + vector column_names; + 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)); + colref->query_location = root->location; + return move(colref); } case duckdb_libpgquery::T_PGAStar: { return TransformStarExpression(head_node); @@ -131298,7 +142726,9 @@ unique_ptr Transformer::TransformValue(duckdb_libpgquery::PG return make_unique(Value::HUGEINT(hugeint_value)); } } - if (try_cast_as_decimal && decimal_position >= 0 && str_val.GetSize() < Decimal::MAX_WIDTH_DECIMAL + 2) { + idx_t decimal_offset = val.val.str[0] == '-' ? 3 : 2; + if (try_cast_as_decimal && decimal_position >= 0 && + str_val.GetSize() < Decimal::MAX_WIDTH_DECIMAL + decimal_offset) { // figure out the width/scale based on the decimal position auto width = uint8_t(str_val.GetSize() - 1); auto scale = uint8_t(width - decimal_position); @@ -131365,7 +142795,7 @@ unique_ptr Transformer::TransformExpression(duckdb_libpgquery: return nullptr; } - StackCheck(); + auto stack_checker = StackCheck(); switch (node->type) { case duckdb_libpgquery::T_PGColumnRef: @@ -131410,6 +142840,8 @@ unique_ptr Transformer::TransformExpression(duckdb_libpgquery: return TransformPositionalReference(reinterpret_cast(node)); case duckdb_libpgquery::T_PGGroupingFunc: return TransformGroupingFunction(reinterpret_cast(node)); + case duckdb_libpgquery::T_PGAStar: + return TransformStarExpression(node); default: throw NotImplementedException("Expr of type %d not implemented\n", (int)node->type); } @@ -131550,12 +142982,21 @@ unique_ptr Transformer::TransformFuncCall(duckdb_libpgquery::P throw ParserException("ORDER BY is not implemented for window functions!"); } - auto win_fun_type = WindowToExpressionType(lowercase_name); + if (root->agg_filter) { + throw ParserException("FILTER is not implemented for window functions!"); + } + + const auto win_fun_type = WindowToExpressionType(lowercase_name); if (win_fun_type == ExpressionType::INVALID) { throw InternalException("Unknown/unsupported window function"); } + if (win_fun_type == ExpressionType::WINDOW_AGGREGATE && root->agg_ignore_nulls) { + throw ParserException("IGNORE NULLS is not supported for windowed aggregates"); + } + auto expr = make_unique(win_fun_type, schema, lowercase_name); + expr->ignore_nulls = root->agg_ignore_nulls; if (root->args) { vector> function_list; @@ -131617,6 +143058,10 @@ unique_ptr Transformer::TransformFuncCall(duckdb_libpgquery::P return move(expr); } + if (root->agg_ignore_nulls) { + throw ParserException("IGNORE NULLS is not supported for non-window functions"); + } + // TransformExpressionList?? vector> children; if (root->args != nullptr) { @@ -131911,10 +143356,10 @@ static string ExtractColumnFromLambda(ParsedExpression &expr) { throw ParserException("Lambda parameter must be a column name"); } auto &colref = (ColumnRefExpression &)expr; - if (!colref.table_name.empty()) { + if (colref.IsQualified()) { throw ParserException("Lambda parameter must be an unqualified name (e.g. 'x', not 'a.x')"); } - return colref.column_name; + return colref.column_names[0]; } unique_ptr Transformer::TransformLambda(duckdb_libpgquery::PGLambdaFunction *node) { @@ -132106,7 +143551,7 @@ unique_ptr Transformer::TransformAExpr(duckdb_libpgquery::PGAE throw NotImplementedException("Custom escape in SIMILAR TO"); } auto &constant = (ConstantExpression &)*similar_func.children[1]; - if (!constant.value.is_null) { + if (!constant.value.IsNull()) { throw NotImplementedException("Custom escape in SIMILAR TO"); } // take the child of the similar_func @@ -133252,6 +144697,7 @@ void Transformer::AddGroupByExpression(unique_ptr expression, static void AddCubeSets(const GroupingSet ¤t_set, vector &result_set, vector &result_sets, idx_t start_idx = 0) { + CheckGroupingSetMax(result_sets.size()); result_sets.push_back(current_set); for (idx_t k = start_idx; k < result_set.size(); k++) { auto child_set = current_set; @@ -133268,7 +144714,7 @@ void Transformer::TransformGroupByExpression(duckdb_libpgquery::PGNode *n, Group // If one GROUPING SETS clause is nested inside another, // the effect is the same as if all the elements of the inner clause had been written directly in the outer clause. -void Transformer::TransformGroupByNode(duckdb_libpgquery::PGNode *n, GroupingExpressionMap &map, GroupByNode &result, +void Transformer::TransformGroupByNode(duckdb_libpgquery::PGNode *n, GroupingExpressionMap &map, SelectNode &result, vector &result_sets) { if (n->type == duckdb_libpgquery::T_PGGroupingSet) { auto grouping_set = (duckdb_libpgquery::PGGroupingSet *)n; @@ -133276,6 +144722,10 @@ void Transformer::TransformGroupByNode(duckdb_libpgquery::PGNode *n, GroupingExp case duckdb_libpgquery::GROUPING_SET_EMPTY: result_sets.emplace_back(); break; + case duckdb_libpgquery::GROUPING_SET_ALL: { + result.aggregate_handling = AggregateHandling::FORCE_AGGREGATES; + break; + } case duckdb_libpgquery::GROUPING_SET_SETS: { for (auto node = grouping_set->content->head; node; node = node->next) { auto pg_node = (duckdb_libpgquery::PGNode *)node->data.ptr_value; @@ -133288,7 +144738,7 @@ void Transformer::TransformGroupByNode(duckdb_libpgquery::PGNode *n, GroupingExp for (auto node = grouping_set->content->head; node; node = node->next) { auto pg_node = (duckdb_libpgquery::PGNode *)node->data.ptr_value; vector rollup_set; - TransformGroupByExpression(pg_node, map, result, rollup_set); + TransformGroupByExpression(pg_node, map, result.groups, rollup_set); rollup_sets.push_back(VectorToGroupingSet(rollup_set)); } // generate the subsets of the rollup set and add them to the grouping sets @@ -133305,7 +144755,7 @@ void Transformer::TransformGroupByNode(duckdb_libpgquery::PGNode *n, GroupingExp for (auto node = grouping_set->content->head; node; node = node->next) { auto pg_node = (duckdb_libpgquery::PGNode *)node->data.ptr_value; vector cube_set; - TransformGroupByExpression(pg_node, map, result, cube_set); + TransformGroupByExpression(pg_node, map, result.groups, cube_set); cube_sets.push_back(VectorToGroupingSet(cube_set)); } // generate the subsets of the rollup set and add them to the grouping sets @@ -133318,22 +144768,23 @@ void Transformer::TransformGroupByNode(duckdb_libpgquery::PGNode *n, GroupingExp } } else { vector indexes; - TransformGroupByExpression(n, map, result, indexes); + TransformGroupByExpression(n, map, result.groups, indexes); result_sets.push_back(VectorToGroupingSet(indexes)); } } // If multiple grouping items are specified in a single GROUP BY clause, // then the final list of grouping sets is the cross product of the individual items. -bool Transformer::TransformGroupBy(duckdb_libpgquery::PGList *group, GroupByNode &result) { +bool Transformer::TransformGroupBy(duckdb_libpgquery::PGList *group, SelectNode &select_node) { if (!group) { return false; } + auto &result = select_node.groups; GroupingExpressionMap map; for (auto node = group->head; node != nullptr; node = node->next) { auto n = reinterpret_cast(node->data.ptr_value); vector result_sets; - TransformGroupByNode(n, map, result, result_sets); + TransformGroupByNode(n, map, select_node, result_sets); CheckGroupingSetMax(result_sets.size()); if (result.grouping_sets.empty()) { // no grouping sets yet: use the current set of grouping sets @@ -133474,6 +144925,8 @@ LogicalType Transformer::TransformTypeName(duckdb_libpgquery::PGTypeName *type_n if (type_name->type != duckdb_libpgquery::T_PGTypeName) { throw ParserException("Expected a type"); } + auto stack_checker = StackCheck(); + auto name = (reinterpret_cast(type_name->names->tail->data.ptr_value)->val.str); // transform it to the SQL type LogicalTypeId base_type = TransformStringToLogicalType(name); @@ -133602,8 +145055,10 @@ LogicalType Transformer::TransformTypeName(duckdb_libpgquery::PGTypeName *type_n } if (type_name->arrayBounds) { // 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)); + StackCheck(extra_stack++); } } return result_type; @@ -133614,6 +145069,67 @@ LogicalType Transformer::TransformTypeName(duckdb_libpgquery::PGTypeName *type_n +namespace duckdb { + +unique_ptr Transformer::TransformAlterSequence(duckdb_libpgquery::PGNode *node) { + auto stmt = reinterpret_cast(node); + D_ASSERT(stmt); + auto result = make_unique(); + + auto qname = TransformQualifiedName(stmt->sequence); + auto sequence_schema = qname.schema; + auto sequence_name = qname.name; + + if (!stmt->options) { + throw InternalException("Expected an argument for ALTER SEQUENCE."); + } + + duckdb_libpgquery::PGListCell *cell = nullptr; + for_each_cell(cell, stmt->options->head) { + auto *def_elem = reinterpret_cast(cell->data.ptr_value); + string opt_name = string(def_elem->defname); + + if (opt_name == "owned_by") { + auto val = (duckdb_libpgquery::PGValue *)def_elem->arg; + if (!val) { + throw InternalException("Expected an argument for option %s", opt_name); + } + D_ASSERT(val); + if (val->type != duckdb_libpgquery::T_PGList) { + throw InternalException("Expected a string argument for option %s", opt_name); + } + auto opt_values = vector(); + + auto opt_value_list = (duckdb_libpgquery::PGList *)(val); + for (auto c = opt_value_list->head; c != nullptr; c = lnext(c)) { + auto target = (duckdb_libpgquery::PGResTarget *)(c->data.ptr_value); + opt_values.emplace_back(target->name); + } + D_ASSERT(!opt_values.empty()); + string owner_schema = ""; + string owner_name = ""; + if (opt_values.size() == 2) { + owner_schema = opt_values[0]; + owner_name = opt_values[1]; + } else if (opt_values.size() == 1) { + owner_schema = DEFAULT_SCHEMA; + owner_name = opt_values[0]; + } 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); + result->info = move(info); + } else { + throw NotImplementedException("ALTER SEQUENCE option not supported yet!"); + } + } + return result; +} +} // namespace duckdb + + + namespace duckdb { @@ -133778,9 +145294,19 @@ unique_ptr Transformer::TransformCopy(duckdb_libpgquery::PGNode * auto &info = *result->info; // get file_path and is_from - info.file_path = stmt->filename; info.is_from = stmt->is_from; - info.format = "csv"; + if (!stmt->filename) { + // stdin/stdout + info.file_path = info.is_from ? "/dev/stdin" : "/dev/stdout"; + } else { + // copy to a file + info.file_path = stmt->filename; + } + if (StringUtil::EndsWith(info.file_path, ".parquet")) { + info.format = "parquet"; + } else { + info.format = "csv"; + } // get select_list if (stmt->attlist) { @@ -133813,6 +145339,7 @@ unique_ptr Transformer::TransformCopy(duckdb_libpgquery::PGNode * + namespace duckdb { vector ReadPgListToString(duckdb_libpgquery::PGList *column_list) { @@ -133827,14 +145354,36 @@ vector ReadPgListToString(duckdb_libpgquery::PGList *column_list) { return result; } +Vector ReadPgListToVector(duckdb_libpgquery::PGList *column_list, idx_t &size) { + if (!column_list) { + Vector result(LogicalType::VARCHAR); + return result; + } + // First we discover the size of this list + for (auto c = column_list->head; c != nullptr; c = lnext(c)) { + size++; + } + + Vector result(LogicalType::VARCHAR, size); + auto result_ptr = FlatVector::GetData(result); + + size = 0; + for (auto c = column_list->head; c != nullptr; c = lnext(c)) { + auto target = (duckdb_libpgquery::PGResTarget *)(c->data.ptr_value); + result_ptr[size++] = StringVector::AddStringOrBlob(result, target->name); + } + return result; +} + unique_ptr Transformer::TransformCreateEnum(duckdb_libpgquery::PGNode *node) { auto stmt = reinterpret_cast(node); D_ASSERT(stmt); auto result = make_unique(); auto info = make_unique(); info->name = ReadPgListToString(stmt->typeName)[0]; - vector ordered_array = ReadPgListToString(stmt->vals); - info->type = make_unique(LogicalType::ENUM(info->name, ordered_array)); + idx_t size = 0; + auto ordered_array = ReadPgListToVector(stmt->vals, size); + info->type = LogicalType::ENUM(info->name, ordered_array, size); result->info = move(info); return result; } @@ -133876,7 +145425,8 @@ 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); + auto alias = param->alias; + macro_func->default_parameters[alias] = move(param); } else if (param->GetExpressionClass() == ExpressionClass::COLUMN_REF) { // positional parameters if (!macro_func->default_parameters.empty()) { @@ -134396,7 +145946,19 @@ namespace duckdb { unique_ptr Transformer::TransformExplain(duckdb_libpgquery::PGNode *node) { auto stmt = reinterpret_cast(node); D_ASSERT(stmt); - return make_unique(TransformStatement(stmt->query)); + auto explain_type = ExplainType::EXPLAIN_STANDARD; + if (stmt->options) { + for (auto n = stmt->options->head; n; n = n->next) { + auto def_elem = ((duckdb_libpgquery::PGDefElem *)n->data.ptr_value)->defname; + string elem(def_elem); + if (elem == "analyze") { + explain_type = ExplainType::EXPLAIN_ANALYZE; + } else { + throw NotImplementedException("Unimplemented explain type: %s", elem); + } + } + } + return make_unique(TransformStatement(stmt->query), explain_type); } } // namespace duckdb @@ -134493,6 +146055,17 @@ unique_ptr Transformer::TransformLoad(duckdb_libpgquery::PGNode * auto load_stmt = make_unique(); auto load_info = make_unique(); load_info->filename = std::string(stmt->filename); + switch (stmt->load_type) { + case duckdb_libpgquery::PG_LOAD_TYPE_LOAD: + load_info->load_type = LoadType::LOAD; + break; + case duckdb_libpgquery::PG_LOAD_TYPE_INSTALL: + load_info->load_type = LoadType::INSTALL; + break; + case duckdb_libpgquery::PG_LOAD_TYPE_FORCE_INSTALL: + load_info->load_type = LoadType::FORCE_INSTALL; + break; + } load_stmt->info = move(load_info); return load_stmt; } @@ -134504,9 +146077,11 @@ unique_ptr Transformer::TransformLoad(duckdb_libpgquery::PGNode * + + namespace duckdb { -unique_ptr Transformer::TransformPragma(duckdb_libpgquery::PGNode *node) { +unique_ptr Transformer::TransformPragma(duckdb_libpgquery::PGNode *node) { auto stmt = reinterpret_cast(node); auto result = make_unique(); @@ -134532,26 +146107,36 @@ unique_ptr Transformer::TransformPragma(duckdb_libpgquery::PGNo } // now parse the pragma type switch (stmt->kind) { - case duckdb_libpgquery::PG_PRAGMA_TYPE_NOTHING: + case duckdb_libpgquery::PG_PRAGMA_TYPE_NOTHING: { if (!info.parameters.empty() || !info.named_parameters.empty()) { - throw ParserException("PRAGMA statement that is not a call or assignment cannot contain parameters"); + throw InternalException("PRAGMA statement that is not a call or assignment cannot contain parameters"); } break; case duckdb_libpgquery::PG_PRAGMA_TYPE_ASSIGNMENT: if (info.parameters.size() != 1) { - throw ParserException("PRAGMA statement with assignment should contain exactly one parameter"); + throw InternalException("PRAGMA statement with assignment should contain exactly one parameter"); } if (!info.named_parameters.empty()) { - throw ParserException("PRAGMA statement with assignment cannot have named parameters"); + throw InternalException("PRAGMA statement with assignment cannot have named parameters"); + } + // SQLite does not distinguish between: + // "PRAGMA table_info='integers'" + // "PRAGMA table_info('integers')" + // for compatibility, any pragmas that match the SQLite ones are parsed as calls + case_insensitive_set_t sqlite_compat_pragmas {"table_info"}; + if (sqlite_compat_pragmas.find(info.name) != sqlite_compat_pragmas.end()) { + break; } - break; + auto set_statement = make_unique(info.name, info.parameters[0], SetScope::AUTOMATIC); + return move(set_statement); + } case duckdb_libpgquery::PG_PRAGMA_TYPE_CALL: break; default: - throw ParserException("Unknown pragma type"); + throw InternalException("Unknown pragma type"); } - return result; + return move(result); } } // namespace duckdb @@ -134683,7 +146268,10 @@ unique_ptr Transformer::TransformRename(duckdb_libpgquery::PGNod throw NotImplementedException("Schema element not supported yet!"); } D_ASSERT(info); - return make_unique(move(info)); + + auto result = make_unique(); + result->info = move(info); + return result; } } // namespace duckdb @@ -134724,7 +146312,7 @@ namespace duckdb { unique_ptr Transformer::TransformSelectNode(duckdb_libpgquery::PGSelectStmt *stmt) { D_ASSERT(stmt->type == duckdb_libpgquery::T_PGSelectStmt); - StackCheck(); + auto stack_checker = StackCheck(); unique_ptr node; @@ -134780,9 +146368,11 @@ unique_ptr Transformer::TransformSelectNode(duckdb_libpgquery::PGSele // where result->where_clause = TransformExpression(stmt->whereClause); // group by - TransformGroupBy(stmt->groupClause, result->groups); + TransformGroupBy(stmt->groupClause, *result); // having result->having = TransformExpression(stmt->havingClause); + // qualify + result->qualify = TransformExpression(stmt->qualifyClause); // sample result->sample = TransformSampleOptions(stmt->sampleOptions); break; @@ -134837,14 +146427,24 @@ unique_ptr Transformer::TransformSelectNode(duckdb_libpgquery::PGSele node->modifiers.push_back(move(order_modifier)); } if (stmt->limitCount || stmt->limitOffset) { - auto limit_modifier = make_unique(); - if (stmt->limitCount) { - limit_modifier->limit = TransformExpression(stmt->limitCount); - } - if (stmt->limitOffset) { - limit_modifier->offset = TransformExpression(stmt->limitOffset); + if (stmt->limitCount && stmt->limitCount->type == duckdb_libpgquery::T_PGLimitPercent) { + auto limit_percent_modifier = make_unique(); + auto expr_node = reinterpret_cast(stmt->limitCount)->limit_percent; + limit_percent_modifier->limit = TransformExpression(expr_node); + if (stmt->limitOffset) { + limit_percent_modifier->offset = TransformExpression(stmt->limitOffset); + } + node->modifiers.push_back(move(limit_percent_modifier)); + } else { + auto limit_modifier = make_unique(); + if (stmt->limitCount) { + limit_modifier->limit = TransformExpression(stmt->limitCount); + } + if (stmt->limitOffset) { + limit_modifier->offset = TransformExpression(stmt->limitOffset); + } + node->modifiers.push_back(move(limit_modifier)); } - node->modifiers.push_back(move(limit_modifier)); } return node; } @@ -134868,7 +146468,7 @@ SetScope ToSetScope(duckdb_libpgquery::VariableSetScope pg_scope) { case duckdb_libpgquery::VariableSetScope::VAR_SET_SCOPE_GLOBAL: return SetScope::GLOBAL; case duckdb_libpgquery::VariableSetScope::VAR_SET_SCOPE_DEFAULT: - return SetScope::SESSION; + return SetScope::AUTOMATIC; default: throw InternalException("Unexpected pg_scope: %d", pg_scope); } @@ -135100,7 +146700,7 @@ unique_ptr Transformer::TransformFrom(duckdb_libpgquery::PGList *root) cur_root = result.get(); } list_size++; - StackCheck(list_size * DEFAULT_ENTRY_STACK_SIZE); + StackCheck(list_size); } return move(result); } @@ -135251,7 +146851,7 @@ unique_ptr Transformer::TransformRangeFunction(duckdb_libpgquery::PGRa namespace duckdb { unique_ptr Transformer::TransformTableRefNode(duckdb_libpgquery::PGNode *n) { - StackCheck(); + auto stack_checker = StackCheck(); switch (n->type) { case duckdb_libpgquery::T_PGRangeVar: @@ -135296,9 +146896,27 @@ unique_ptr Transformer::TransformTableRefNode(duckdb_libpgquery::PGNod namespace duckdb { +StackChecker::StackChecker(Transformer &transformer_p, idx_t stack_usage_p) + : transformer(transformer_p), stack_usage(stack_usage_p) { + transformer.stack_depth += stack_usage; +} + +StackChecker::~StackChecker() { + transformer.stack_depth -= stack_usage; +} + +StackChecker::StackChecker(StackChecker &&other) noexcept + : transformer(other.transformer), stack_usage(other.stack_usage) { + other.stack_usage = 0; +} + +Transformer::Transformer(Transformer *parent, idx_t max_expression_depth_p) + : parent(parent), max_expression_depth(parent ? parent->max_expression_depth : max_expression_depth_p), + stack_depth(DConstants::INVALID_INDEX) { +} + bool Transformer::TransformParseTree(duckdb_libpgquery::PGList *tree, vector> &statements) { - int stack_check_var; - InitializeStackCheck(&stack_check_var); + InitializeStackCheck(); for (auto entry = tree->head; entry != nullptr; entry = entry->next) { SetParamCount(0); auto stmt = TransformStatement((duckdb_libpgquery::PGNode *)entry->data.ptr_value); @@ -135309,27 +146927,29 @@ bool Transformer::TransformParseTree(duckdb_libpgquery::PGList *tree, vectorroot = stack_check_var; +void Transformer::InitializeStackCheck() { + stack_depth = 0; } -void Transformer::StackCheck(idx_t extra_stack) { - if (!root) { - return; - } - int current_stack_var; - if (¤t_stack_var > root) { - throw InternalException("Transformer::StackCheck variables are incorrectly set up"); +StackChecker Transformer::StackCheck(idx_t extra_stack) { + auto node = this; + while (node->parent) { + node = node->parent; } - idx_t stack_size = root - ¤t_stack_var + extra_stack; - if (stack_size > MAX_STACK_SIZE) { - throw ParserException( - "Stack usage in parsing is too high: the query tree is too deep (stack usage %lld, max stack usage %lld)", - stack_size, MAX_STACK_SIZE); + D_ASSERT(node->stack_depth != DConstants::INVALID_INDEX); + if (node->stack_depth + extra_stack >= max_expression_depth) { + throw ParserException("Max expression depth limit of %lld exceeded", max_expression_depth); } + return StackChecker(*node, extra_stack); } unique_ptr Transformer::TransformStatement(duckdb_libpgquery::PGNode *stmt) { + auto result = TransformStatementInternal(stmt); + result->n_param = ParamCount(); + return result; +} + +unique_ptr Transformer::TransformStatementInternal(duckdb_libpgquery::PGNode *stmt) { switch (stmt->type) { case duckdb_libpgquery::T_PGRawStmt: { auto raw_stmt = (duckdb_libpgquery::PGRawStmt *)stmt; @@ -135402,6 +147022,8 @@ unique_ptr Transformer::TransformStatement(duckdb_libpgquery::PGNo return TransformLoad(stmt); case duckdb_libpgquery::T_PGCreateEnumStmt: return TransformCreateEnum(stmt); + case duckdb_libpgquery::T_PGAlterSeqStmt: + return TransformAlterSequence(stmt); default: throw NotImplementedException(NodetypeToString(stmt->type)); } @@ -135569,6 +147191,34 @@ unordered_set BindContext::GetMatchingBindings(const string &column_name return result; } +unique_ptr BindContext::CreateColumnReference(const string &table_name, const string &column_name) { + string schema_name; + return CreateColumnReference(schema_name, table_name, column_name); +} + +unique_ptr BindContext::CreateColumnReference(const string &schema_name, const string &table_name, + const string &column_name) { + string error_message; + vector names; + 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)); + // because of case insensitivity in the binder we rename the column to the original name + // as it appears in the binding itself + auto binding = GetBinding(table_name, error_message); + if (binding) { + auto column_index = binding->GetBindingIndex(column_name); + if (column_index < binding->names.size() && binding->names[column_index] != column_name) { + result->alias = binding->names[column_index]; + } + } + return move(result); +} + Binding *BindContext::GetCTEBinding(const string &ctename) { auto match = cte_bindings.find(ctename); if (match == cte_bindings.end()) { @@ -135594,12 +147244,12 @@ Binding *BindContext::GetBinding(const string &name, string &out_error) { } BindResult BindContext::BindColumn(ColumnRefExpression &colref, idx_t depth) { - if (colref.table_name.empty()) { - return BindResult(StringUtil::Format("Could not bind alias \"%s\"!", colref.column_name)); + if (!colref.IsQualified()) { + throw InternalException("Could not bind alias \"%s\"!", colref.GetColumnName()); } string error; - auto binding = GetBinding(colref.table_name, error); + auto binding = GetBinding(colref.GetTableName(), error); if (!binding) { return BindResult(error); } @@ -135643,8 +147293,10 @@ bool BindContext::CheckExclusionList(StarExpression &expr, Binding *binding, con } auto entry = expr.replace_list.find(column_name); if (entry != expr.replace_list.end()) { + auto new_entry = entry->second->Copy(); + new_entry->alias = entry->first; excluded_columns.insert(entry->first); - new_select_list.push_back(entry->second->Copy()); + new_select_list.push_back(move(new_entry)); return true; } return false; @@ -135876,7 +147528,7 @@ class BoundSelectNode; struct BoundGroupInformation { expression_map_t map; - unordered_map alias_map; + case_insensitive_map_t alias_map; }; //! The SELECT binder is responsible for binding an expression within the SELECT clause of a SQL statement @@ -135992,6 +147644,8 @@ class BoundSelectNode : public BoundQueryNode { BoundGroupByNode groups; //! HAVING clause unique_ptr having; + //! QUALIFY clause + unique_ptr qualify; //! SAMPLE clause unique_ptr sample_options; @@ -136055,12 +147709,12 @@ static void InvertPercentileFractions(unique_ptr &fractions) { Value value = ExpressionExecutor::EvaluateScalar(*bound.expr); if (value.type().id() == LogicalTypeId::LIST) { vector values; - for (const auto &element_val : value.list_value) { - values.emplace_back(Value(1) - element_val); + for (const auto &element_val : ListValue::GetChildren(value)) { + values.push_back(Value::DOUBLE(1 - element_val.GetValue())); } bound.expr = make_unique(Value::LIST(values)); } else { - bound.expr = make_unique(Value(1) - value); + bound.expr = make_unique(Value::DOUBLE(1 - value.GetValue())); } } @@ -136179,7 +147833,7 @@ BindResult SelectBinder::BindAggregate(FunctionExpression &aggr, AggregateFuncti // bind the aggregate idx_t best_function = Function::BindFunction(func->name, func->functions, types, error); - if (best_function == INVALID_INDEX) { + if (best_function == DConstants::INVALID_INDEX) { throw BinderException(binder.FormatError(aggr, error)); } // found a matching function! @@ -136266,8 +147920,10 @@ BindResult ExpressionBinder::BindExpression(BetweenExpression &expr, idx_t depth lower.expr = PushCollation(context, move(lower.expr), collation, false); upper.expr = PushCollation(context, move(upper.expr), collation, false); } - if (!input.expr->HasSideEffects() && !input.expr->HasParameter()) { - // the expression does not have side effects: create two comparisons + 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)); auto right_compare = make_unique(ExpressionType::COMPARE_LESSTHANOREQUALTO, @@ -136391,57 +148047,241 @@ BindResult ExpressionBinder::BindExpression(CollateExpression &expr, idx_t depth + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/expression_binder/where_binder.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + namespace duckdb { -BindResult ExpressionBinder::BindExpression(ColumnRefExpression &colref, idx_t depth) { - D_ASSERT(!colref.column_name.empty()); - // individual column reference - // resolve to either a base table or a subquery expression - if (colref.table_name.empty()) { - auto using_binding = binder.bind_context.GetUsingBinding(colref.column_name); - if (using_binding) { - // we are referencing a USING column - // check if we can refer to one of the base columns directly - unique_ptr expression; - if (!using_binding->primary_binding.empty()) { - // we can! just assign the table name and re-bind - colref.table_name = using_binding->primary_binding; - return BindExpression(colref, depth); - } else { - // we cannot! we need to bind this as a coalesce between all the relevant columns - auto coalesce = make_unique(ExpressionType::OPERATOR_COALESCE); - for (auto &entry : using_binding->bindings) { - coalesce->children.push_back(make_unique(colref.column_name, entry)); - } - return BindExpression(*coalesce, depth); +class ColumnAliasBinder; + +//! The WHERE binder is responsible for binding an expression within the WHERE clause of a SQL statement +class WhereBinder : public ExpressionBinder { +public: + WhereBinder(Binder &binder, ClientContext &context, ColumnAliasBinder *column_alias_binder = nullptr); + +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); + + ColumnAliasBinder *column_alias_binder; +}; + +} // namespace duckdb + + + + + + + +namespace duckdb { + +unique_ptr ExpressionBinder::QualifyColumnName(const string &column_name, string &error_message) { + auto using_binding = binder.bind_context.GetUsingBinding(column_name); + if (using_binding) { + // we are referencing a USING column + // check if we can refer to one of the base columns directly + unique_ptr expression; + if (!using_binding->primary_binding.empty()) { + // we can! just assign the table name and re-bind + return make_unique(column_name, using_binding->primary_binding); + } else { + // // we cannot! we need to bind this as a coalesce between all the relevant columns + auto coalesce = make_unique(ExpressionType::OPERATOR_COALESCE); + for (auto &entry : using_binding->bindings) { + coalesce->children.push_back(make_unique(column_name, entry)); + } + return move(coalesce); + } + } + // no table name: find a binding that contains this + if (binder.macro_binding != nullptr && binder.macro_binding->HasMatchingBinding(column_name)) { + // priority to macro parameter bindings TODO: throw a warning when this name conflicts + D_ASSERT(!binder.macro_binding->alias.empty()); + return make_unique(column_name, binder.macro_binding->alias); + } else { + string table_name = binder.bind_context.GetMatchingBinding(column_name); + if (table_name.empty()) { + auto similar_bindings = binder.bind_context.GetSimilarBindings(column_name); + string candidate_str = StringUtil::CandidatesMessage(similar_bindings, "Candidate bindings"); + error_message = + StringUtil::Format("Referenced column \"%s\" not found in FROM clause!%s", column_name, candidate_str); + return nullptr; + } + return binder.bind_context.CreateColumnReference(table_name, column_name); + } +} + +void ExpressionBinder::QualifyColumnNames(unique_ptr &expr) { + switch (expr->type) { + case ExpressionType::COLUMN_REF: { + auto &colref = (ColumnRefExpression &)*expr; + string error_message; + auto new_expr = QualifyColumnName(colref, error_message); + if (new_expr) { + if (!expr->alias.empty()) { + new_expr->alias = expr->alias; + } + expr = move(new_expr); + } + break; + } + case ExpressionType::POSITIONAL_REFERENCE: { + auto &ref = (PositionalReferenceExpression &)*expr; + if (ref.alias.empty()) { + string table_name, column_name; + auto error = binder.bind_context.BindColumn(ref, table_name, column_name); + if (error.empty()) { + ref.alias = column_name; + } + } + break; + } + default: + break; + } + ParsedExpressionIterator::EnumerateChildren( + *expr, [&](unique_ptr &child) { QualifyColumnNames(child); }); +} + +void ExpressionBinder::QualifyColumnNames(Binder &binder, unique_ptr &expr) { + WhereBinder where_binder(binder, binder.context); + where_binder.QualifyColumnNames(expr); +} + +unique_ptr ExpressionBinder::CreateStructExtract(unique_ptr base, + string field_name) { + vector> children; + children.push_back(move(base)); + children.push_back(make_unique_base(Value(move(field_name)))); + auto extract_fun = make_unique("struct_extract", move(children)); + return move(extract_fun); +} + +unique_ptr ExpressionBinder::QualifyColumnName(ColumnRefExpression &colref, string &error_message) { + idx_t column_parts = colref.column_names.size(); + // column names can have an arbitrary amount of dots + // here is how the resolution works: + if (column_parts == 1) { + // no dots (i.e. "part1") + // -> part1 refers to a column + // check if we can qualify the column name with the table name + return QualifyColumnName(colref.GetColumnName(), error_message); + } else if (column_parts == 2) { + // one dot (i.e. "part1.part2") + // EITHER: + // -> part1 is a table, part2 is a column + // -> part1 is a column, part2 is a property of that column (i.e. struct_extract) + + // first check if part1 is a table + if (binder.HasMatchingBinding(colref.column_names[0], colref.column_names[1], error_message)) { + // it is! return the colref directly + return binder.bind_context.CreateColumnReference(colref.column_names[0], colref.column_names[1]); + } else { + // otherwise check if we can turn this into a struct extract + auto new_colref = make_unique(colref.column_names[0]); + string other_error; + auto qualified_colref = QualifyColumnName(colref.column_names[0], other_error); + if (!qualified_colref) { + // we could not! bail + return nullptr; } + // we could: create a struct extract + return CreateStructExtract(move(qualified_colref), colref.column_names[1]); } - // no table name: find a binding that contains this - if (binder.macro_binding != nullptr && binder.macro_binding->HasMatchingBinding(colref.column_name)) { - // priority to macro parameter bindings TODO: throw a warning when this name conflicts - colref.table_name = binder.macro_binding->alias; + } else { + // two or more dots (i.e. "part1.part2.part3.part4...") + // -> 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 + + 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" + // 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]); + struct_extract_start = 3; + } else if (binder.HasMatchingBinding(colref.column_names[0], colref.column_names[1], error_message)) { + // part1 is a table + // the column reference is "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]); + struct_extract_start = 2; } else { - colref.table_name = binder.bind_context.GetMatchingBinding(colref.column_name); + // part1 could be a column + 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! add the struct extract calls + struct_extract_start = 1; } - if (colref.table_name.empty()) { - auto similar_bindings = binder.bind_context.GetSimilarBindings(colref.column_name); - string candidate_str = StringUtil::CandidatesMessage(similar_bindings, "Candidate bindings"); - return BindResult(binder.FormatError(colref.query_location, - "Referenced column \"%s\" not found in FROM clause!%s", - colref.column_name.c_str(), candidate_str)); + for (idx_t i = struct_extract_start; i < colref.column_names.size(); i++) { + result_expr = CreateStructExtract(move(result_expr), colref.column_names[i]); } + return result_expr; + } +} + +BindResult ExpressionBinder::BindExpression(ColumnRefExpression &colref_p, idx_t depth) { + if (binder.GetBindingMode() == BindingMode::EXTRACT_NAMES) { + return BindResult(make_unique(Value(LogicalType::SQLNULL))); + } + string error_message; + auto expr = QualifyColumnName(colref_p, error_message); + if (!expr) { + return BindResult(binder.FormatError(colref_p, error_message)); } + if (expr->type != ExpressionType::COLUMN_REF) { + return BindExpression(&expr, depth); + } + auto &colref = (ColumnRefExpression &)*expr; + D_ASSERT(colref.column_names.size() == 2 || colref.column_names.size() == 3); + auto &table_name = colref.column_names.size() == 3 ? colref.column_names[1] : colref.column_names[0]; + // individual column reference + // resolve to either a base table or a subquery expression // if it was a macro parameter, let macro_binding bind it to the argument - BindResult result = binder.macro_binding != nullptr && colref.table_name == binder.macro_binding->alias - ? binder.macro_binding->Bind(colref, depth) - : binder.bind_context.BindColumn(colref, depth); + BindResult result; + if (binder.macro_binding && table_name == binder.macro_binding->alias) { + result = binder.macro_binding->Bind(colref, depth); + } else { + result = binder.bind_context.BindColumn(colref, depth); + } if (!result.HasError()) { BoundColumnReferenceInfo ref; - ref.name = colref.column_name; + ref.name = colref.column_names.back(); ref.query_location = colref.query_location; bound_columns.push_back(move(ref)); } else { - result.error = binder.FormatError(colref, result.error); + result.error = binder.FormatError(colref_p, result.error); } return result; } @@ -136474,6 +148314,7 @@ unique_ptr ExpressionBinder::PushCollation(ClientContext &context, u } else { collation = collation_p; } + collation = StringUtil::Lower(collation); // bind the collation if (collation.empty() || collation == "binary" || collation == "c" || collation == "posix") { // binary collation: just skip @@ -136676,6 +148517,10 @@ BindResult ExpressionBinder::BindFunction(FunctionExpression &function, ScalarFu if (!error.empty()) { return BindResult(error); } + if (binder.GetBindingMode() == BindingMode::EXTRACT_NAMES) { + return BindResult(make_unique(Value(LogicalType::SQLNULL))); + } + // all children bound successfully // extract the children and types vector> children; @@ -136686,7 +148531,7 @@ BindResult ExpressionBinder::BindFunction(FunctionExpression &function, ScalarFu unique_ptr result = ScalarFunction::BindScalarFunction(context, *func, move(children), error, function.is_operator); if (!result) { - throw BinderException(binder.FormatError(function, error)); + return BindResult(binder.FormatError(function, error)); } return BindResult(move(result)); } @@ -136739,11 +148584,6 @@ BindResult ExpressionBinder::BindExpression(LambdaExpression &expr, idx_t depth) - - - - - namespace duckdb { void ExpressionBinder::ReplaceMacroParametersRecursive(unique_ptr &expr) { @@ -136751,7 +148591,14 @@ void ExpressionBinder::ReplaceMacroParametersRecursive(unique_ptrHasMatchingBinding(colref.column_name)) { + bool bind_macro_parameter = false; + if (colref.IsQualified()) { + bind_macro_parameter = colref.GetTableName() == MacroBinding::MACRO_NAME; + } else { + bind_macro_parameter = macro_binding->HasMatchingBinding(colref.GetColumnName()); + } + if (bind_macro_parameter) { + D_ASSERT(macro_binding->HasMatchingBinding(colref.GetColumnName())); expr = macro_binding->ParamToArg(colref); } return; @@ -136759,7 +148606,8 @@ void ExpressionBinder::ReplaceMacroParametersRecursive(unique_ptrnode); + ParsedExpressionIterator::EnumerateQueryNodeChildren( + *sq->node, [&](unique_ptr &child) { ReplaceMacroParametersRecursive(child); }); break; } default: // fall through @@ -136770,89 +148618,6 @@ void ExpressionBinder::ReplaceMacroParametersRecursive(unique_ptr &child) { ReplaceMacroParametersRecursive(child); }); } -void ExpressionBinder::ReplaceMacroParametersRecursive(ParsedExpression &expr, TableRef &ref) { - switch (ref.type) { - case TableReferenceType::CROSS_PRODUCT: { - auto &cp_ref = (CrossProductRef &)ref; - ReplaceMacroParametersRecursive(expr, *cp_ref.left); - ReplaceMacroParametersRecursive(expr, *cp_ref.right); - break; - } - case TableReferenceType::EXPRESSION_LIST: { - auto &el_ref = (ExpressionListRef &)ref; - for (idx_t i = 0; i < el_ref.values.size(); i++) { - for (idx_t j = 0; j < el_ref.values[i].size(); j++) { - ReplaceMacroParametersRecursive(el_ref.values[i][j]); - } - } - break; - } - case TableReferenceType::JOIN: { - auto &j_ref = (JoinRef &)ref; - ReplaceMacroParametersRecursive(expr, *j_ref.left); - ReplaceMacroParametersRecursive(expr, *j_ref.right); - ReplaceMacroParametersRecursive(j_ref.condition); - break; - } - case TableReferenceType::SUBQUERY: { - auto &sq_ref = (SubqueryRef &)ref; - ReplaceMacroParametersRecursive(expr, *sq_ref.subquery->node); - break; - } - case TableReferenceType::TABLE_FUNCTION: { - auto &tf_ref = (TableFunctionRef &)ref; - ReplaceMacroParametersRecursive(tf_ref.function); - break; - } - case TableReferenceType::BASE_TABLE: - case TableReferenceType::EMPTY: - // these TableRefs do not need to be unfolded - break; - default: - throw NotImplementedException("TableRef type not implemented for macro's!"); - } -} - -void ExpressionBinder::ReplaceMacroParametersRecursive(ParsedExpression &expr, QueryNode &node) { - switch (node.type) { - case QueryNodeType::RECURSIVE_CTE_NODE: { - auto &rcte_node = (RecursiveCTENode &)node; - ReplaceMacroParametersRecursive(expr, *rcte_node.left); - ReplaceMacroParametersRecursive(expr, *rcte_node.right); - break; - } - case QueryNodeType::SELECT_NODE: { - auto &sel_node = (SelectNode &)node; - for (idx_t i = 0; i < sel_node.select_list.size(); i++) { - ReplaceMacroParametersRecursive(sel_node.select_list[i]); - } - for (idx_t i = 0; i < sel_node.groups.group_expressions.size(); i++) { - ReplaceMacroParametersRecursive(sel_node.groups.group_expressions[i]); - } - if (sel_node.where_clause != nullptr) { - ReplaceMacroParametersRecursive(sel_node.where_clause); - } - if (sel_node.having != nullptr) { - ReplaceMacroParametersRecursive(sel_node.having); - } - - ReplaceMacroParametersRecursive(expr, *sel_node.from_table.get()); - break; - } - case QueryNodeType::SET_OPERATION_NODE: { - auto &setop_node = (SetOperationNode &)node; - ReplaceMacroParametersRecursive(expr, *setop_node.left); - ReplaceMacroParametersRecursive(expr, *setop_node.right); - break; - } - default: - throw NotImplementedException("QueryNode type not implemented for macro's!"); - } - for (auto &kv : node.cte_map) { - ReplaceMacroParametersRecursive(expr, *kv.second->query->node); - } -} - BindResult ExpressionBinder::BindMacro(FunctionExpression &function, MacroCatalogEntry *macro_func, idx_t depth, unique_ptr *expr) { auto ¯o_def = *macro_func->function; @@ -136869,13 +148634,13 @@ BindResult ExpressionBinder::BindMacro(FunctionExpression &function, MacroCatalo vector names; // positional parameters for (idx_t i = 0; i < macro_def.parameters.size(); i++) { - types.push_back(LogicalType::SQLNULL); + types.emplace_back(LogicalType::SQLNULL); auto ¶m = (ColumnRefExpression &)*macro_def.parameters[i]; - names.push_back(param.column_name); + names.push_back(param.GetColumnName()); } // default parameters for (auto it = macro_def.default_parameters.begin(); it != macro_def.default_parameters.end(); it++) { - types.push_back(LogicalType::SQLNULL); + types.emplace_back(LogicalType::SQLNULL); names.push_back(it->first); // now push the defaults into the positionals positionals.push_back(move(defaults[it->first])); @@ -137069,11 +148834,14 @@ class BoundSubqueryNode : public QueryNode { unique_ptr subquery; const vector> &GetSelectList() const override { - throw Exception("Cannot get select list of bound subquery node"); + throw InternalException("Cannot get select list of bound subquery node"); } - unique_ptr Copy() override { - throw Exception("Cannot copy bound subquery node"); + unique_ptr Copy() const override { + throw InternalException("Cannot copy bound subquery node"); + } + void Serialize(FieldWriter &writer) const override { + throw InternalException("Cannot copy bound subquery node"); } }; @@ -137393,7 +149161,7 @@ BindResult SelectBinder::BindWindow(WindowExpression &window, idx_t depth) { // bind the aggregate string error; auto best_function = Function::BindFunction(func->name, func->functions, types, error); - if (best_function == INVALID_INDEX) { + if (best_function == DConstants::INVALID_INDEX) { throw BinderException(binder.FormatError(window, error)); } // found a matching function! bind it as an aggregate @@ -137413,6 +149181,7 @@ BindResult SelectBinder::BindWindow(WindowExpression &window, idx_t depth) { for (auto &child : window.partitions) { result->partitions.push_back(GetExpression(child)); } + result->ignore_nulls = window.ignore_nulls; // Convert RANGE boundary expressions to ORDER +/- expressions. // Note that PRECEEDING and FOLLOWING refer to the sequential order in the frame, @@ -137420,7 +149189,7 @@ BindResult SelectBinder::BindWindow(WindowExpression &window, idx_t depth) { // for ORDER BY DESC. auto &config = DBConfig::GetConfig(context); auto range_sense = OrderType::INVALID; - auto start_type = LogicalType::BIGINT; + LogicalType start_type = LogicalType::BIGINT; if (window.start == WindowBoundary::EXPR_PRECEDING_RANGE) { D_ASSERT(window.orders.size() == 1); range_sense = ResolveOrderType(config, window.orders[0].type); @@ -137433,7 +149202,7 @@ BindResult SelectBinder::BindWindow(WindowExpression &window, idx_t depth) { start_type = BindRangeExpression(context, name, window.start_expr, window.orders[0].expression); } - auto end_type = LogicalType::BIGINT; + LogicalType end_type = LogicalType::BIGINT; if (window.end == WindowBoundary::EXPR_PRECEDING_RANGE) { D_ASSERT(window.orders.size() == 1); range_sense = ResolveOrderType(config, window.orders[0].type); @@ -137627,14 +149396,14 @@ class ColumnRefExpression; //! A helper binder for WhereBinder and HavingBinder which support alias as a columnref. class ColumnAliasBinder { public: - ColumnAliasBinder(BoundSelectNode &node, const unordered_map &alias_map); + ColumnAliasBinder(BoundSelectNode &node, const case_insensitive_map_t &alias_map); BindResult BindAlias(ExpressionBinder &enclosing_binder, ColumnRefExpression &expr, idx_t depth, bool root_expression); private: BoundSelectNode &node; - const unordered_map &alias_map; + const case_insensitive_map_t &alias_map; bool in_alias; }; @@ -137683,7 +149452,6 @@ class ConstantBinder : public ExpressionBinder { - namespace duckdb { class ConstantExpression; class ColumnRefExpression; @@ -137692,7 +149460,7 @@ class ColumnRefExpression; class GroupBinder : public ExpressionBinder { public: GroupBinder(Binder &binder, ClientContext &context, SelectNode &node, idx_t group_index, - unordered_map &alias_map, unordered_map &group_alias_map); + case_insensitive_map_t &alias_map, case_insensitive_map_t &group_alias_map); //! The unbound root expression unique_ptr unbound_expression; @@ -137709,8 +149477,8 @@ class GroupBinder : public ExpressionBinder { BindResult BindConstant(ConstantExpression &expr); SelectNode &node; - unordered_map &alias_map; - unordered_map &group_alias_map; + case_insensitive_map_t &alias_map; + case_insensitive_map_t &group_alias_map; unordered_set used_aliases; idx_t group_index; @@ -137737,7 +149505,7 @@ namespace duckdb { class HavingBinder : public SelectBinder { public: HavingBinder(Binder &binder, ClientContext &context, BoundSelectNode &node, BoundGroupInformation &info, - unordered_map &alias_map); + case_insensitive_map_t &alias_map); protected: BindResult BindExpression(unique_ptr *expr_ptr, idx_t depth, @@ -137754,7 +149522,7 @@ class HavingBinder : public SelectBinder { //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/planner/expression_binder/order_binder.hpp +// duckdb/planner/expression_binder/qualify_binder.hpp // // //===----------------------------------------------------------------------===// @@ -137764,41 +149532,30 @@ class HavingBinder : public SelectBinder { - - namespace duckdb { -class Binder; -class Expression; -class SelectNode; -//! The ORDER binder is responsible for binding an expression within the ORDER BY clause of a SQL statement -class OrderBinder { +//! The QUALIFY binder is responsible for binding an expression within the QUALIFY clause of a SQL statement +class QualifyBinder : public SelectBinder { public: - OrderBinder(vector binders, idx_t projection_index, unordered_map &alias_map, - expression_map_t &projection_map, idx_t max_count); - OrderBinder(vector binders, idx_t projection_index, SelectNode &node, - unordered_map &alias_map, expression_map_t &projection_map); + QualifyBinder(Binder &binder, ClientContext &context, BoundSelectNode &node, BoundGroupInformation &info, + case_insensitive_map_t &alias_map); - unique_ptr Bind(unique_ptr expr); +protected: + BindResult BindExpression(unique_ptr *expr_ptr, idx_t depth, + bool root_expression = false) override; private: - unique_ptr CreateProjectionReference(ParsedExpression &expr, idx_t index); + BindResult BindColumnRef(unique_ptr *expr_ptr, idx_t depth, bool root_expression); - vector binders; - idx_t projection_index; - idx_t max_count; - vector> *extra_list; - unordered_map &alias_map; - expression_map_t &projection_map; + ColumnAliasBinder column_alias_binder; }; } // namespace duckdb - //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/planner/expression_binder/where_binder.hpp +// duckdb/planner/expression_binder/order_binder.hpp // // //===----------------------------------------------------------------------===// @@ -137807,25 +149564,39 @@ class OrderBinder { -namespace duckdb { -class ColumnAliasBinder; -//! The WHERE binder is responsible for binding an expression within the WHERE clause of a SQL statement -class WhereBinder : public ExpressionBinder { + +namespace duckdb { +class Binder; +class Expression; +class SelectNode; + +//! The ORDER binder is responsible for binding an expression within the ORDER BY clause of a SQL statement +class OrderBinder { public: - WhereBinder(Binder &binder, ClientContext &context, ColumnAliasBinder *column_alias_binder = nullptr); + OrderBinder(vector binders, idx_t projection_index, case_insensitive_map_t &alias_map, + expression_map_t &projection_map, idx_t max_count); + OrderBinder(vector binders, idx_t projection_index, SelectNode &node, + case_insensitive_map_t &alias_map, expression_map_t &projection_map); -protected: - BindResult BindExpression(unique_ptr *expr_ptr, idx_t depth, - bool root_expression = false) override; +public: + unique_ptr Bind(unique_ptr expr); - string UnsupportedAggregateMessage() override; + idx_t MaxCount() { + return max_count; + } private: - BindResult BindColumnRef(unique_ptr *expr_ptr, idx_t depth, bool root_expression); + unique_ptr CreateProjectionReference(ParsedExpression &expr, idx_t index); - ColumnAliasBinder *column_alias_binder; +private: + vector binders; + idx_t projection_index; + idx_t max_count; + vector> *extra_list; + case_insensitive_map_t &alias_map; + expression_map_t &projection_map; }; } // namespace duckdb @@ -137833,6 +149604,8 @@ class WhereBinder : public ExpressionBinder { + + namespace duckdb { unique_ptr Binder::BindOrderExpression(OrderBinder &order_binder, unique_ptr expr) { @@ -137848,15 +149621,14 @@ unique_ptr Binder::BindOrderExpression(OrderBinder &order_binder, un } unique_ptr Binder::BindDelimiter(ClientContext &context, unique_ptr delimiter, - int64_t &delimiter_value) { + const LogicalType &type, Value &delimiter_value) { auto new_binder = Binder::CreateBinder(context, this, true); ExpressionBinder expr_binder(*new_binder, context); - expr_binder.target_type = LogicalType::UBIGINT; + expr_binder.target_type = type; auto expr = expr_binder.Bind(delimiter); if (expr->IsFoldable()) { //! this is a constant - Value value = ExpressionExecutor::EvaluateScalar(*expr).CastAs(LogicalType::BIGINT); - delimiter_value = value.GetValue(); + delimiter_value = ExpressionExecutor::EvaluateScalar(*expr).CastAs(type); return nullptr; } return expr; @@ -137865,10 +149637,40 @@ unique_ptr Binder::BindDelimiter(ClientContext &context, unique_ptr< unique_ptr Binder::BindLimit(LimitModifier &limit_mod) { auto result = make_unique(); if (limit_mod.limit) { - result->limit = BindDelimiter(context, move(limit_mod.limit), result->limit_val); + Value val; + result->limit = BindDelimiter(context, move(limit_mod.limit), LogicalType::BIGINT, val); + if (!result->limit) { + result->limit_val = val.GetValue(); + } + } + if (limit_mod.offset) { + Value val; + result->offset = BindDelimiter(context, move(limit_mod.offset), LogicalType::BIGINT, val); + if (!result->offset) { + result->offset_val = val.GetValue(); + } + } + return move(result); +} + +unique_ptr Binder::BindLimitPercent(LimitPercentModifier &limit_mod) { + auto result = make_unique(); + if (limit_mod.limit) { + Value val; + result->limit = BindDelimiter(context, move(limit_mod.limit), LogicalType::DOUBLE, val); + if (!result->limit) { + result->limit_percent = val.GetValue(); + if (result->limit_percent < 0.0) { + throw Exception("Limit percentage can't be negative value"); + } + } } if (limit_mod.offset) { - result->offset = BindDelimiter(context, move(limit_mod.offset), result->offset_val); + Value val; + result->offset = BindDelimiter(context, move(limit_mod.offset), LogicalType::BIGINT, val); + if (!result->offset) { + result->offset_val = val.GetValue(); + } } return move(result); } @@ -137880,6 +149682,11 @@ void Binder::BindModifiers(OrderBinder &order_binder, QueryNode &statement, Boun case ResultModifierType::DISTINCT_MODIFIER: { auto &distinct = (DistinctModifier &)*mod; auto bound_distinct = make_unique(); + if (distinct.distinct_on_targets.empty()) { + for (idx_t i = 0; i < result.names.size(); i++) { + distinct.distinct_on_targets.push_back(make_unique(Value::INTEGER(1 + i))); + } + } for (auto &distinct_on_target : distinct.distinct_on_targets) { auto expr = BindOrderExpression(order_binder, move(distinct_on_target)); if (!expr) { @@ -137894,6 +149701,21 @@ void Binder::BindModifiers(OrderBinder &order_binder, QueryNode &statement, Boun auto &order = (OrderModifier &)*mod; auto bound_order = make_unique(); auto &config = DBConfig::GetConfig(context); + D_ASSERT(!order.orders.empty()); + if (order.orders[0].expression->type == ExpressionType::STAR) { + // ORDER BY ALL + // replace the order list with the maximum order by count + D_ASSERT(order.orders.size() == 1); + auto order_type = order.orders[0].type; + auto null_order = order.orders[0].null_order; + + vector new_orders; + for (idx_t i = 0; i < order_binder.MaxCount(); i++) { + new_orders.emplace_back(order_type, null_order, + make_unique(Value::INTEGER(i + 1))); + } + order.orders = move(new_orders); + } for (auto &order_node : order.orders) { auto order_expression = BindOrderExpression(order_binder, move(order_node.expression)); if (!order_expression) { @@ -137912,6 +149734,9 @@ void Binder::BindModifiers(OrderBinder &order_binder, QueryNode &statement, Boun case ResultModifierType::LIMIT_MODIFIER: bound_modifier = BindLimit((LimitModifier &)*mod); break; + case ResultModifierType::LIMIT_PERCENT_MODIFIER: + bound_modifier = BindLimitPercent((LimitPercentModifier &)*mod); + break; default: throw Exception("Unsupported result modifier"); } @@ -137937,7 +149762,7 @@ void Binder::BindModifierTypes(BoundQueryNode &result, const vector for (auto &expr : distinct.target_distincts) { D_ASSERT(expr->type == ExpressionType::BOUND_COLUMN_REF); auto &bound_colref = (BoundColumnRefExpression &)*expr; - if (bound_colref.binding.column_index == INVALID_INDEX) { + if (bound_colref.binding.column_index == DConstants::INVALID_INDEX) { throw BinderException("Ambiguous name in DISTINCT ON!"); } D_ASSERT(bound_colref.binding.column_index < sql_types.size()); @@ -137960,7 +149785,7 @@ void Binder::BindModifierTypes(BoundQueryNode &result, const vector auto &expr = order_node.expression; D_ASSERT(expr->type == ExpressionType::BOUND_COLUMN_REF); auto &bound_colref = (BoundColumnRefExpression &)*expr; - if (bound_colref.binding.column_index == INVALID_INDEX) { + if (bound_colref.binding.column_index == DConstants::INVALID_INDEX) { throw BinderException("Ambiguous name in ORDER BY!"); } D_ASSERT(bound_colref.binding.column_index < sql_types.size()); @@ -138014,12 +149839,12 @@ unique_ptr Binder::BindNode(SelectNode &statement) { statement.select_list = move(new_select_list); // create a mapping of (alias -> index) and a mapping of (Expression -> index) for the SELECT list - unordered_map alias_map; + case_insensitive_map_t alias_map; expression_map_t projection_map; for (idx_t i = 0; i < statement.select_list.size(); i++) { auto &expr = statement.select_list[i]; result->names.push_back(expr->GetName()); - ExpressionBinder::BindTableNames(*this, *expr); + ExpressionBinder::QualifyColumnNames(*this, expr); if (!expr->alias.empty()) { alias_map[expr->alias] = i; result->names[i] = expr->alias; @@ -138073,7 +149898,7 @@ unique_ptr Binder::BindNode(SelectNode &statement) { // 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); - ExpressionBinder::BindTableNames(*this, *unbound_groups[i]); + ExpressionBinder::QualifyColumnNames(*this, unbound_groups[i]); info.map[unbound_groups[i].get()] = i; } } @@ -138082,10 +149907,17 @@ unique_ptr Binder::BindNode(SelectNode &statement) { // bind the HAVING clause, if any if (statement.having) { HavingBinder having_binder(*this, context, *result, info, alias_map); - ExpressionBinder::BindTableNames(*this, *statement.having, &alias_map); + ExpressionBinder::QualifyColumnNames(*this, statement.having); result->having = having_binder.Bind(statement.having); } + // bind the QUALIFY clause, if any + if (statement.qualify) { + QualifyBinder qualify_binder(*this, context, *result, info, alias_map); + ExpressionBinder::QualifyColumnNames(*this, statement.qualify); + result->qualify = qualify_binder.Bind(statement.qualify); + } + // after that, we bind to the SELECT list SelectBinder select_binder(*this, context, *result, info); vector internal_sql_types; @@ -138133,6 +149965,12 @@ unique_ptr Binder::BindNode(SelectNode &statement) { } } + // QUALIFY clause requires at least one window function to be specified in at least one of the SELECT column list or + // the filter predicate of the QUALIFY clause + if (statement.qualify && result->windows.empty()) { + throw BinderException("at least one window function must appear in the SELECT column or QUALIFY clause"); + } + // 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); @@ -138195,7 +150033,7 @@ class BoundSetOperationNode : public BoundQueryNode { namespace duckdb { -static void GatherAliases(BoundQueryNode &node, unordered_map &aliases, +static void GatherAliases(BoundQueryNode &node, case_insensitive_map_t &aliases, expression_map_t &expressions) { if (node.type == QueryNodeType::SET_OPERATION_NODE) { // setop, recurse @@ -138219,7 +150057,7 @@ static void GatherAliases(BoundQueryNode &node, unordered_map &al // there is a conflict // we place "-1" in the aliases map at this location // "-1" signifies that there is an ambiguous reference - aliases[name] = INVALID_INDEX; + aliases[name] = DConstants::INVALID_INDEX; } } else { // the alias is not in there yet, just assign it @@ -138231,7 +150069,7 @@ static void GatherAliases(BoundQueryNode &node, unordered_map &al // the node is in there // repeat the same as with the alias: if there is an ambiguity we insert "-1" if (expr_entry->second != i) { - expressions[expr.get()] = INVALID_INDEX; + expressions[expr.get()] = DConstants::INVALID_INDEX; } } else { // not in there yet, just place it in there @@ -138265,7 +150103,7 @@ unique_ptr Binder::BindNode(SetOperationNode &statement) { // we recursively visit the children of this node to extract aliases and expressions that can be referenced in // the ORDER BY - unordered_map alias_map; + case_insensitive_map_t alias_map; expression_map_t expression_map; GatherAliases(*result, alias_map, expression_map); @@ -138310,6 +150148,7 @@ unique_ptr Binder::BindNode(SetOperationNode &statement) { + namespace duckdb { unique_ptr Binder::VisitQueryNode(BoundQueryNode &node, unique_ptr root) { @@ -138338,6 +150177,14 @@ unique_ptr Binder::VisitQueryNode(BoundQueryNode &node, unique_ root = 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); + break; + } default: throw BinderException("Unimplemented modifier type!"); } @@ -138372,7 +150219,8 @@ unique_ptr Binder::CreatePlan(BoundRecursiveCTENode &node) { left_node = CastLogicalOperatorToTypes(node.left->types, node.types, move(left_node)); right_node = CastLogicalOperatorToTypes(node.right->types, node.types, move(right_node)); - if (node.right_binder->bind_context.cte_references[node.ctename] == nullptr) { + 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)); @@ -138393,6 +150241,7 @@ unique_ptr Binder::CreatePlan(BoundRecursiveCTENode &node) { + namespace duckdb { unique_ptr Binder::PlanFilter(unique_ptr condition, unique_ptr root) { @@ -138465,6 +150314,14 @@ unique_ptr Binder::CreatePlan(BoundSelectNode &statement) { root = move(win); } + if (statement.qualify) { + PlanSubqueries(&statement.qualify, &root); + auto qualify = make_unique(move(statement.qualify)); + + qualify->AddChild(move(root)); + root = move(qualify); + } + if (!statement.unnests.empty()) { auto unnest = make_unique(statement.unnest_index); unnest->expressions = move(statement.unnests); @@ -138483,15 +150340,25 @@ unique_ptr Binder::CreatePlan(BoundSelectNode &statement) { for (size_t i = 0; i < statement.modifiers.size(); i++) { auto &modifier = statement.modifiers[i]; - if (modifier->type != ResultModifierType::LIMIT_MODIFIER) { - continue; - } - auto &limit_modifier = (BoundLimitModifier &)*modifier; - if (limit_modifier.limit || limit_modifier.offset) { - PlanSubqueries(&limit_modifier.limit, &root); - PlanSubqueries(&limit_modifier.offset, &root); - auto limit = make_unique(limit_modifier.limit_val, limit_modifier.offset_val, - move(limit_modifier.limit), move(limit_modifier.offset)); + unique_ptr limit = nullptr; + if (modifier->type == ResultModifierType::LIMIT_MODIFIER) { + auto &limit_modifier = (BoundLimitModifier &)*modifier; + if (limit_modifier.limit || limit_modifier.offset) { + PlanSubqueries(&limit_modifier.limit, &root); + PlanSubqueries(&limit_modifier.offset, &root); + limit = make_unique(limit_modifier.limit_val, limit_modifier.offset_val, + move(limit_modifier.limit), move(limit_modifier.offset)); + } + } else if (modifier->type == ResultModifierType::LIMIT_PERCENT_MODIFIER) { + auto &limit_modifier = (BoundLimitPercentModifier &)*modifier; + if (limit_modifier.limit || limit_modifier.offset) { + PlanSubqueries(&limit_modifier.limit, &root); + PlanSubqueries(&limit_modifier.offset, &root); + limit = make_unique(limit_modifier.limit_percent, limit_modifier.offset_val, + move(limit_modifier.limit), move(limit_modifier.offset)); + } + } + if (limit) { limit->AddChild(move(root)); root = move(limit); // Delete from modifiers @@ -139088,7 +150955,7 @@ BoundStatement Binder::BindCopyTo(CopyStatement &stmt) { // COPY TO a file auto &config = DBConfig::GetConfig(context); if (!config.enable_external_access) { - throw Exception("COPY TO is disabled by configuration"); + throw PermissionException("COPY TO is disabled by configuration"); } BoundStatement result; result.types = {LogicalType::BIGINT}; @@ -139118,7 +150985,7 @@ BoundStatement Binder::BindCopyTo(CopyStatement &stmt) { BoundStatement Binder::BindCopyFrom(CopyStatement &stmt) { auto &config = DBConfig::GetConfig(context); if (!config.enable_external_access) { - throw Exception("COPY FROM is disabled by configuration"); + throw PermissionException("COPY FROM is disabled by configuration"); } BoundStatement result; result.types = {LogicalType::BIGINT}; @@ -139150,7 +151017,7 @@ BoundStatement Binder::BindCopyFrom(CopyStatement &stmt) { if (!bound_insert.column_index_map.empty()) { expected_names.resize(bound_insert.expected_types.size()); for (idx_t i = 0; i < table->columns.size(); i++) { - if (bound_insert.column_index_map[i] != INVALID_INDEX) { + if (bound_insert.column_index_map[i] != DConstants::INVALID_INDEX) { expected_names[bound_insert.column_index_map[i]] = table->columns[i].name; } } @@ -139371,11 +151238,11 @@ SchemaCatalogEntry *Binder::BindCreateFunctionInfo(CreateInfo &info) { // positional parameters for (idx_t i = 0; i < base.function->parameters.size(); i++) { auto param = (ColumnRefExpression &)*base.function->parameters[i]; - if (!param.table_name.empty()) { - throw BinderException("Invalid parameter name '%s'", param.ToString()); + if (param.IsQualified()) { + throw BinderException("Invalid parameter name '%s': must be unqualified", param.ToString()); } - dummy_types.push_back(LogicalType::SQLNULL); - dummy_names.push_back(param.column_name); + dummy_types.emplace_back(LogicalType::SQLNULL); + dummy_names.push_back(param.GetColumnName()); } // default parameters for (auto it = base.function->default_parameters.begin(); it != base.function->default_parameters.end(); it++) { @@ -139385,6 +151252,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, base.function->expression); // create a copy of the expression because we do not want to alter the original auto expression = base.function->expression->Copy(); @@ -139426,7 +151294,7 @@ void Binder::BindLogicalType(ClientContext &context, LogicalType &type, const st if (!user_type_catalog) { throw NotImplementedException("DataType %s not supported yet...\n", user_type_name); } - type = *user_type_catalog->user_type; + type = user_type_catalog->user_type; EnumType::SetCatalog(type, user_type_catalog); } else if (type.id() == LogicalTypeId::ENUM) { auto &enum_type_name = EnumType::GetTypeName(type); @@ -139632,7 +151500,7 @@ static void BindConstraints(Binder &binder, BoundCreateTableInfo &info) { // have to resolve columns of the unique constraint vector keys; unordered_set key_set; - if (unique.index != INVALID_INDEX) { + if (unique.index != DConstants::INVALID_INDEX) { D_ASSERT(unique.index < base.columns.size()); // unique constraint is given by single index unique.columns.push_back(base.columns[unique.index].name); @@ -139818,8 +151686,8 @@ BoundStatement Binder::Bind(DeleteStatement &stmt) { del->AddChild(move(root)); // set up the delete expression - del->expressions.push_back( - make_unique(LOGICAL_ROW_TYPE, ColumnBinding(get.table_index, get.column_ids.size()))); + del->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); result.plan = move(del); @@ -139894,7 +151762,7 @@ 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)); + auto explain = make_unique(move(plan.plan), stmt.explain_type); explain->logical_plan_unopt = logical_plan_unopt; result.plan = move(explain); @@ -139949,7 +151817,7 @@ BoundStatement Binder::Bind(ExportStatement &stmt) { // COPY TO a file auto &config = DBConfig::GetConfig(context); if (!config.enable_external_access) { - throw Exception("COPY TO is disabled by configuration"); + throw PermissionException("COPY TO is disabled through configuration"); } BoundStatement result; result.types = {LogicalType::BOOLEAN}; @@ -140115,7 +151983,7 @@ BoundStatement Binder::Bind(InsertStatement &stmt) { // insertion statement specifies column list // create a mapping of (list index) -> (column index) - unordered_map column_name_map; + case_insensitive_map_t column_name_map; for (idx_t i = 0; i < stmt.columns.size(); i++) { column_name_map[stmt.columns[i]] = i; auto entry = table->name_map.find(stmt.columns[i]); @@ -140132,8 +152000,8 @@ BoundStatement Binder::Bind(InsertStatement &stmt) { auto &col = table->columns[i]; auto entry = column_name_map.find(col.name); if (entry == column_name_map.end()) { - // column not specified, set index to INVALID_INDEX - insert->column_index_map.push_back(INVALID_INDEX); + // column not specified, set index to DConstants::INVALID_INDEX + insert->column_index_map.push_back(DConstants::INVALID_INDEX); } else { // column was specified, set to the index insert->column_index_map.push_back(entry->second); @@ -140237,7 +152105,7 @@ BoundStatement Binder::Bind(PragmaStatement &stmt) { auto entry = catalog.GetEntry(context, DEFAULT_SCHEMA, stmt.info->name, false); string error; idx_t bound_idx = Function::BindFunction(entry->name, entry->functions, *stmt.info, error); - if (bound_idx == INVALID_INDEX) { + if (bound_idx == DConstants::INVALID_INDEX) { throw BinderException(FormatError(stmt.stmt_location, error)); } auto &bound_function = entry->functions[bound_idx]; @@ -140759,7 +152627,7 @@ BoundStatement Binder::Bind(UpdateStatement &stmt) { // finally add the row id column to the projection list proj->expressions.push_back(make_unique( - LOGICAL_ROW_TYPE, ColumnBinding(get->table_index, get->column_ids.size()))); + 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 @@ -140861,6 +152729,29 @@ 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 { @@ -140924,6 +152815,19 @@ unique_ptr Binder::Bind(BaseTableRef &ref) { 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 + AddTableName(ref.table_name); + + // add a bind context entry + auto table_index = GenerateTableIndex(); + auto alias = ref.alias.empty() ? ref.table_name : ref.alias; + vector types {LogicalType::INTEGER}; + vector names {"__dummy_col" + to_string(table_index)}; + bind_context.AddGenericBinding(table_index, alias, names, types); + 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); @@ -140964,7 +152868,9 @@ unique_ptr Binder::Bind(BaseTableRef &ref) { subquery.column_name_alias = BindContext::AliasColumnNames(subquery.alias, view_catalog_entry->aliases, ref.column_name_alias); // bind the child subquery + view_binder->AddBoundView(view_catalog_entry); auto bound_child = view_binder->Bind(subquery); + D_ASSERT(bound_child->type == TableReferenceType::SUBQUERY); // verify that the types and names match up with the expected types and names auto &bound_subquery = (BoundSubqueryRef &)*bound_child; @@ -141006,28 +152912,6 @@ unique_ptr Binder::Bind(CrossProductRef &ref) { } // 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 { @@ -141412,7 +153296,7 @@ unique_ptr Binder::Bind(JoinRef &ref) { namespace duckdb { -void Binder::BindNamedParameters(unordered_map &types, unordered_map &values, +void Binder::BindNamedParameters(named_parameter_type_map_t &types, named_parameter_map_t &values, QueryErrorContext &error_context, string &func_name) { for (auto &kv : values) { auto entry = types.find(kv.first); @@ -141489,7 +153373,7 @@ unique_ptr Binder::Bind(SubqueryRef &ref, CommonTableExpressionIn namespace duckdb { bool Binder::BindFunctionParameters(vector> &expressions, vector &arguments, - vector ¶meters, unordered_map &named_parameters, + vector ¶meters, named_parameter_map_t &named_parameters, unique_ptr &subquery, string &error) { bool seen_subquery = false; for (auto &child : expressions) { @@ -141501,8 +153385,8 @@ bool Binder::BindFunctionParameters(vector> &expres auto &comp = (ComparisonExpression &)*child; if (comp.left->type == ExpressionType::COLUMN_REF) { auto &colref = (ColumnRefExpression &)*comp.left; - if (colref.table_name.empty()) { - parameter_name = colref.column_name; + if (!colref.IsQualified()) { + parameter_name = colref.GetColumnName(); child = move(comp.right); } } @@ -141553,7 +153437,7 @@ unique_ptr Binder::Bind(TableFunctionRef &ref) { // evaluate the input parameters to the function vector arguments; vector parameters; - unordered_map named_parameters; + named_parameter_map_t named_parameters; unique_ptr subquery; string error; if (!BindFunctionParameters(fexpr->children, arguments, parameters, named_parameters, subquery, error)) { @@ -141567,7 +153451,7 @@ unique_ptr Binder::Bind(TableFunctionRef &ref) { // select the function based on the input parameters idx_t best_function_idx = Function::BindFunction(function->name, function->functions, arguments, error); - if (best_function_idx == INVALID_INDEX) { + if (best_function_idx == DConstants::INVALID_INDEX) { throw BinderException(FormatError(ref, error)); } auto &table_function = function->functions[best_function_idx]; @@ -141863,7 +153747,7 @@ static bool HasCorrelatedColumns(Expression &expression) { unique_ptr Binder::CreatePlan(BoundJoinRef &ref) { auto left = CreatePlan(*ref.left); auto right = CreatePlan(*ref.right); - if (ref.type == JoinType::RIGHT && context.enable_optimizer) { + 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; @@ -141973,6 +153857,9 @@ unique_ptr Binder::CreatePlan(BoundTableFunction &ref) { + + + #include namespace duckdb { @@ -142190,6 +154077,19 @@ bool Binder::CTEIsAlreadyBound(CommonTableExpressionInfo *cte) { return false; } +void Binder::AddBoundView(ViewCatalogEntry *view) { + // check if the view is already bound + auto current = this; + while (current) { + if (current->bound_views.find(view) != current->bound_views.end()) { + throw BinderException("infinite recursion detected: attempting to recursively bind view \"%s\"", + view->name); + } + current = current->parent.get(); + } + bound_views.insert(view); +} + idx_t Binder::GenerateTableIndex() { if (parent) { return parent->GenerateTableIndex(); @@ -142252,6 +154152,67 @@ void Binder::AddCorrelatedColumn(const CorrelatedColumnInfo &info) { } } +bool Binder::HasMatchingBinding(const string &table_name, const string &column_name, string &error_message) { + string empty_schema; + return HasMatchingBinding(empty_schema, table_name, column_name, error_message); +} + +bool Binder::HasMatchingBinding(const string &schema_name, const string &table_name, const string &column_name, + string &error_message) { + Binding *binding; + if (macro_binding && table_name == macro_binding->alias) { + binding = macro_binding; + } else { + binding = bind_context.GetBinding(table_name, error_message); + } + if (!binding) { + return false; + } + if (!schema_name.empty()) { + auto table_entry = binding->GetTableEntry(); + if (!table_entry) { + return false; + } + if (table_entry->schema->name != schema_name || table_entry->name != table_name) { + return false; + } + } + if (!binding->HasMatchingBinding(column_name)) { + error_message = binding->ColumnNotFoundError(column_name); + return false; + } + return true; +} + +void Binder::SetBindingMode(BindingMode mode) { + if (parent) { + parent->SetBindingMode(mode); + } + this->mode = mode; +} + +BindingMode Binder::GetBindingMode() { + if (parent) { + return parent->GetBindingMode(); + } + return mode; +} + +void Binder::AddTableName(string table_name) { + if (parent) { + parent->AddTableName(move(table_name)); + return; + } + table_names.insert(move(table_name)); +} + +const unordered_set &Binder::GetTableNames() { + if (parent) { + return parent->GetTableNames(); + } + return table_names; +} + string Binder::FormatError(ParsedExpression &expr_context, const string &message) { return FormatError(expr_context.query_location, message); } @@ -142510,18 +154471,45 @@ bool BoundCastExpression::CastIsInvertible(const LogicalType &source_type, const } return true; } - if (source_type.id() == LogicalTypeId::TIMESTAMP && target_type.id() == LogicalTypeId::DATE) { - return false; + if (source_type.id() == LogicalTypeId::TIMESTAMP || source_type.id() == LogicalTypeId::TIMESTAMP_TZ) { + switch (target_type.id()) { + case LogicalTypeId::DATE: + case LogicalTypeId::TIME: + case LogicalTypeId::TIME_TZ: + return false; + default: + break; + } } if (source_type.id() == LogicalTypeId::VARCHAR) { - return target_type.id() == LogicalTypeId::DATE || target_type.id() == LogicalTypeId::TIME || - target_type.id() == LogicalTypeId::TIMESTAMP || target_type.id() == LogicalTypeId::TIMESTAMP_NS || - target_type.id() == LogicalTypeId::TIMESTAMP_MS || target_type.id() == LogicalTypeId::TIMESTAMP_SEC; + switch (target_type.id()) { + case LogicalTypeId::DATE: + case LogicalTypeId::TIME: + case LogicalTypeId::TIMESTAMP: + case LogicalTypeId::TIMESTAMP_NS: + case LogicalTypeId::TIMESTAMP_MS: + case LogicalTypeId::TIMESTAMP_SEC: + case LogicalTypeId::TIME_TZ: + case LogicalTypeId::TIMESTAMP_TZ: + return true; + default: + return false; + } } if (target_type.id() == LogicalTypeId::VARCHAR) { - return source_type.id() == LogicalTypeId::DATE || source_type.id() == LogicalTypeId::TIME || - source_type.id() == LogicalTypeId::TIMESTAMP || source_type.id() == LogicalTypeId::TIMESTAMP_NS || - source_type.id() == LogicalTypeId::TIMESTAMP_MS || source_type.id() == LogicalTypeId::TIMESTAMP_SEC; + switch (source_type.id()) { + case LogicalTypeId::DATE: + case LogicalTypeId::TIME: + case LogicalTypeId::TIMESTAMP: + case LogicalTypeId::TIMESTAMP_NS: + case LogicalTypeId::TIMESTAMP_MS: + case LogicalTypeId::TIMESTAMP_SEC: + case LogicalTypeId::TIME_TZ: + case LogicalTypeId::TIMESTAMP_TZ: + return true; + default: + return false; + } } return true; } @@ -142694,7 +154682,7 @@ bool BoundConstantExpression::Equals(const BaseExpression *other_p) const { hash_t BoundConstantExpression::Hash() const { hash_t result = Expression::Hash(); - return CombineHash(ValueOperations::Hash(value), result); + return CombineHash(value.Hash(), result); } unique_ptr BoundConstantExpression::Copy() { @@ -142985,7 +154973,7 @@ BoundWindowExpression::BoundWindowExpression(ExpressionType type, LogicalType re unique_ptr aggregate, unique_ptr bind_info) : Expression(type, ExpressionClass::BOUND_WINDOW, move(return_type)), aggregate(move(aggregate)), - bind_info(move(bind_info)) { + bind_info(move(bind_info)), ignore_nulls(false) { } string BoundWindowExpression::ToString() const { @@ -143003,6 +154991,11 @@ string BoundWindowExpression::ToString() const { result += default_expr->GetName(); } + // IGNORE NULLS + if (ignore_nulls) { + result += " IGNORE NULLS"; + } + // Over clause result += ") OVER("; string sep; @@ -143120,6 +155113,9 @@ bool BoundWindowExpression::Equals(const BaseExpression *other_p) const { } auto other = (BoundWindowExpression *)other_p; + if (ignore_nulls != other->ignore_nulls) { + return false; + } if (start != other->start || end != other->end) { return false; } @@ -143202,6 +155198,7 @@ unique_ptr BoundWindowExpression::Copy() { new_window->end_expr = end_expr ? end_expr->Copy() : nullptr; new_window->offset_expr = offset_expr ? offset_expr->Copy() : nullptr; new_window->default_expr = default_expr ? default_expr->Copy() : nullptr; + new_window->ignore_nulls = ignore_nulls; return move(new_window); } @@ -143343,13 +155340,13 @@ string AlterBinder::UnsupportedAggregateMessage() { } BindResult AlterBinder::BindColumn(ColumnRefExpression &colref) { - if (!colref.table_name.empty() && colref.table_name != table.name) { - throw BinderException("Cannot reference table %s from within alter statement for table %s!", colref.table_name, - table.name); + if (colref.column_names.size() > 1) { + return BindQualifiedColumnName(colref, table.name); } - auto idx = table.GetColumnIndex(colref.column_name, true); - if (idx == INVALID_INDEX) { - throw BinderException("Table does not contain column %s referenced in alter statement!", colref.column_name); + auto idx = table.GetColumnIndex(colref.column_names[0], true); + if (idx == DConstants::INVALID_INDEX) { + throw BinderException("Table does not contain column %s referenced in alter statement!", + colref.column_names[0]); } bound_columns.push_back(idx); return BindResult(make_unique(table.columns[idx].type, bound_columns.size() - 1)); @@ -143363,9 +155360,9 @@ BindResult AlterBinder::BindColumn(ColumnRefExpression &colref) { namespace duckdb { -CheckBinder::CheckBinder(Binder &binder, ClientContext &context, string table, vector &columns, +CheckBinder::CheckBinder(Binder &binder, ClientContext &context, string table_p, vector &columns, unordered_set &bound_columns) - : ExpressionBinder(binder, context), table(move(table)), columns(columns), bound_columns(bound_columns) { + : ExpressionBinder(binder, context), table(move(table_p)), columns(columns), bound_columns(bound_columns) { target_type = LogicalType::INTEGER; } @@ -143387,18 +155384,29 @@ string CheckBinder::UnsupportedAggregateMessage() { return "aggregate functions are not allowed in check constraints"; } +BindResult ExpressionBinder::BindQualifiedColumnName(ColumnRefExpression &colref, const string &table_name) { + idx_t struct_start = 0; + if (colref.column_names[0] == table_name) { + struct_start++; + } + 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]); + } + return BindExpression(&result, 0); +} + BindResult CheckBinder::BindCheckColumn(ColumnRefExpression &colref) { - if (!colref.table_name.empty() && colref.table_name != table) { - throw BinderException("Cannot reference table %s from within check constraint for table %s!", colref.table_name, - table); + if (colref.column_names.size() > 1) { + return BindQualifiedColumnName(colref, table); } for (idx_t i = 0; i < columns.size(); i++) { - if (colref.column_name == columns[i].name) { + if (colref.column_names[0] == columns[i].name) { bound_columns.insert(i); return BindResult(make_unique(columns[i].type, i)); } } - throw BinderException("Table does not contain column %s referenced in check constraint!", colref.column_name); + throw BinderException("Table does not contain column %s referenced in check constraint!", colref.column_names[0]); } } // namespace duckdb @@ -143410,17 +155418,17 @@ BindResult CheckBinder::BindCheckColumn(ColumnRefExpression &colref) { namespace duckdb { -ColumnAliasBinder::ColumnAliasBinder(BoundSelectNode &node, const unordered_map &alias_map) +ColumnAliasBinder::ColumnAliasBinder(BoundSelectNode &node, const case_insensitive_map_t &alias_map) : node(node), alias_map(alias_map), in_alias(false) { } BindResult ColumnAliasBinder::BindAlias(ExpressionBinder &enclosing_binder, ColumnRefExpression &expr, idx_t depth, bool root_expression) { - if (!expr.table_name.empty()) { + if (expr.IsQualified()) { return BindResult(StringUtil::Format("Alias %s cannot be qualified.", expr.ToString())); } - auto alias_entry = alias_map.find(expr.column_name); + auto alias_entry = alias_map.find(expr.column_names[0]); if (alias_entry == alias_map.end()) { return BindResult(StringUtil::Format("Alias %s is not found.", expr.ToString())); } @@ -143474,7 +155482,7 @@ string ConstantBinder::UnsupportedAggregateMessage() { namespace duckdb { GroupBinder::GroupBinder(Binder &binder, ClientContext &context, SelectNode &node, idx_t group_index, - unordered_map &alias_map, unordered_map &group_alias_map) + case_insensitive_map_t &alias_map, case_insensitive_map_t &group_alias_map) : ExpressionBinder(binder, context), node(node), alias_map(alias_map), group_alias_map(group_alias_map), group_index(group_index) { } @@ -143550,13 +155558,13 @@ BindResult GroupBinder::BindColumnRef(ColumnRefExpression &colref) { // first try to bind to the base columns (original tables) auto result = ExpressionBinder::BindExpression(colref, 0); if (result.HasError()) { - // failed to bind the column and the node is the root expression with depth = 0 - // check if refers to an alias in the select clause - auto alias_name = colref.column_name; - if (!colref.table_name.empty()) { + if (colref.IsQualified()) { // explicit table name: not an alias reference return result; } + // failed to bind the column and the node is the root expression with depth = 0 + // check if refers to an alias in the select clause + auto alias_name = colref.column_names[0]; auto entry = alias_map.find(alias_name); if (entry == alias_map.end()) { // no matching alias found @@ -143582,7 +155590,7 @@ BindResult GroupBinder::BindColumnRef(ColumnRefExpression &colref) { namespace duckdb { HavingBinder::HavingBinder(Binder &binder, ClientContext &context, BoundSelectNode &node, BoundGroupInformation &info, - unordered_map &alias_map) + case_insensitive_map_t &alias_map) : SelectBinder(binder, context, node, info), column_alias_binder(node, alias_map) { target_type = LogicalType(LogicalTypeId::BOOLEAN); } @@ -143602,7 +155610,7 @@ BindResult HavingBinder::BindExpression(unique_ptr *expr_ptr, auto &expr = **expr_ptr; // check if the expression binds to one of the groups auto group_index = TryBindGroup(expr, depth); - if (group_index != INVALID_INDEX) { + if (group_index != DConstants::INVALID_INDEX) { return BindGroup(expr, depth, group_index); } switch (expr.expression_class) { @@ -143674,15 +155682,16 @@ string InsertBinder::UnsupportedAggregateMessage() { + namespace duckdb { -OrderBinder::OrderBinder(vector binders, idx_t projection_index, unordered_map &alias_map, +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), alias_map(alias_map), projection_map(projection_map) { } OrderBinder::OrderBinder(vector binders, idx_t projection_index, SelectNode &node, - unordered_map &alias_map, expression_map_t &projection_map) + 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) { this->max_count = node.select_list.size(); this->extra_list = &node.select_list; @@ -143723,11 +155732,11 @@ unique_ptr OrderBinder::Bind(unique_ptr expr) { // check if we can bind it to an alias in the select list auto &colref = (ColumnRefExpression &)*expr; // if there is an explicit table name we can't bind to an alias - if (!colref.table_name.empty()) { + if (colref.IsQualified()) { break; } // check the alias list - auto entry = alias_map.find(colref.column_name); + auto entry = alias_map.find(colref.column_names[0]); if (entry != alias_map.end()) { // it does! point it to that entry return CreateProjectionReference(*expr, entry->second); @@ -143744,12 +155753,12 @@ unique_ptr OrderBinder::Bind(unique_ptr expr) { // general case // first bind the table names of this entry for (auto &binder : binders) { - ExpressionBinder::BindTableNames(*binder, *expr); + ExpressionBinder::QualifyColumnNames(*binder, expr); } // first check if the ORDER BY clause already points to an entry in the projection list auto entry = projection_map.find(expr.get()); if (entry != projection_map.end()) { - if (entry->second == INVALID_INDEX) { + if (entry->second == DConstants::INVALID_INDEX) { throw BinderException("Ambiguous reference to column"); } // there is a matching entry in the projection list @@ -143769,6 +155778,56 @@ unique_ptr OrderBinder::Bind(unique_ptr expr) { } } // namespace duckdb + + + + + + + + +namespace duckdb { + +QualifyBinder::QualifyBinder(Binder &binder, ClientContext &context, BoundSelectNode &node, BoundGroupInformation &info, + case_insensitive_map_t &alias_map) + : SelectBinder(binder, context, node, info), column_alias_binder(node, alias_map) { + target_type = LogicalType(LogicalTypeId::BOOLEAN); +} + +BindResult QualifyBinder::BindColumnRef(unique_ptr *expr_ptr, idx_t depth, bool root_expression) { + auto &expr = (ColumnRefExpression &)**expr_ptr; + auto result = duckdb::SelectBinder::BindExpression(expr_ptr, depth); + if (!result.HasError()) { + return result; + } + + auto alias_result = column_alias_binder.BindAlias(*this, expr, depth, root_expression); + if (!alias_result.HasError()) { + return alias_result; + } + + return BindResult(StringUtil::Format("Referenced column %s not found in FROM clause and can't find in alias map.", + expr.ToString())); +} + +BindResult QualifyBinder::BindExpression(unique_ptr *expr_ptr, idx_t depth, bool root_expression) { + auto &expr = **expr_ptr; + // check if the expression binds to one of the groups + auto group_index = TryBindGroup(expr, depth); + if (group_index != DConstants::INVALID_INDEX) { + return BindGroup(expr, depth, group_index); + } + switch (expr.expression_class) { + case ExpressionClass::WINDOW: + return BindWindow((WindowExpression &)expr, depth); + case ExpressionClass::COLUMN_REF: + return BindColumnRef(expr_ptr, depth, root_expression); + default: + return duckdb::SelectBinder::BindExpression(expr_ptr, depth); + } +} + +} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // @@ -143850,7 +155909,7 @@ BindResult SelectBinder::BindExpression(unique_ptr *expr_ptr, auto &expr = **expr_ptr; // check if the expression binds to one of the groups auto group_index = TryBindGroup(expr, depth); - if (group_index != INVALID_INDEX) { + if (group_index != DConstants::INVALID_INDEX) { return BindGroup(expr, depth, group_index); } switch (expr.expression_class) { @@ -143867,8 +155926,8 @@ idx_t SelectBinder::TryBindGroup(ParsedExpression &expr, idx_t depth) { // first check the group alias map, if expr is a ColumnRefExpression if (expr.type == ExpressionType::COLUMN_REF) { auto &colref = (ColumnRefExpression &)expr; - if (colref.table_name.empty()) { - auto alias_entry = info.alias_map.find(colref.column_name); + if (!colref.IsQualified()) { + auto alias_entry = info.alias_map.find(colref.column_names[0]); if (alias_entry != info.alias_map.end()) { // found entry! return alias_entry->second; @@ -143887,7 +155946,7 @@ idx_t SelectBinder::TryBindGroup(ParsedExpression &expr, idx_t depth) { D_ASSERT(!expr.Equals(entry.first)); } #endif - return INVALID_INDEX; + return DConstants::INVALID_INDEX; } BindResult SelectBinder::BindGroupingFunction(OperatorExpression &op, idx_t depth) { @@ -143903,9 +155962,9 @@ BindResult SelectBinder::BindGroupingFunction(OperatorExpression &op, idx_t dept vector group_indexes; group_indexes.reserve(op.children.size()); for (auto &child : op.children) { - ExpressionBinder::BindTableNames(binder, *child); + ExpressionBinder::QualifyColumnNames(binder, child); auto idx = TryBindGroup(*child, depth); - if (idx == INVALID_INDEX) { + if (idx == DConstants::INVALID_INDEX) { return BindResult(binder.FormatError( op, StringUtil::Format("GROUPING child \"%s\" must be a grouping column", child->GetName()))); } @@ -144073,7 +156132,7 @@ bool ExpressionBinder::BindCorrelatedColumns(unique_ptr &expr) bool success = false; while (!active_binders.empty()) { auto &next_binder = active_binders.back(); - ExpressionBinder::BindTableNames(next_binder->binder, *expr); + ExpressionBinder::QualifyColumnNames(next_binder->binder, expr); auto bind_result = next_binder->Bind(&expr, depth); if (bind_result.empty()) { success = true; @@ -144234,33 +156293,6 @@ string ExpressionBinder::Bind(unique_ptr *expr, idx_t depth, b } } -void ExpressionBinder::BindTableNames(Binder &binder, ParsedExpression &expr, unordered_map *alias_map) { - if (expr.type == ExpressionType::COLUMN_REF) { - auto &colref = (ColumnRefExpression &)expr; - if (colref.table_name.empty()) { - // no table name: find a binding that contains this - if (binder.macro_binding != nullptr && binder.macro_binding->HasMatchingBinding(colref.column_name)) { - // macro parameters get priority - colref.table_name = binder.macro_binding->alias; - } else { - colref.table_name = binder.bind_context.GetMatchingBinding(colref.column_name); - } - } - binder.bind_context.BindColumn(colref, 0); - } else if (expr.type == ExpressionType::POSITIONAL_REFERENCE) { - auto &ref = (PositionalReferenceExpression &)expr; - if (ref.alias.empty()) { - string table_name, column_name; - auto error = binder.bind_context.BindColumn(ref, table_name, column_name); - if (error.empty()) { - ref.alias = column_name; - } - } - } - ParsedExpressionIterator::EnumerateChildren( - expr, [&](const ParsedExpression &child) { BindTableNames(binder, (ParsedExpression &)child, alias_map); }); -} - } // namespace duckdb @@ -144418,6 +156450,15 @@ void ExpressionIterator::EnumerateTableRefChildren(BoundTableRef &ref, EnumerateTableRefChildren(*bound_crossproduct.right, callback); break; } + case TableReferenceType::EXPRESSION_LIST: { + auto &bound_expr_list = (BoundExpressionListRef &)ref; + for (auto &expr_list : bound_expr_list.values) { + for (auto &expr : expr_list) { + EnumerateExpression(expr, callback); + } + } + break; + } case TableReferenceType::JOIN: { auto &bound_join = (BoundJoinRef &)ref; EnumerateExpression(bound_join.condition, callback); @@ -144494,7 +156535,7 @@ void ExpressionIterator::EnumerateQueryNodeChildren(BoundQueryNode &node, namespace duckdb { -ConjunctionOrFilter::ConjunctionOrFilter() : TableFilter(TableFilterType::CONJUNCTION_OR) { +ConjunctionOrFilter::ConjunctionOrFilter() : ConjunctionFilter(TableFilterType::CONJUNCTION_OR) { } FilterPropagateResult ConjunctionOrFilter::CheckStatistics(BaseStatistics &stats) { @@ -144523,7 +156564,7 @@ string ConjunctionOrFilter::ToString(const string &column_name) { } bool ConjunctionOrFilter::Equals(const TableFilter &other_p) const { - if (!TableFilter::Equals(other_p)) { + if (!ConjunctionFilter::Equals(other_p)) { return false; } auto &other = (ConjunctionOrFilter &)other_p; @@ -144538,11 +156579,11 @@ bool ConjunctionOrFilter::Equals(const TableFilter &other_p) const { return true; } -ConjunctionAndFilter::ConjunctionAndFilter() : TableFilter(TableFilterType::CONJUNCTION_AND) { +ConjunctionAndFilter::ConjunctionAndFilter() : ConjunctionFilter(TableFilterType::CONJUNCTION_AND) { } FilterPropagateResult ConjunctionAndFilter::CheckStatistics(BaseStatistics &stats) { - // the OR filter is true if ALL of the children is true + // the AND filter is true if ALL of the children is true D_ASSERT(!child_filters.empty()); auto result = FilterPropagateResult::FILTER_ALWAYS_TRUE; for (auto &filter : child_filters) { @@ -144568,7 +156609,7 @@ string ConjunctionAndFilter::ToString(const string &column_name) { } bool ConjunctionAndFilter::Equals(const TableFilter &other_p) const { - if (!TableFilter::Equals(other_p)) { + if (!ConjunctionFilter::Equals(other_p)) { return false; } auto &other = (ConjunctionAndFilter &)other_p; @@ -144833,7 +156874,7 @@ vector LogicalOperator::MapBindings(const vector & } } -string LogicalOperator::ToString(idx_t depth) const { +string LogicalOperator::ToString() const { TreeRenderer renderer; return renderer.ToString(*this); } @@ -144956,6 +156997,16 @@ void LogicalOperatorVisitor::EnumerateExpressions(LogicalOperator &op, } break; } + case LogicalOperatorType::LOGICAL_LIMIT_PERCENT: { + auto &limit = (LogicalLimitPercent &)op; + if (limit.limit) { + callback(&limit.limit); + } + if (limit.offset) { + callback(&limit.offset); + } + break; + } case LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY: { auto &aggr = (LogicalAggregate &)op; for (auto &group : aggr.groups) { @@ -145135,11 +157186,11 @@ 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(INVALID_INDEX) { + aggregate_index(aggregate_index), groupings_index(DConstants::INVALID_INDEX) { } void LogicalAggregate::ResolveTypes() { - D_ASSERT(groupings_index != INVALID_INDEX || grouping_functions.empty()); + D_ASSERT(groupings_index != DConstants::INVALID_INDEX || grouping_functions.empty()); for (auto &expr : groups) { types.push_back(expr->return_type); } @@ -145148,12 +157199,12 @@ void LogicalAggregate::ResolveTypes() { types.push_back(expr->return_type); } for (idx_t i = 0; i < grouping_functions.size(); i++) { - types.push_back(LogicalType::BIGINT); + types.emplace_back(LogicalType::BIGINT); } } vector LogicalAggregate::GetColumnBindings() { - D_ASSERT(groupings_index != INVALID_INDEX || grouping_functions.empty()); + D_ASSERT(groupings_index != DConstants::INVALID_INDEX || grouping_functions.empty()); vector result; for (idx_t i = 0; i < groups.size(); i++) { result.emplace_back(group_index, i); @@ -145323,6 +157374,7 @@ bool LogicalFilter::SplitPredicates(vector> &expressions) + namespace duckdb { LogicalGet::LogicalGet(idx_t table_index, TableFunction function, unique_ptr bind_data, @@ -145335,6 +157387,10 @@ string LogicalGet::GetName() const { return StringUtil::Upper(function.name); } +TableCatalogEntry *LogicalGet::GetTable() const { + return TableScanFunction::GetTableEntry(function, bind_data.get()); +} + string LogicalGet::ParamsToString() const { string result; for (auto &kv : table_filters.filters) { @@ -145368,7 +157424,7 @@ void LogicalGet::ResolveTypes() { } for (auto &index : column_ids) { if (index == COLUMN_IDENTIFIER_ROW_ID) { - types.push_back(LOGICAL_ROW_TYPE); + types.emplace_back(LogicalType::ROW_TYPE); } else { types.push_back(returned_types[index]); } @@ -145422,7 +157478,7 @@ void LogicalJoin::ResolveTypes() { } if (join_type == JoinType::MARK) { // for MARK join we project the left hand side, plus a BOOLEAN column indicating the MARK - types.push_back(LogicalType::BOOLEAN); + types.emplace_back(LogicalType::BOOLEAN); return; } // for any other join we project both sides @@ -145449,6 +157505,33 @@ void LogicalJoin::GetExpressionBindings(Expression &expr, unordered_set & } // namespace duckdb +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)) { +} + +vector LogicalLimit::GetColumnBindings() { + return children[0]->GetColumnBindings(); +} + +idx_t LogicalLimit::EstimateCardinality(ClientContext &context) { + auto child_cardinality = children[0]->EstimateCardinality(context); + if (limit_val >= 0 && idx_t(limit_val) < child_cardinality) { + child_cardinality = limit_val; + } + return child_cardinality; +} + +void LogicalLimit::ResolveTypes() { + types = children[0]->types; +} + +} // namespace duckdb + + namespace duckdb { LogicalProjection::LogicalProjection(idx_t table_index, vector> select_list) @@ -145468,6 +157551,37 @@ void LogicalProjection::ResolveTypes() { } // 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)); +} + +vector LogicalSample::GetColumnBindings() { + return children[0]->GetColumnBindings(); +} + +idx_t LogicalSample::EstimateCardinality(ClientContext &context) { + auto child_cardinality = children[0]->EstimateCardinality(context); + if (sample_options->is_percentage) { + return idx_t(child_cardinality * sample_options->sample_size.GetValue()); + } else { + auto sample_size = sample_options->sample_size.GetValue(); + if (sample_size < child_cardinality) { + return sample_size; + } + } + return child_cardinality; +} + +void LogicalSample::ResolveTypes() { + types = children[0]->types; +} + +} // namespace duckdb + + namespace duckdb { vector LogicalUnnest::GetColumnBindings() { @@ -145529,13 +157643,15 @@ Planner::Planner(ClientContext &context) : binder(Binder::CreateBinder(context)) } void Planner::CreatePlan(SQLStatement &statement) { + auto &profiler = QueryProfiler::Get(context); + vector bound_parameters; // first bind the tables and columns to the catalog - context.profiler->StartPhase("binder"); + profiler.StartPhase("binder"); binder->parameters = &bound_parameters; auto bound_statement = binder->Bind(statement); - context.profiler->EndPhase(); + profiler.EndPhase(); this->read_only = binder->read_only; this->requires_valid_transaction = binder->requires_valid_transaction; @@ -145609,7 +157725,9 @@ void Planner::PlanExecute(unique_ptr statement) { vector bind_values; for (idx_t i = 0; i < stmt.values.size(); i++) { ConstantBinder cbinder(*binder, context, "EXECUTE statement"); - cbinder.target_type = prepared->GetType(i + 1); + if (prepared->value_map.count(i + 1)) { + cbinder.target_type = prepared->GetType(i + 1); + } auto bound_expr = cbinder.Bind(stmt.values[i]); Value value = ExpressionExecutor::EvaluateScalar(*bound_expr); @@ -145710,7 +157828,7 @@ void PragmaHandler::HandlePragmaStatementsInternal(vector(context, DEFAULT_SCHEMA, info.name, false); string error; idx_t bound_idx = Function::BindFunction(entry->name, entry->functions, info, error); - if (bound_idx == INVALID_INDEX) { + if (bound_idx == DConstants::INVALID_INDEX) { throw BinderException(error); } auto &bound_function = entry->functions[bound_idx]; @@ -146051,8 +158169,9 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal join->children.push_back(move(plan->children[1])); return move(join); } + case LogicalOperatorType::LOGICAL_ANY_JOIN: case LogicalOperatorType::LOGICAL_COMPARISON_JOIN: { - auto &join = (LogicalComparisonJoin &)*plan; + auto &join = (LogicalJoin &)*plan; D_ASSERT(plan->children.size() == 2); // check the correlated expressions in the children of the join bool left_has_correlation = has_correlated_expressions.find(plan->children[0].get())->second; @@ -146077,6 +158196,13 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0])); return plan; } + } else if (join.join_type == JoinType::RIGHT) { + // left outer join + if (!left_has_correlation) { + // only right has correlation: push into right + plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1])); + return plan; + } } else if (join.join_type == JoinType::MARK) { if (right_has_correlation) { throw Exception("MARK join with correlation in RHS not supported"); @@ -146092,27 +158218,42 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal } // both sides have correlation // push into both sides - // 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 - // because the RIGHT binding might contain NULL values plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0])); auto left_binding = this->base_binding; plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1])); 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 + // because the RIGHT binding might contain NULL values if (join.join_type == JoinType::LEFT) { this->base_binding = left_binding; + } else if (join.join_type == JoinType::RIGHT) { + this->base_binding = right_binding; } // add the correlated columns to the join conditions for (idx_t i = 0; i < correlated_columns.size(); i++) { - JoinCondition cond; - - cond.left = make_unique( + auto left = make_unique( correlated_columns[i].type, ColumnBinding(left_binding.table_index, left_binding.column_index + i)); - cond.right = make_unique( + auto right = make_unique( correlated_columns[i].type, ColumnBinding(right_binding.table_index, right_binding.column_index + i)); - cond.comparison = ExpressionType::COMPARE_EQUAL; - cond.null_values_are_equal = true; - join.conditions.push_back(move(cond)); + + if (join.type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN) { + JoinCondition cond; + cond.left = move(left); + cond.right = move(right); + cond.comparison = ExpressionType::COMPARE_EQUAL; + cond.null_values_are_equal = true; + + auto &comparison_join = (LogicalComparisonJoin &)join; + comparison_join.conditions.push_back(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); + } } // then we replace any correlated expressions with the corresponding entry in the correlated_map RewriteCorrelatedExpressions rewriter(right_binding, correlated_map); @@ -146136,6 +158277,9 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal return move(plan->children[0]); } } + case LogicalOperatorType::LOGICAL_LIMIT_PERCENT: { + throw ParserException("Limit percent operator not supported in correlated subquery"); + } case LogicalOperatorType::LOGICAL_WINDOW: { auto &window = (LogicalWindow &)*plan; // push into children @@ -146165,9 +158309,32 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal setop.column_count += correlated_columns.size(); return plan; } - case LogicalOperatorType::LOGICAL_DISTINCT: - plan->children[0] = PushDownDependentJoin(move(plan->children[0])); - return plan; + case LogicalOperatorType::LOGICAL_DISTINCT: + plan->children[0] = PushDownDependentJoin(move(plan->children[0])); + return plan; + case LogicalOperatorType::LOGICAL_EXPRESSION_GET: { + // expression get + // first we flatten the dependent join in the child + plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0])); + // then we replace any correlated expressions with the corresponding entry in the correlated_map + RewriteCorrelatedExpressions rewriter(base_binding, correlated_map); + rewriter.VisitOperator(*plan); + // now we add all the correlated columns to each of the expressions of the expression scan + auto expr_get = (LogicalExpressionGet *)plan.get(); + for (idx_t i = 0; i < correlated_columns.size(); i++) { + 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_get->expr_types.push_back(correlated_columns[i].type); + } + + base_binding.table_index = expr_get->table_index; + this->delim_offset = base_binding.column_index = expr_get->expr_types.size() - correlated_columns.size(); + this->data_offset = 0; + return plan; + } case LogicalOperatorType::LOGICAL_ORDER_BY: throw ParserException("ORDER BY not supported in correlated subquery"); default: @@ -146374,16 +158541,27 @@ bool Binding::TryGetBindingIndex(const string &column_name, column_t &result) { return false; } +column_t Binding::GetBindingIndex(const string &column_name) { + column_t result; + if (!TryGetBindingIndex(column_name, result)) { + throw InternalException("Binding index for column \"%s\" not found", column_name); + } + return result; +} + bool Binding::HasMatchingBinding(const string &column_name) { column_t result; return TryGetBindingIndex(column_name, result); } +string Binding::ColumnNotFoundError(const string &column_name) const { + return StringUtil::Format("Values list \"%s\" does not have a column named \"%s\"", alias, column_name); +} + BindResult Binding::Bind(ColumnRefExpression &colref, idx_t depth) { column_t column_index; - if (!TryGetBindingIndex(colref.column_name, column_index)) { - return BindResult(StringUtil::Format("Values list \"%s\" does not have a column named \"%s\"", alias.c_str(), - colref.column_name.c_str())); + if (!TryGetBindingIndex(colref.GetColumnName(), column_index)) { + return BindResult(ColumnNotFoundError(colref.GetColumnName())); } ColumnBinding binding; binding.table_index = index; @@ -146395,6 +158573,10 @@ BindResult Binding::Bind(ColumnRefExpression &colref, idx_t depth) { return BindResult(make_unique(colref.GetName(), sql_type, binding, depth)); } +TableCatalogEntry *Binding::GetTableEntry() { + return nullptr; +} + TableBinding::TableBinding(const string &alias, vector types_p, vector names_p, LogicalGet &get, idx_t index, bool add_row_id) : Binding(alias, move(types_p), move(names_p), index), get(get) { @@ -146406,10 +158588,10 @@ TableBinding::TableBinding(const string &alias, vector types_p, vec } BindResult TableBinding::Bind(ColumnRefExpression &colref, idx_t depth) { + auto &column_name = colref.GetColumnName(); column_t column_index; - if (!TryGetBindingIndex(colref.column_name, column_index)) { - return BindResult(StringUtil::Format("Table \"%s\" does not have a column named \"%s\"", colref.table_name, - colref.column_name)); + if (!TryGetBindingIndex(column_name, column_index)) { + return BindResult(ColumnNotFoundError(column_name)); } // fetch the type of the column LogicalType col_type; @@ -146443,15 +158625,22 @@ BindResult TableBinding::Bind(ColumnRefExpression &colref, idx_t depth) { return BindResult(make_unique(colref.GetName(), col_type, binding, depth)); } +TableCatalogEntry *TableBinding::GetTableEntry() { + return get.GetTable(); +} + +string TableBinding::ColumnNotFoundError(const string &column_name) const { + return StringUtil::Format("Table \"%s\" does not have a column named \"%s\"", alias, column_name); +} + MacroBinding::MacroBinding(vector types_p, vector names_p, string macro_name_p) - : Binding("0_macro_parameters", move(types_p), move(names_p), -1), macro_name(move(macro_name_p)) { + : Binding(MacroBinding::MACRO_NAME, move(types_p), move(names_p), -1), macro_name(move(macro_name_p)) { } BindResult MacroBinding::Bind(ColumnRefExpression &colref, idx_t depth) { column_t column_index; - if (!TryGetBindingIndex(colref.column_name, column_index)) { - return BindResult( - StringUtil::Format("Macro \"%s\" does not have a parameter named \"%s\"", macro_name, colref.column_name)); + if (!TryGetBindingIndex(colref.GetColumnName(), column_index)) { + throw InternalException("Column %s not found in macro", colref.GetColumnName()); } ColumnBinding binding; binding.table_index = index; @@ -146463,8 +158652,8 @@ BindResult MacroBinding::Bind(ColumnRefExpression &colref, idx_t depth) { unique_ptr MacroBinding::ParamToArg(ColumnRefExpression &colref) { column_t column_index; - if (!TryGetBindingIndex(colref.column_name, column_index)) { - throw BinderException("Macro \"%s\" does not have a parameter named \"%s\"", macro_name, colref.column_name); + if (!TryGetBindingIndex(colref.GetColumnName(), column_index)) { + throw InternalException("Column %s not found in macro", colref.GetColumnName()); } auto arg = arguments[column_index]->Copy(); arg->alias = colref.alias; @@ -147965,6 +160154,2042 @@ void PartialBlock::FlushToDisk(DatabaseInstance &db) { } } +} // namespace duckdb + + +// LICENSE_CHANGE_BEGIN +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #10 +// See the end of this file for a list + +/** +* This code is released under the +* Apache License Version 2.0 http://www.apache.org/licenses/. +* +* (c) Daniel Lemire, http://lemire.me/en/ +*/ + + + +// LICENSE_CHANGE_BEGIN +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #10 +// See the end of this file for a list + +/** + * This code is released under the + * Apache License Version 2.0 http://www.apache.org/licenses/. + * + * (c) Daniel Lemire, http://fastpforlib.me/en/ + */ + +#include +#include + +namespace duckdb_fastpforlib { +namespace internal { + +// Unpacks 8 uint8_t values +void __fastunpack0(const uint8_t *__restrict in, uint8_t *__restrict out); +void __fastunpack1(const uint8_t *__restrict in, uint8_t *__restrict out); +void __fastunpack2(const uint8_t *__restrict in, uint8_t *__restrict out); +void __fastunpack3(const uint8_t *__restrict in, uint8_t *__restrict out); +void __fastunpack4(const uint8_t *__restrict in, uint8_t *__restrict out); +void __fastunpack5(const uint8_t *__restrict in, uint8_t *__restrict out); +void __fastunpack6(const uint8_t *__restrict in, uint8_t *__restrict out); +void __fastunpack7(const uint8_t *__restrict in, uint8_t *__restrict out); +void __fastunpack8(const uint8_t *__restrict in, uint8_t *__restrict out); + +// Unpacks 16 uint16_t values +void __fastunpack0(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastunpack1(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastunpack2(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastunpack3(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastunpack4(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastunpack5(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastunpack6(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastunpack7(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastunpack8(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastunpack9(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastunpack10(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastunpack11(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastunpack12(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastunpack13(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastunpack14(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastunpack15(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastunpack16(const uint16_t *__restrict in, uint16_t *__restrict out); + +// Unpacks 32 uint32_t values +void __fastunpack0(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack1(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack2(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack3(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack4(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack5(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack6(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack7(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack8(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack9(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack10(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack11(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack12(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack13(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack14(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack15(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack16(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack17(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack18(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack19(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack20(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack21(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack22(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack23(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack24(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack25(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack26(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack27(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack28(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack29(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack30(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack31(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastunpack32(const uint32_t *__restrict in, uint32_t *__restrict out); + +// Unpacks 32 uint64_t values +void __fastunpack0(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack1(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack2(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack3(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack4(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack5(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack6(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack7(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack8(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack9(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack10(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack11(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack12(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack13(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack14(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack15(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack16(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack17(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack18(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack19(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack20(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack21(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack22(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack23(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack24(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack25(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack26(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack27(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack28(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack29(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack30(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack31(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack32(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack33(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack34(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack35(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack36(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack37(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack38(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack39(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack40(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack41(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack42(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack43(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack44(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack45(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack46(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack47(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack48(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack49(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack50(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack51(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack52(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack53(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack54(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack55(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack56(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack57(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack58(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack59(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack60(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack61(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack62(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack63(const uint32_t *__restrict in, uint64_t *__restrict out); +void __fastunpack64(const uint32_t *__restrict in, uint64_t *__restrict out); + +// Packs 8 int8_t values +void __fastpack0(const uint8_t *__restrict in, uint8_t *__restrict out); +void __fastpack1(const uint8_t *__restrict in, uint8_t *__restrict out); +void __fastpack2(const uint8_t *__restrict in, uint8_t *__restrict out); +void __fastpack3(const uint8_t *__restrict in, uint8_t *__restrict out); +void __fastpack4(const uint8_t *__restrict in, uint8_t *__restrict out); +void __fastpack5(const uint8_t *__restrict in, uint8_t *__restrict out); +void __fastpack6(const uint8_t *__restrict in, uint8_t *__restrict out); +void __fastpack7(const uint8_t *__restrict in, uint8_t *__restrict out); +void __fastpack8(const uint8_t *__restrict in, uint8_t *__restrict out); + +// Packs 16 int16_t values +void __fastpack0(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastpack1(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastpack2(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastpack3(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastpack4(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastpack5(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastpack6(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastpack7(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastpack8(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastpack9(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastpack10(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastpack11(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastpack12(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastpack13(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastpack14(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastpack15(const uint16_t *__restrict in, uint16_t *__restrict out); +void __fastpack16(const uint16_t *__restrict in, uint16_t *__restrict out); + +// Packs 32 int32_t values +void __fastpack0(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack1(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack2(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack3(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack4(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack5(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack6(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack7(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack8(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack9(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack10(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack11(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack12(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack13(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack14(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack15(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack16(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack17(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack18(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack19(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack20(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack21(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack22(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack23(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack24(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack25(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack26(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack27(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack28(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack29(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack30(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack31(const uint32_t *__restrict in, uint32_t *__restrict out); +void __fastpack32(const uint32_t *__restrict in, uint32_t *__restrict out); + +// Packs 32 int64_t values +void __fastpack0(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack1(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack2(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack3(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack4(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack5(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack6(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack7(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack8(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack9(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack10(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack11(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack12(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack13(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack14(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack15(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack16(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack17(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack18(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack19(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack20(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack21(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack22(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack23(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack24(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack25(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack26(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack27(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack28(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack29(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack30(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack31(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack32(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack33(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack34(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack35(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack36(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack37(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack38(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack39(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack40(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack41(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack42(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack43(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack44(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack45(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack46(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack47(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack48(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack49(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack50(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack51(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack52(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack53(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack54(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack55(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack56(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack57(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack58(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack59(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack60(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack61(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack62(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack63(const uint64_t *__restrict in, uint32_t *__restrict out); +void __fastpack64(const uint64_t *__restrict in, uint32_t *__restrict out); +} // namespace internal +} // namespace duckdb_fastpforlib + + +// LICENSE_CHANGE_END + + + +#include + +namespace duckdb_fastpforlib { + +namespace internal { + +// Note that this only packs 8 values +inline void fastunpack_quarter(const uint8_t *__restrict in, uint8_t *__restrict out, const uint32_t bit) { + // Could have used function pointers instead of switch. + // Switch calls do offer the compiler more opportunities for optimization in + // theory. In this case, it makes no difference with a good compiler. + switch (bit) { + case 0: + internal::__fastunpack0(in, out); + break; + case 1: + internal::__fastunpack1(in, out); + break; + case 2: + internal::__fastunpack2(in, out); + break; + case 3: + internal::__fastunpack3(in, out); + break; + case 4: + internal::__fastunpack4(in, out); + break; + case 5: + internal::__fastunpack5(in, out); + break; + case 6: + internal::__fastunpack6(in, out); + break; + case 7: + internal::__fastunpack7(in, out); + break; + case 8: + internal::__fastunpack8(in, out); + break; + default: + throw std::logic_error("Invalid bit width for bitpacking"); + } +} + +// Note that this only packs 8 values +inline void fastpack_quarter(const uint8_t *__restrict in, uint8_t *__restrict out, const uint32_t bit) { + // Could have used function pointers instead of switch. + // Switch calls do offer the compiler more opportunities for optimization in + // theory. In this case, it makes no difference with a good compiler. + switch (bit) { + case 0: + internal::__fastpack0(in, out); + break; + case 1: + internal::__fastpack1(in, out); + break; + case 2: + internal::__fastpack2(in, out); + break; + case 3: + internal::__fastpack3(in, out); + break; + case 4: + internal::__fastpack4(in, out); + break; + case 5: + internal::__fastpack5(in, out); + break; + case 6: + internal::__fastpack6(in, out); + break; + case 7: + internal::__fastpack7(in, out); + break; + case 8: + internal::__fastpack8(in, out); + break; + default: + throw std::logic_error("Invalid bit width for bitpacking"); + } +} + +// Note that this only packs 16 values +inline void fastunpack_half(const uint16_t *__restrict in, uint16_t *__restrict out, const uint32_t bit) { + // Could have used function pointers instead of switch. + // Switch calls do offer the compiler more opportunities for optimization in + // theory. In this case, it makes no difference with a good compiler. + switch (bit) { + case 0: + internal::__fastunpack0(in, out); + break; + case 1: + internal::__fastunpack1(in, out); + break; + case 2: + internal::__fastunpack2(in, out); + break; + case 3: + internal::__fastunpack3(in, out); + break; + case 4: + internal::__fastunpack4(in, out); + break; + case 5: + internal::__fastunpack5(in, out); + break; + case 6: + internal::__fastunpack6(in, out); + break; + case 7: + internal::__fastunpack7(in, out); + break; + case 8: + internal::__fastunpack8(in, out); + break; + case 9: + internal::__fastunpack9(in, out); + break; + case 10: + internal::__fastunpack10(in, out); + break; + case 11: + internal::__fastunpack11(in, out); + break; + case 12: + internal::__fastunpack12(in, out); + break; + case 13: + internal::__fastunpack13(in, out); + break; + case 14: + internal::__fastunpack14(in, out); + break; + case 15: + internal::__fastunpack15(in, out); + break; + case 16: + internal::__fastunpack16(in, out); + break; + default: + throw std::logic_error("Invalid bit width for bitpacking"); + } +} + +// Note that this only packs 16 values +inline void fastpack_half(const uint16_t *__restrict in, uint16_t *__restrict out, const uint32_t bit) { + // Could have used function pointers instead of switch. + // Switch calls do offer the compiler more opportunities for optimization in + // theory. In this case, it makes no difference with a good compiler. + switch (bit) { + case 0: + internal::__fastpack0(in, out); + break; + case 1: + internal::__fastpack1(in, out); + break; + case 2: + internal::__fastpack2(in, out); + break; + case 3: + internal::__fastpack3(in, out); + break; + case 4: + internal::__fastpack4(in, out); + break; + case 5: + internal::__fastpack5(in, out); + break; + case 6: + internal::__fastpack6(in, out); + break; + case 7: + internal::__fastpack7(in, out); + break; + case 8: + internal::__fastpack8(in, out); + break; + case 9: + internal::__fastpack9(in, out); + break; + case 10: + internal::__fastpack10(in, out); + break; + case 11: + internal::__fastpack11(in, out); + break; + case 12: + internal::__fastpack12(in, out); + break; + case 13: + internal::__fastpack13(in, out); + break; + case 14: + internal::__fastpack14(in, out); + break; + case 15: + internal::__fastpack15(in, out); + break; + case 16: + internal::__fastpack16(in, out); + break; + default: + throw std::logic_error("Invalid bit width for bitpacking"); + } +} +} + +inline void fastunpack(const uint8_t *__restrict in, uint8_t *__restrict out, const uint32_t bit) { + for (uint8_t i = 0; i < 4; i++) { + internal::fastunpack_quarter(in + (i*bit), out+(i*8), bit); + } +} + +inline void fastunpack(const uint16_t *__restrict in, uint16_t *__restrict out, const uint32_t bit) { + internal::fastunpack_half(in, out, bit); + internal::fastunpack_half(in + bit, out+16, bit); +} + +inline void fastunpack(const uint32_t *__restrict in, + uint32_t *__restrict out, const uint32_t bit) { + // Could have used function pointers instead of switch. + // Switch calls do offer the compiler more opportunities for optimization in + // theory. In this case, it makes no difference with a good compiler. + switch (bit) { + case 0: + internal::__fastunpack0(in, out); + break; + case 1: + internal::__fastunpack1(in, out); + break; + case 2: + internal::__fastunpack2(in, out); + break; + case 3: + internal::__fastunpack3(in, out); + break; + case 4: + internal::__fastunpack4(in, out); + break; + case 5: + internal::__fastunpack5(in, out); + break; + case 6: + internal::__fastunpack6(in, out); + break; + case 7: + internal::__fastunpack7(in, out); + break; + case 8: + internal::__fastunpack8(in, out); + break; + case 9: + internal::__fastunpack9(in, out); + break; + case 10: + internal::__fastunpack10(in, out); + break; + case 11: + internal::__fastunpack11(in, out); + break; + case 12: + internal::__fastunpack12(in, out); + break; + case 13: + internal::__fastunpack13(in, out); + break; + case 14: + internal::__fastunpack14(in, out); + break; + case 15: + internal::__fastunpack15(in, out); + break; + case 16: + internal::__fastunpack16(in, out); + break; + case 17: + internal::__fastunpack17(in, out); + break; + case 18: + internal::__fastunpack18(in, out); + break; + case 19: + internal::__fastunpack19(in, out); + break; + case 20: + internal::__fastunpack20(in, out); + break; + case 21: + internal::__fastunpack21(in, out); + break; + case 22: + internal::__fastunpack22(in, out); + break; + case 23: + internal::__fastunpack23(in, out); + break; + case 24: + internal::__fastunpack24(in, out); + break; + case 25: + internal::__fastunpack25(in, out); + break; + case 26: + internal::__fastunpack26(in, out); + break; + case 27: + internal::__fastunpack27(in, out); + break; + case 28: + internal::__fastunpack28(in, out); + break; + case 29: + internal::__fastunpack29(in, out); + break; + case 30: + internal::__fastunpack30(in, out); + break; + case 31: + internal::__fastunpack31(in, out); + break; + case 32: + internal::__fastunpack32(in, out); + break; + default: + throw std::logic_error("Invalid bit width for bitpacking"); + } +} + +inline void fastunpack(const uint32_t *__restrict in, + uint64_t *__restrict out, const uint32_t bit) { + // Could have used function pointers instead of switch. + // Switch calls do offer the compiler more opportunities for optimization in + // theory. In this case, it makes no difference with a good compiler. + switch (bit) { + case 0: + internal::__fastunpack0(in, out); + break; + case 1: + internal::__fastunpack1(in, out); + break; + case 2: + internal::__fastunpack2(in, out); + break; + case 3: + internal::__fastunpack3(in, out); + break; + case 4: + internal::__fastunpack4(in, out); + break; + case 5: + internal::__fastunpack5(in, out); + break; + case 6: + internal::__fastunpack6(in, out); + break; + case 7: + internal::__fastunpack7(in, out); + break; + case 8: + internal::__fastunpack8(in, out); + break; + case 9: + internal::__fastunpack9(in, out); + break; + case 10: + internal::__fastunpack10(in, out); + break; + case 11: + internal::__fastunpack11(in, out); + break; + case 12: + internal::__fastunpack12(in, out); + break; + case 13: + internal::__fastunpack13(in, out); + break; + case 14: + internal::__fastunpack14(in, out); + break; + case 15: + internal::__fastunpack15(in, out); + break; + case 16: + internal::__fastunpack16(in, out); + break; + case 17: + internal::__fastunpack17(in, out); + break; + case 18: + internal::__fastunpack18(in, out); + break; + case 19: + internal::__fastunpack19(in, out); + break; + case 20: + internal::__fastunpack20(in, out); + break; + case 21: + internal::__fastunpack21(in, out); + break; + case 22: + internal::__fastunpack22(in, out); + break; + case 23: + internal::__fastunpack23(in, out); + break; + case 24: + internal::__fastunpack24(in, out); + break; + case 25: + internal::__fastunpack25(in, out); + break; + case 26: + internal::__fastunpack26(in, out); + break; + case 27: + internal::__fastunpack27(in, out); + break; + case 28: + internal::__fastunpack28(in, out); + break; + case 29: + internal::__fastunpack29(in, out); + break; + case 30: + internal::__fastunpack30(in, out); + break; + case 31: + internal::__fastunpack31(in, out); + break; + case 32: + internal::__fastunpack32(in, out); + break; + case 33: + internal::__fastunpack33(in, out); + break; + case 34: + internal::__fastunpack34(in, out); + break; + case 35: + internal::__fastunpack35(in, out); + break; + case 36: + internal::__fastunpack36(in, out); + break; + case 37: + internal::__fastunpack37(in, out); + break; + case 38: + internal::__fastunpack38(in, out); + break; + case 39: + internal::__fastunpack39(in, out); + break; + case 40: + internal::__fastunpack40(in, out); + break; + case 41: + internal::__fastunpack41(in, out); + break; + case 42: + internal::__fastunpack42(in, out); + break; + case 43: + internal::__fastunpack43(in, out); + break; + case 44: + internal::__fastunpack44(in, out); + break; + case 45: + internal::__fastunpack45(in, out); + break; + case 46: + internal::__fastunpack46(in, out); + break; + case 47: + internal::__fastunpack47(in, out); + break; + case 48: + internal::__fastunpack48(in, out); + break; + case 49: + internal::__fastunpack49(in, out); + break; + case 50: + internal::__fastunpack50(in, out); + break; + case 51: + internal::__fastunpack51(in, out); + break; + case 52: + internal::__fastunpack52(in, out); + break; + case 53: + internal::__fastunpack53(in, out); + break; + case 54: + internal::__fastunpack54(in, out); + break; + case 55: + internal::__fastunpack55(in, out); + break; + case 56: + internal::__fastunpack56(in, out); + break; + case 57: + internal::__fastunpack57(in, out); + break; + case 58: + internal::__fastunpack58(in, out); + break; + case 59: + internal::__fastunpack59(in, out); + break; + case 60: + internal::__fastunpack60(in, out); + break; + case 61: + internal::__fastunpack61(in, out); + break; + case 62: + internal::__fastunpack62(in, out); + break; + case 63: + internal::__fastunpack63(in, out); + break; + case 64: + internal::__fastunpack64(in, out); + break; + default: + throw std::logic_error("Invalid bit width for bitpacking"); + } +} + +inline void fastpack(const uint8_t *__restrict in, uint8_t *__restrict out, const uint32_t bit) { + + for (uint8_t i = 0; i < 4; i++) { + internal::fastpack_quarter(in+(i*8), out + (i*bit), bit); + } +} + +inline void fastpack(const uint16_t *__restrict in, uint16_t *__restrict out, const uint32_t bit) { + internal::fastpack_half(in, out, bit); + internal::fastpack_half(in+16, out + bit, bit); +} + +inline void fastpack(const uint32_t *__restrict in, + uint32_t *__restrict out, const uint32_t bit) { + // Could have used function pointers instead of switch. + // Switch calls do offer the compiler more opportunities for optimization in + // theory. In this case, it makes no difference with a good compiler. + switch (bit) { + case 0: + internal::__fastpack0(in, out); + break; + case 1: + internal::__fastpack1(in, out); + break; + case 2: + internal::__fastpack2(in, out); + break; + case 3: + internal::__fastpack3(in, out); + break; + case 4: + internal::__fastpack4(in, out); + break; + case 5: + internal::__fastpack5(in, out); + break; + case 6: + internal::__fastpack6(in, out); + break; + case 7: + internal::__fastpack7(in, out); + break; + case 8: + internal::__fastpack8(in, out); + break; + case 9: + internal::__fastpack9(in, out); + break; + case 10: + internal::__fastpack10(in, out); + break; + case 11: + internal::__fastpack11(in, out); + break; + case 12: + internal::__fastpack12(in, out); + break; + case 13: + internal::__fastpack13(in, out); + break; + case 14: + internal::__fastpack14(in, out); + break; + case 15: + internal::__fastpack15(in, out); + break; + case 16: + internal::__fastpack16(in, out); + break; + case 17: + internal::__fastpack17(in, out); + break; + case 18: + internal::__fastpack18(in, out); + break; + case 19: + internal::__fastpack19(in, out); + break; + case 20: + internal::__fastpack20(in, out); + break; + case 21: + internal::__fastpack21(in, out); + break; + case 22: + internal::__fastpack22(in, out); + break; + case 23: + internal::__fastpack23(in, out); + break; + case 24: + internal::__fastpack24(in, out); + break; + case 25: + internal::__fastpack25(in, out); + break; + case 26: + internal::__fastpack26(in, out); + break; + case 27: + internal::__fastpack27(in, out); + break; + case 28: + internal::__fastpack28(in, out); + break; + case 29: + internal::__fastpack29(in, out); + break; + case 30: + internal::__fastpack30(in, out); + break; + case 31: + internal::__fastpack31(in, out); + break; + case 32: + internal::__fastpack32(in, out); + break; + default: + throw std::logic_error("Invalid bit width for bitpacking"); + } +} + +inline void fastpack(const uint64_t *__restrict in, + uint32_t *__restrict out, const uint32_t bit) { + switch (bit) { + case 0: + internal::__fastpack0(in, out); + break; + case 1: + internal::__fastpack1(in, out); + break; + case 2: + internal::__fastpack2(in, out); + break; + case 3: + internal::__fastpack3(in, out); + break; + case 4: + internal::__fastpack4(in, out); + break; + case 5: + internal::__fastpack5(in, out); + break; + case 6: + internal::__fastpack6(in, out); + break; + case 7: + internal::__fastpack7(in, out); + break; + case 8: + internal::__fastpack8(in, out); + break; + case 9: + internal::__fastpack9(in, out); + break; + case 10: + internal::__fastpack10(in, out); + break; + case 11: + internal::__fastpack11(in, out); + break; + case 12: + internal::__fastpack12(in, out); + break; + case 13: + internal::__fastpack13(in, out); + break; + case 14: + internal::__fastpack14(in, out); + break; + case 15: + internal::__fastpack15(in, out); + break; + case 16: + internal::__fastpack16(in, out); + break; + case 17: + internal::__fastpack17(in, out); + break; + case 18: + internal::__fastpack18(in, out); + break; + case 19: + internal::__fastpack19(in, out); + break; + case 20: + internal::__fastpack20(in, out); + break; + case 21: + internal::__fastpack21(in, out); + break; + case 22: + internal::__fastpack22(in, out); + break; + case 23: + internal::__fastpack23(in, out); + break; + case 24: + internal::__fastpack24(in, out); + break; + case 25: + internal::__fastpack25(in, out); + break; + case 26: + internal::__fastpack26(in, out); + break; + case 27: + internal::__fastpack27(in, out); + break; + case 28: + internal::__fastpack28(in, out); + break; + case 29: + internal::__fastpack29(in, out); + break; + case 30: + internal::__fastpack30(in, out); + break; + case 31: + internal::__fastpack31(in, out); + break; + case 32: + internal::__fastpack32(in, out); + break; + case 33: + internal::__fastpack33(in, out); + break; + case 34: + internal::__fastpack34(in, out); + break; + case 35: + internal::__fastpack35(in, out); + break; + case 36: + internal::__fastpack36(in, out); + break; + case 37: + internal::__fastpack37(in, out); + break; + case 38: + internal::__fastpack38(in, out); + break; + case 39: + internal::__fastpack39(in, out); + break; + case 40: + internal::__fastpack40(in, out); + break; + case 41: + internal::__fastpack41(in, out); + break; + case 42: + internal::__fastpack42(in, out); + break; + case 43: + internal::__fastpack43(in, out); + break; + case 44: + internal::__fastpack44(in, out); + break; + case 45: + internal::__fastpack45(in, out); + break; + case 46: + internal::__fastpack46(in, out); + break; + case 47: + internal::__fastpack47(in, out); + break; + case 48: + internal::__fastpack48(in, out); + break; + case 49: + internal::__fastpack49(in, out); + break; + case 50: + internal::__fastpack50(in, out); + break; + case 51: + internal::__fastpack51(in, out); + break; + case 52: + internal::__fastpack52(in, out); + break; + case 53: + internal::__fastpack53(in, out); + break; + case 54: + internal::__fastpack54(in, out); + break; + case 55: + internal::__fastpack55(in, out); + break; + case 56: + internal::__fastpack56(in, out); + break; + case 57: + internal::__fastpack57(in, out); + break; + case 58: + internal::__fastpack58(in, out); + break; + case 59: + internal::__fastpack59(in, out); + break; + case 60: + internal::__fastpack60(in, out); + break; + case 61: + internal::__fastpack61(in, out); + break; + case 62: + internal::__fastpack62(in, out); + break; + case 63: + internal::__fastpack63(in, out); + break; + case 64: + internal::__fastpack64(in, out); + break; + default: + throw std::logic_error("Invalid bit width for bitpacking"); + } +} +} // namespace fastpfor_lib + + +// LICENSE_CHANGE_END + + + + + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/storage/table/column_data_checkpointer.hpp +// +// +//===----------------------------------------------------------------------===// + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/storage/table/column_data.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/storage/table/column_checkpoint_state.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + + + +namespace duckdb { +class ColumnData; +class DatabaseInstance; +class RowGroup; +class TableDataWriter; + +struct ColumnCheckpointState { + ColumnCheckpointState(RowGroup &row_group, ColumnData &column_data, TableDataWriter &writer); + virtual ~ColumnCheckpointState(); + + RowGroup &row_group; + ColumnData &column_data; + TableDataWriter &writer; + SegmentTree new_tree; + vector data_pointers; + unique_ptr global_stats; + +public: + virtual unique_ptr GetStatistics() { + return global_stats->Copy(); + } + + virtual void FlushSegment(unique_ptr segment, idx_t segment_size); + virtual void FlushToDisk(); +}; + +} // namespace duckdb + + + +namespace duckdb { +class ColumnData; +class ColumnSegment; +class DatabaseInstance; +class RowGroup; +class TableDataWriter; +class Transaction; + +struct DataTableInfo; + +struct ColumnCheckpointInfo { + ColumnCheckpointInfo(CompressionType compression_type_p) : compression_type(compression_type_p) {}; + CompressionType compression_type; +}; + +class ColumnData { + friend class ColumnDataCheckpointer; + +public: + ColumnData(DataTableInfo &info, idx_t column_index, idx_t start_row, LogicalType type, ColumnData *parent); + virtual ~ColumnData(); + + //! Table info for the column + DataTableInfo &info; + //! The column index of the column, either within the parent table or within the parent + idx_t column_index; + //! The start row + idx_t start; + //! The type of the column + LogicalType type; + //! The parent column (if any) + ColumnData *parent; + +public: + virtual bool CheckZonemap(ColumnScanState &state, TableFilter &filter) = 0; + + DatabaseInstance &GetDatabase() const; + DataTableInfo &GetTableInfo() const; + virtual idx_t GetMaxEntry(); + + //! The root type of the column + const LogicalType &RootType() const; + + //! Initialize a scan of the column + virtual void InitializeScan(ColumnScanState &state); + //! Initialize a scan starting at the specified offset + virtual void InitializeScanWithOffset(ColumnScanState &state, idx_t row_idx); + //! Scan the next vector from the column + virtual idx_t Scan(Transaction &transaction, idx_t vector_index, ColumnScanState &state, Vector &result); + virtual idx_t ScanCommitted(idx_t vector_index, ColumnScanState &state, Vector &result, bool allow_updates); + virtual void ScanCommittedRange(idx_t row_group_start, idx_t offset_in_row_group, idx_t count, Vector &result); + virtual idx_t ScanCount(ColumnScanState &state, Vector &result, idx_t count); + //! Select + virtual void Select(Transaction &transaction, idx_t vector_index, ColumnScanState &state, Vector &result, + SelectionVector &sel, idx_t &count, const TableFilter &filter); + virtual void FilterScan(Transaction &transaction, idx_t vector_index, ColumnScanState &state, Vector &result, + SelectionVector &sel, idx_t count); + virtual void FilterScanCommitted(idx_t vector_index, ColumnScanState &state, Vector &result, SelectionVector &sel, + idx_t count, bool allow_updates); + + //! Skip the scan forward by "count" rows + virtual void Skip(ColumnScanState &state, idx_t count = STANDARD_VECTOR_SIZE); + + //! Initialize an appending phase for this column + virtual void InitializeAppend(ColumnAppendState &state); + //! Append a vector of type [type] to the end of the column + virtual void Append(BaseStatistics &stats, ColumnAppendState &state, Vector &vector, idx_t count); + virtual void AppendData(BaseStatistics &stats, ColumnAppendState &state, VectorData &vdata, idx_t count); + //! Revert a set of appends to the ColumnData + virtual void RevertAppend(row_t start_row); + + //! Fetch the vector from the column data that belongs to this specific row + virtual idx_t Fetch(ColumnScanState &state, row_t row_id, Vector &result); + //! Fetch a specific row id and append it to the vector + virtual void FetchRow(Transaction &transaction, ColumnFetchState &state, row_t row_id, Vector &result, + idx_t result_idx); + + virtual void Update(Transaction &transaction, idx_t column_index, Vector &update_vector, row_t *row_ids, + idx_t update_count); + virtual void UpdateColumn(Transaction &transaction, const vector &column_path, Vector &update_vector, + row_t *row_ids, idx_t update_count, idx_t depth); + virtual unique_ptr GetUpdateStatistics(); + + virtual void CommitDropColumn(); + + virtual unique_ptr CreateCheckpointState(RowGroup &row_group, TableDataWriter &writer); + virtual unique_ptr Checkpoint(RowGroup &row_group, TableDataWriter &writer, + ColumnCheckpointInfo &checkpoint_info); + + virtual void CheckpointScan(ColumnSegment *segment, ColumnScanState &state, idx_t row_group_start, idx_t count, + Vector &scan_vector); + + virtual void DeserializeColumn(Deserializer &source); + static shared_ptr Deserialize(DataTableInfo &info, idx_t column_index, 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 Verify(RowGroup &parent); + + static shared_ptr CreateColumn(DataTableInfo &info, idx_t column_index, idx_t start_row, + const LogicalType &type, ColumnData *parent = nullptr); + static unique_ptr CreateColumnUnique(DataTableInfo &info, idx_t column_index, idx_t start_row, + const LogicalType &type, ColumnData *parent = nullptr); + +protected: + //! Append a transient segment + void AppendTransientSegment(idx_t start_row); + + //! Scans a base vector from the column + idx_t ScanVector(ColumnScanState &state, Vector &result, idx_t remaining); + //! Scans a vector from the column merged with any potential updates + //! If ALLOW_UPDATES is set to false, the function will instead throw an exception if any updates are found + template + idx_t ScanVector(Transaction *transaction, idx_t vector_index, ColumnScanState &state, Vector &result); + +protected: + //! The segments holding the data of this column segment + SegmentTree data; + //! The lock for the updates + mutex update_lock; + //! The updates for this column segment + unique_ptr updates; +}; + +} // namespace duckdb + + + +namespace duckdb { + +class ColumnDataCheckpointer { +public: + ColumnDataCheckpointer(ColumnData &col_data_p, RowGroup &row_group_p, ColumnCheckpointState &state_p, + ColumnCheckpointInfo &checkpoint_info); + +public: + DatabaseInstance &GetDatabase(); + const LogicalType &GetType() const; + ColumnData &GetColumnData(); + RowGroup &GetRowGroup(); + ColumnCheckpointState &GetCheckpointState(); + + void Checkpoint(unique_ptr segment); + +private: + void ScanSegments(const std::function &callback); + unique_ptr DetectBestCompressionMethod(idx_t &compression_idx); + void WriteToDisk(); + bool HasChanges(); + void WritePersistentSegments(); + +private: + ColumnData &col_data; + RowGroup &row_group; + ColumnCheckpointState &state; + bool is_validity; + Vector intermediate; + unique_ptr owned_segment; + vector compression_functions; + ColumnCheckpointInfo &checkpoint_info; +}; + +} // namespace duckdb + + + +#include + +namespace duckdb { + +using bitpacking_width_t = uint8_t; + +// 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_WIDTH_GROUP_SIZE = 1024; + +class BitpackingPrimitives { +public: + static constexpr const idx_t BITPACKING_ALGORITHM_GROUP_SIZE = 32; + static constexpr const idx_t BITPACKING_HEADER_SIZE = sizeof(uint64_t); + static constexpr const bool BYTE_ALIGNED = false; + + // Packs a block of BITPACKING_ALGORITHM_GROUP_SIZE values + template + inline static void PackBlock(data_ptr_t dst, T *src, bitpacking_width_t width) { + return PackGroup(dst, src, width); + } + + // Unpacks a block of BITPACKING_ALGORITHM_GROUP_SIZE values + template + inline static void UnPackBlock(data_ptr_t dst, data_ptr_t src, bitpacking_width_t width, + bool skip_sign_extension = false) { + return UnPackGroup(dst, src, width, skip_sign_extension); + } + + // Calculates the minimum required number of bits per value that can store all values + template + inline static bitpacking_width_t MinimumBitWidth(T *values, idx_t count) { + return FindMinimumBitWidth(values, count); + } + +private: + template + static bitpacking_width_t MinimumBitWidth(T min_value, T max_value) { + bitpacking_width_t required_bits; + + if (std::is_signed::value) { + if (min_value == NumericLimits::Minimum()) { + // handle special case of the minimal value, as it cannot be negated like all other values. + return sizeof(T) * 8; + } else { + max_value = MaxValue((T)-min_value, max_value); + } + } + + if (max_value == 0) { + return 0; + } + + if (std::is_signed::value) { + required_bits = 1; + } else { + required_bits = 0; + } + + while (max_value) { + required_bits++; + max_value >>= 1; + } + + return GetEffectiveWidth(required_bits); + } + + template + static bitpacking_width_t FindMinimumBitWidth(T *values, idx_t count) { + T min_value = values[0]; + T max_value = values[0]; + + for (idx_t i = 1; i < count; i++) { + if (values[i] > max_value) { + max_value = values[i]; + } + + if (std::is_signed::value) { + if (values[i] < min_value) { + min_value = values[i]; + } + } + } + + bitpacking_width_t calc_width = MinimumBitWidth(std::is_signed::value ? min_value : 0, max_value); + + // Assert results are correct +#ifdef DEBUG + if (calc_width < sizeof(T) * 8 && calc_width != 0) { + if (std::is_signed::value) { + D_ASSERT((int64_t)max_value <= (int64_t)(1L << (calc_width - 1)) - 1); + D_ASSERT((int64_t)min_value >= (int64_t)(-1 * ((1L << (calc_width - 1)) - 1) - 1)); + } else { + D_ASSERT((uint64_t)max_value <= (uint64_t)(1L << (calc_width)) - 1); + } + } +#endif + if (round_to_next_byte) { + return (calc_width / 8 + (calc_width % 8 != 0)) * 8; + } else { + return calc_width; + } + } + + template + static void UnPackGroup(data_ptr_t dst, data_ptr_t src, bitpacking_width_t width, + bool skip_sign_extension = false) { + if (std::is_same::value || std::is_same::value) { + duckdb_fastpforlib::fastunpack((const uint8_t *)src, (uint8_t *)dst, (uint32_t)width); + } else if (std::is_same::value || std::is_same::value) { + duckdb_fastpforlib::fastunpack((const uint16_t *)src, (uint16_t *)dst, (uint32_t)width); + } else if (std::is_same::value || std::is_same::value) { + duckdb_fastpforlib::fastunpack((const uint32_t *)src, (uint32_t *)dst, (uint32_t)width); + } else if (std::is_same::value || std::is_same::value) { + duckdb_fastpforlib::fastunpack((const uint32_t *)src, (uint64_t *)dst, (uint32_t)width); + } else { + throw InternalException("Unsupported type found in bitpacking."); + } + + if (NumericLimits::IsSigned() && !skip_sign_extension && width > 0 && width < sizeof(T) * 8) { + SignExtend(dst, width); + } + } + + // Prevent compression at widths that are ineffective + template + static bitpacking_width_t GetEffectiveWidth(bitpacking_width_t width) { + if (width > 56) { + return 64; + } + + if (width > 28 && (std::is_same::value || std::is_same::value)) { + return 32; + } + + else if (width > 14 && (std::is_same::value || std::is_same::value)) { + return 16; + } + + return width; + } + + // Sign bit extension + template ::type> + static void SignExtend(data_ptr_t dst, bitpacking_width_t width) { + T const mask = ((T_U)1) << (width - 1); + for (idx_t i = 0; i < BitpackingPrimitives::BITPACKING_ALGORITHM_GROUP_SIZE; ++i) { + T value = Load(dst + i * sizeof(T)); + value = value & ((((T_U)1) << width) - ((T_U)1)); + T result = (value ^ mask) - mask; + Store(result, dst + i * sizeof(T)); + } + } + + template + static void PackGroup(data_ptr_t dst, T *values, bitpacking_width_t width) { + if (std::is_same::value || std::is_same::value) { + duckdb_fastpforlib::fastpack((const uint8_t *)values, (uint8_t *)dst, (uint32_t)width); + } else if (std::is_same::value || std::is_same::value) { + duckdb_fastpforlib::fastpack((const uint16_t *)values, (uint16_t *)dst, (uint32_t)width); + } else if (std::is_same::value || std::is_same::value) { + duckdb_fastpforlib::fastpack((const uint32_t *)values, (uint32_t *)dst, (uint32_t)width); + } else if (std::is_same::value || std::is_same::value) { + duckdb_fastpforlib::fastpack((const uint64_t *)values, (uint32_t *)dst, (uint32_t)width); + } else { + throw InternalException("Unsupported type found in bitpacking."); + } + } +}; + +struct EmptyBitpackingWriter { + template + static void Operation(T *values, bool *validity, bitpacking_width_t width, idx_t count, void *data_ptr) { + } +}; + +template +struct BitpackingState { +public: + BitpackingState() : compression_buffer_idx(0), total_size(0), data_ptr(nullptr) { + } + + T compression_buffer[BITPACKING_WIDTH_GROUP_SIZE]; + bool compression_buffer_validity[BITPACKING_WIDTH_GROUP_SIZE]; + idx_t compression_buffer_idx; + idx_t total_size; + void *data_ptr; + +public: + template + void Flush() { + bitpacking_width_t width = BitpackingPrimitives::MinimumBitWidth(compression_buffer, compression_buffer_idx); + OP::Operation(compression_buffer, compression_buffer_validity, width, compression_buffer_idx, data_ptr); + total_size += (BITPACKING_WIDTH_GROUP_SIZE * width) / 8 + sizeof(bitpacking_width_t); + compression_buffer_idx = 0; + } + + template + void Update(T *data, ValidityMask &validity, idx_t idx) { + + if (validity.RowIsValid(idx)) { + compression_buffer_validity[compression_buffer_idx] = true; + compression_buffer[compression_buffer_idx++] = data[idx]; + } 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 (compression_buffer_idx == BITPACKING_WIDTH_GROUP_SIZE) { + // Calculate bitpacking width; + Flush(); + } + } +}; + +//===--------------------------------------------------------------------===// +// Analyze +//===--------------------------------------------------------------------===// +template +struct BitpackingAnalyzeState : public AnalyzeState { + BitpackingState state; +}; + +template +unique_ptr BitpackingInitAnalyze(ColumnData &col_data, PhysicalType type) { + return make_unique>(); +} + +template +bool BitpackingAnalyze(AnalyzeState &state, Vector &input, idx_t count) { + auto &analyze_state = (BitpackingAnalyzeState &)state; + VectorData vdata; + input.Orrify(count, vdata); + + auto data = (T *)vdata.data; + for (idx_t i = 0; i < count; i++) { + auto idx = vdata.sel->get_index(i); + analyze_state.state.template Update(data, vdata.validity, idx); + } + + return true; +} + +template +idx_t BitpackingFinalAnalyze(AnalyzeState &state) { + auto &bitpacking_state = (BitpackingAnalyzeState &)state; + bitpacking_state.state.template Flush(); + return bitpacking_state.state.total_size; +} + +//===--------------------------------------------------------------------===// +// Compress +//===--------------------------------------------------------------------===// +template +struct BitpackingCompressState : public CompressionState { +public: + explicit BitpackingCompressState(ColumnDataCheckpointer &checkpointer) : checkpointer(checkpointer) { + auto &db = checkpointer.GetDatabase(); + auto &type = checkpointer.GetType(); + auto &config = DBConfig::GetConfig(db); + function = config.GetCompressionFunction(CompressionType::COMPRESSION_BITPACKING, type.InternalType()); + CreateEmptySegment(checkpointer.GetRowGroup().start); + + state.data_ptr = (void *)this; + } + + ColumnDataCheckpointer &checkpointer; + CompressionFunction *function; + unique_ptr current_segment; + unique_ptr handle; + + // Ptr to next free spot in segment; + data_ptr_t data_ptr; + // Ptr to next free spot for storing bitwidths (growing downwards). + data_ptr_t width_ptr; + + BitpackingState state; + +public: + struct BitpackingWriter { + template + static void Operation(VALUE_TYPE *values, bool *validity, bitpacking_width_t width, idx_t count, + void *data_ptr) { + auto state = (BitpackingCompressState *)data_ptr; + + if (state->RemainingSize() < (width * BITPACKING_WIDTH_GROUP_SIZE) / 8 + sizeof(bitpacking_width_t)) { + // 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]); + } + } + + state->WriteValues(values, width, count); + } + }; + + // Space remaining between the width_ptr growing down and data ptr growing up + idx_t RemainingSize() { + return width_ptr - data_ptr; + } + + void CreateEmptySegment(idx_t row_start) { + auto &db = checkpointer.GetDatabase(); + auto &type = checkpointer.GetType(); + auto compressed_segment = ColumnSegment::CreateTransientSegment(db, type, row_start); + compressed_segment->function = function; + current_segment = move(compressed_segment); + auto &buffer_manager = BufferManager::GetBufferManager(db); + handle = buffer_manager.Pin(current_segment->block); + + data_ptr = handle->Ptr() + current_segment->GetBlockOffset() + BitpackingPrimitives::BITPACKING_HEADER_SIZE; + width_ptr = + handle->Ptr() + current_segment->GetBlockOffset() + Storage::BLOCK_SIZE - sizeof(bitpacking_width_t); + } + + void Append(VectorData &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); + } + } + + void WriteValues(T *values, bitpacking_width_t width, idx_t count) { + // TODO we can optimize this by stopping early if count < BITPACKING_WIDTH_GROUP_SIZE + idx_t compress_loops = BITPACKING_WIDTH_GROUP_SIZE / BitpackingPrimitives::BITPACKING_ALGORITHM_GROUP_SIZE; + for (idx_t i = 0; i < compress_loops; i++) { + BitpackingPrimitives::PackBlock( + data_ptr, &values[i * BitpackingPrimitives::BITPACKING_ALGORITHM_GROUP_SIZE], width); + data_ptr += (BitpackingPrimitives::BITPACKING_ALGORITHM_GROUP_SIZE * width) / 8; + } + + Store(width, width_ptr); + width_ptr -= sizeof(bitpacking_width_t); + + current_segment->count += count; + } + + void FlushSegment() { + auto &state = checkpointer.GetCheckpointState(); + + // Compact the segment by moving the widths next to the data. + idx_t minimal_widths_offset = AlignValue(data_ptr - handle->node->buffer); + idx_t widths_size = handle->node->buffer + Storage::BLOCK_SIZE - width_ptr - 1; + idx_t total_segment_size = minimal_widths_offset + widths_size; + memmove(handle->node->buffer + minimal_widths_offset, width_ptr + 1, widths_size); + + // Store the offset of the first width (which is at the highest address). + Store(minimal_widths_offset + widths_size - 1, handle->node->buffer); + handle.reset(); + + state.FlushSegment(move(current_segment), total_segment_size); + } + + void Finalize() { + state.template Flush::BitpackingWriter>(); + FlushSegment(); + current_segment.reset(); + } +}; + +template +unique_ptr BitpackingInitCompression(ColumnDataCheckpointer &checkpointer, + unique_ptr state) { + return make_unique>(checkpointer); +} + +template +void BitpackingCompress(CompressionState &state_p, Vector &scan_vector, idx_t count) { + auto &state = (BitpackingCompressState &)state_p; + VectorData vdata; + scan_vector.Orrify(count, vdata); + state.Append(vdata, count); +} + +template +void BitpackingFinalizeCompress(CompressionState &state_p) { + auto &state = (BitpackingCompressState &)state_p; + state.Finalize(); +} + +//===--------------------------------------------------------------------===// +// Scan +//===--------------------------------------------------------------------===// +template +struct BitpackingScanState : public SegmentScanState { +public: + explicit BitpackingScanState(ColumnSegment &segment) { + auto &buffer_manager = BufferManager::GetBufferManager(segment.db); + handle = buffer_manager.Pin(segment.block); + + current_width_group_ptr = + handle->node->buffer + segment.GetBlockOffset() + BitpackingPrimitives::BITPACKING_HEADER_SIZE; + + // load offset to bitpacking widths pointer + auto bitpacking_widths_offset = Load(handle->node->buffer + segment.GetBlockOffset()); + bitpacking_width_ptr = handle->node->buffer + segment.GetBlockOffset() + bitpacking_widths_offset; + + // load the bitwidth of the first vector + LoadCurrentBitWidth(); + } + + unique_ptr handle; + + void (*decompress_function)(data_ptr_t, data_ptr_t, bitpacking_width_t, bool skip_sign_extension); + T decompression_buffer[BitpackingPrimitives::BITPACKING_ALGORITHM_GROUP_SIZE]; + + idx_t position_in_group = 0; + data_ptr_t current_width_group_ptr; + data_ptr_t bitpacking_width_ptr; + bitpacking_width_t current_width; + +public: + void LoadCurrentBitWidth() { + D_ASSERT(bitpacking_width_ptr > handle->node->buffer && + bitpacking_width_ptr < handle->node->buffer + Storage::BLOCK_SIZE); + current_width = Load(bitpacking_width_ptr); + LoadDecompressFunction(); + } + + void Skip(ColumnSegment &segment, idx_t skip_count) { + while (skip_count > 0) { + if (position_in_group + skip_count < BITPACKING_WIDTH_GROUP_SIZE) { + // We're not leaving this bitpacking group, we can perform all skips. + position_in_group += skip_count; + break; + } else { + // The skip crosses the current bitpacking group, we skip the remainder of this group. + auto skipping = BITPACKING_WIDTH_GROUP_SIZE - position_in_group; + position_in_group = 0; + current_width_group_ptr += (current_width * BITPACKING_WIDTH_GROUP_SIZE) / 8; + + // Update width pointer and load new width + bitpacking_width_ptr -= sizeof(bitpacking_width_t); + LoadCurrentBitWidth(); + + skip_count -= skipping; + } + } + } + + void LoadDecompressFunction() { + decompress_function = &BitpackingPrimitives::UnPackBlock; + } +}; + +template +unique_ptr BitpackingInitScan(ColumnSegment &segment) { + auto result = make_unique>(segment); + return move(result); +} + +//===--------------------------------------------------------------------===// +// Scan base data +//===--------------------------------------------------------------------===// +template +void BitpackingScanPartial(ColumnSegment &segment, ColumnScanState &state, idx_t scan_count, Vector &result, + idx_t result_offset) { + auto &scan_state = (BitpackingScanState &)*state.scan_state; + + 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_WIDTH_GROUP_SIZE) { + if (scan_state.current_width == sizeof(T) * 8 && scan_count <= BITPACKING_WIDTH_GROUP_SIZE && + scan_state.position_in_group == 0) { + + memcpy(result_data + result_offset, scan_state.current_width_group_ptr, scan_count * sizeof(T)); + scan_state.current_width_group_ptr += scan_count * sizeof(T); + scan_state.bitpacking_width_ptr -= sizeof(bitpacking_width_t); + scan_state.LoadCurrentBitWidth(); + return; + } + } + + // Determine if we can skip sign extension during compression + auto &nstats = (NumericStatistics &)*segment.stats.statistics; + bool skip_sign_extend = std::is_signed::value && nstats.min >= 0; + + idx_t scanned = 0; + + while (scanned < scan_count) { + // Exhausted this width group, move pointers to next group and load bitwidth for next group. + if (scan_state.position_in_group >= BITPACKING_WIDTH_GROUP_SIZE) { + scan_state.position_in_group = 0; + scan_state.bitpacking_width_ptr -= sizeof(bitpacking_width_t); + scan_state.current_width_group_ptr += (scan_state.current_width * BITPACKING_WIDTH_GROUP_SIZE) / 8; + scan_state.LoadCurrentBitWidth(); + } + + idx_t offset_in_compression_group = + scan_state.position_in_group % BitpackingPrimitives::BITPACKING_ALGORITHM_GROUP_SIZE; + + 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_width_group_ptr + scan_state.position_in_group * scan_state.current_width / 8; + data_ptr_t decompression_group_start_pointer = + current_position_ptr - offset_in_compression_group * scan_state.current_width / 8; + + T *current_result_ptr = result_data + result_offset + scanned; + + if (to_scan == BitpackingPrimitives::BITPACKING_ALGORITHM_GROUP_SIZE && offset_in_compression_group == 0) { + // Decompress directly into result vector + scan_state.decompress_function((data_ptr_t)current_result_ptr, decompression_group_start_pointer, + scan_state.current_width, skip_sign_extend); + } else { + // Decompress compression algorithm to buffer + scan_state.decompress_function((data_ptr_t)scan_state.decompression_buffer, + decompression_group_start_pointer, scan_state.current_width, + skip_sign_extend); + + memcpy(current_result_ptr, scan_state.decompression_buffer + offset_in_compression_group, + to_scan * sizeof(T)); + } + + scanned += to_scan; + scan_state.position_in_group += to_scan; + } +} + +template +void BitpackingScan(ColumnSegment &segment, ColumnScanState &state, idx_t scan_count, Vector &result) { + BitpackingScanPartial(segment, state, scan_count, result, 0); +} + +//===--------------------------------------------------------------------===// +// Fetch +//===--------------------------------------------------------------------===// +template +void BitpackingFetchRow(ColumnSegment &segment, ColumnFetchState &state, row_t row_id, Vector &result, + idx_t result_idx) { + BitpackingScanState scan_state(segment); + scan_state.Skip(segment, row_id); + 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; + + data_ptr_t decompression_group_start_pointer = + scan_state.current_width_group_ptr + + (scan_state.position_in_group - offset_in_compression_group) * scan_state.current_width / 8; + + auto &nstats = (NumericStatistics &)*segment.stats.statistics; + bool skip_sign_extend = std::is_signed::value && nstats.min >= 0; + + scan_state.decompress_function((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); +} +template +void BitpackingSkip(ColumnSegment &segment, ColumnScanState &state, idx_t skip_count) { + auto &scan_state = (BitpackingScanState &)*state.scan_state; + scan_state.Skip(segment, skip_count); +} + +//===--------------------------------------------------------------------===// +// Get Function +//===--------------------------------------------------------------------===// +template +CompressionFunction GetBitpackingFunction(PhysicalType data_type) { + return CompressionFunction(CompressionType::COMPRESSION_BITPACKING, data_type, BitpackingInitAnalyze, + BitpackingAnalyze, BitpackingFinalAnalyze, BitpackingInitCompression, + BitpackingCompress, BitpackingFinalizeCompress, BitpackingInitScan, + BitpackingScan, BitpackingScanPartial, BitpackingFetchRow, BitpackingSkip); +} + +CompressionFunction BitpackingFun::GetFunction(PhysicalType type) { + switch (type) { + case PhysicalType::BOOL: + case PhysicalType::INT8: + return GetBitpackingFunction(type); + case PhysicalType::INT16: + return GetBitpackingFunction(type); + case PhysicalType::INT32: + return GetBitpackingFunction(type); + case PhysicalType::INT64: + return GetBitpackingFunction(type); + case PhysicalType::UINT8: + return GetBitpackingFunction(type); + case PhysicalType::UINT16: + return GetBitpackingFunction(type); + case PhysicalType::UINT32: + return GetBitpackingFunction(type); + case PhysicalType::UINT64: + return GetBitpackingFunction(type); + default: + throw InternalException("Unsupported type for Bitpacking"); + } +} + +bool BitpackingFun::TypeIsSupported(PhysicalType type) { + switch (type) { + case PhysicalType::BOOL: + case PhysicalType::INT8: + case PhysicalType::INT16: + case PhysicalType::INT32: + case PhysicalType::INT64: + case PhysicalType::UINT8: + case PhysicalType::UINT16: + case PhysicalType::UINT32: + case PhysicalType::UINT64: + return true; + default: + return false; + } +} + } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB @@ -148024,242 +162249,6 @@ struct StringUncompressed { -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/storage/table/column_data_checkpointer.hpp -// -// -//===----------------------------------------------------------------------===// - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/storage/table/column_data.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - - - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/storage/table/column_checkpoint_state.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - - - - -namespace duckdb { -class ColumnData; -class DatabaseInstance; -class RowGroup; -class TableDataWriter; - -struct ColumnCheckpointState { - ColumnCheckpointState(RowGroup &row_group, ColumnData &column_data, TableDataWriter &writer); - virtual ~ColumnCheckpointState(); - - RowGroup &row_group; - ColumnData &column_data; - TableDataWriter &writer; - SegmentTree new_tree; - vector data_pointers; - unique_ptr global_stats; - -public: - virtual unique_ptr GetStatistics() { - return global_stats->Copy(); - } - - virtual void FlushSegment(unique_ptr segment, idx_t segment_size); - virtual void FlushToDisk(); -}; - -} // namespace duckdb - - - -namespace duckdb { -class ColumnData; -class ColumnSegment; -class DatabaseInstance; -class RowGroup; -class TableDataWriter; -class Transaction; - -struct DataTableInfo; - -struct ColumnCheckpointInfo { - ColumnCheckpointInfo(CompressionType compression_type_p) : compression_type(compression_type_p) {}; - CompressionType compression_type; -}; - -class ColumnData { - friend class ColumnDataCheckpointer; - -public: - ColumnData(DataTableInfo &info, idx_t column_index, idx_t start_row, LogicalType type, ColumnData *parent); - virtual ~ColumnData(); - - //! Table info for the column - DataTableInfo &info; - //! The column index of the column, either within the parent table or within the parent - idx_t column_index; - //! The start row - idx_t start; - //! The type of the column - LogicalType type; - //! The parent column (if any) - ColumnData *parent; - -public: - virtual bool CheckZonemap(ColumnScanState &state, TableFilter &filter) = 0; - - DatabaseInstance &GetDatabase() const; - DataTableInfo &GetTableInfo() const; - virtual idx_t GetMaxEntry(); - - //! The root type of the column - const LogicalType &RootType() const; - - //! Initialize a scan of the column - virtual void InitializeScan(ColumnScanState &state); - //! Initialize a scan starting at the specified offset - virtual void InitializeScanWithOffset(ColumnScanState &state, idx_t row_idx); - //! Scan the next vector from the column - virtual idx_t Scan(Transaction &transaction, idx_t vector_index, ColumnScanState &state, Vector &result); - virtual idx_t ScanCommitted(idx_t vector_index, ColumnScanState &state, Vector &result, bool allow_updates); - virtual void ScanCommittedRange(idx_t row_group_start, idx_t offset_in_row_group, idx_t count, Vector &result); - virtual idx_t ScanCount(ColumnScanState &state, Vector &result, idx_t count); - //! Select - virtual void Select(Transaction &transaction, idx_t vector_index, ColumnScanState &state, Vector &result, - SelectionVector &sel, idx_t &count, const TableFilter &filter); - virtual void FilterScan(Transaction &transaction, idx_t vector_index, ColumnScanState &state, Vector &result, - SelectionVector &sel, idx_t count); - virtual void FilterScanCommitted(idx_t vector_index, ColumnScanState &state, Vector &result, SelectionVector &sel, - idx_t count, bool allow_updates); - - //! Skip the scan forward by "count" rows - virtual void Skip(ColumnScanState &state, idx_t count = STANDARD_VECTOR_SIZE); - - //! Initialize an appending phase for this column - virtual void InitializeAppend(ColumnAppendState &state); - //! Append a vector of type [type] to the end of the column - virtual void Append(BaseStatistics &stats, ColumnAppendState &state, Vector &vector, idx_t count); - virtual void AppendData(BaseStatistics &stats, ColumnAppendState &state, VectorData &vdata, idx_t count); - //! Revert a set of appends to the ColumnData - virtual void RevertAppend(row_t start_row); - - //! Fetch the vector from the column data that belongs to this specific row - virtual idx_t Fetch(ColumnScanState &state, row_t row_id, Vector &result); - //! Fetch a specific row id and append it to the vector - virtual void FetchRow(Transaction &transaction, ColumnFetchState &state, row_t row_id, Vector &result, - idx_t result_idx); - - virtual void Update(Transaction &transaction, idx_t column_index, Vector &update_vector, row_t *row_ids, - idx_t offset, idx_t update_count); - virtual void UpdateColumn(Transaction &transaction, const vector &column_path, Vector &update_vector, - row_t *row_ids, idx_t update_count, idx_t depth); - virtual unique_ptr GetUpdateStatistics(); - - virtual void CommitDropColumn(); - - virtual unique_ptr CreateCheckpointState(RowGroup &row_group, TableDataWriter &writer); - virtual unique_ptr Checkpoint(RowGroup &row_group, TableDataWriter &writer, - ColumnCheckpointInfo &checkpoint_info); - - virtual void CheckpointScan(ColumnSegment *segment, ColumnScanState &state, idx_t row_group_start, idx_t count, - Vector &scan_vector); - - virtual void DeserializeColumn(Deserializer &source); - static shared_ptr Deserialize(DataTableInfo &info, idx_t column_index, 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 Verify(RowGroup &parent); - - static shared_ptr CreateColumn(DataTableInfo &info, idx_t column_index, idx_t start_row, - const LogicalType &type, ColumnData *parent = nullptr); - static unique_ptr CreateColumnUnique(DataTableInfo &info, idx_t column_index, idx_t start_row, - const LogicalType &type, ColumnData *parent = nullptr); - -protected: - //! Append a transient segment - void AppendTransientSegment(idx_t start_row); - - //! Scans a base vector from the column - idx_t ScanVector(ColumnScanState &state, Vector &result, idx_t remaining); - //! Scans a vector from the column merged with any potential updates - //! If ALLOW_UPDATES is set to false, the function will instead throw an exception if any updates are found - template - idx_t ScanVector(Transaction *transaction, idx_t vector_index, ColumnScanState &state, Vector &result); - -protected: - //! The segments holding the data of this column segment - SegmentTree data; - //! The lock for the updates - mutex update_lock; - //! The updates for this column segment - unique_ptr updates; -}; - -} // namespace duckdb - - - -namespace duckdb { - -class ColumnDataCheckpointer { -public: - ColumnDataCheckpointer(ColumnData &col_data_p, RowGroup &row_group_p, ColumnCheckpointState &state_p, - ColumnCheckpointInfo &checkpoint_info); - -public: - DatabaseInstance &GetDatabase(); - const LogicalType &GetType() const; - ColumnData &GetColumnData(); - RowGroup &GetRowGroup(); - ColumnCheckpointState &GetCheckpointState(); - - void Checkpoint(unique_ptr segment); - -private: - void ScanSegments(const std::function &callback); - unique_ptr DetectBestCompressionMethod(idx_t &compression_idx); - void WriteToDisk(); - bool HasChanges(); - void WritePersistentSegments(); - -private: - ColumnData &col_data; - RowGroup &row_group; - ColumnCheckpointState &state; - bool is_validity; - Vector intermediate; - unique_ptr owned_segment; - vector compression_functions; - ColumnCheckpointInfo &checkpoint_info; -}; - -} // namespace duckdb namespace duckdb { @@ -150189,7 +164178,7 @@ class StandardColumnData : public ColumnData { idx_t Fetch(ColumnScanState &state, row_t row_id, Vector &result) override; void FetchRow(Transaction &transaction, ColumnFetchState &state, row_t row_id, Vector &result, idx_t result_idx) override; - void Update(Transaction &transaction, idx_t column_index, Vector &update_vector, row_t *row_ids, idx_t offset, + void Update(Transaction &transaction, idx_t column_index, Vector &update_vector, row_t *row_ids, idx_t update_count) override; void UpdateColumn(Transaction &transaction, const vector &column_path, Vector &update_vector, row_t *row_ids, idx_t update_count, idx_t depth) override; @@ -150394,7 +164383,7 @@ DataTable::DataTable(ClientContext &context, DataTable &parent, idx_t changed_id vector scan_types; for (idx_t i = 0; i < bound_columns.size(); i++) { if (bound_columns[i] == COLUMN_IDENTIFIER_ROW_ID) { - scan_types.push_back(LOGICAL_ROW_TYPE); + scan_types.emplace_back(LogicalType::ROW_TYPE); } else { scan_types.push_back(parent.column_definitions[bound_columns[i]].type); } @@ -150488,7 +164477,7 @@ bool DataTable::InitializeScanInRowGroup(TableScanState &state, const vectorstart + MinValue(state.current_row_group->count, @@ -150523,7 +164512,7 @@ bool DataTable::NextParallelScan(ClientContext &context, ParallelTableScanState max_row = MinValue(max_row, state.max_row); bool need_to_scan = InitializeScanInRowGroup(scan_state, column_ids, scan_state.table_filters, state.current_row_group, vector_index, max_row); - if (context.verify_parallelism) { + if (ClientConfig::GetConfig(context).verify_parallelism) { state.vector_index++; if (state.vector_index * STANDARD_VECTOR_SIZE >= state.current_row_group->count) { state.current_row_group = (RowGroup *)state.current_row_group->next.get(); @@ -150861,7 +164850,7 @@ void DataTable::RevertAppend(idx_t start_row, idx_t count) { if (!info->indexes.Empty()) { idx_t current_row_base = start_row; row_t row_data[STANDARD_VECTOR_SIZE]; - Vector row_identifiers(LOGICAL_ROW_TYPE, (data_ptr_t)row_data); + Vector row_identifiers(LogicalType::ROW_TYPE, (data_ptr_t)row_data); ScanTableSegment(start_row, count, [&](DataChunk &chunk) { for (idx_t i = 0; i < chunk.size(); i++) { row_data[i] = current_row_base + i; @@ -150885,7 +164874,7 @@ bool DataTable::AppendToIndexes(TableAppendState &state, DataChunk &chunk, row_t return true; } // first generate the vector of row identifiers - Vector row_identifiers(LOGICAL_ROW_TYPE); + Vector row_identifiers(LogicalType::ROW_TYPE); VectorOperations::GenerateSequence(row_identifiers, chunk.size(), row_start, 1); vector already_appended; @@ -150919,7 +164908,7 @@ void DataTable::RemoveFromIndexes(TableAppendState &state, DataChunk &chunk, row return; } // first generate the vector of row identifiers - Vector row_identifiers(LOGICAL_ROW_TYPE); + Vector row_identifiers(LogicalType::ROW_TYPE); VectorOperations::GenerateSequence(row_identifiers, chunk.size(), row_start, 1); // now remove the entries from the indices @@ -151230,7 +165219,7 @@ void DataTable::AddIndex(unique_ptr index, const vectorcolumn_ids) { intermediate_types.push_back(column_definitions[id].type); } - intermediate_types.push_back(LOGICAL_ROW_TYPE); + intermediate_types.emplace_back(LogicalType::ROW_TYPE); intermediate.Initialize(intermediate_types); // initialize an index scan @@ -151544,7 +165533,7 @@ void LocalStorage::Scan(LocalScanState &state, const vector &column_id if (count != chunk_count) { sel.Initialize(valid_sel); } else { - sel.Initialize(FlatVector::INCREMENTAL_SELECTION_VECTOR); + sel.Initialize(nullptr); } // now scan the vectors of the chunk for (idx_t i = 0; i < column_ids.size(); i++) { @@ -151596,7 +165585,7 @@ void LocalStorage::Append(DataTable *table, DataChunk &chunk) { idx_t base_id = MAX_ROW_ID + storage->collection.Count(); // first generate the vector of row identifiers - Vector row_ids(LOGICAL_ROW_TYPE); + Vector row_ids(LogicalType::ROW_TYPE); VectorOperations::GenerateSequence(row_ids, chunk.size(), base_id, 1); // now append the entries to the indices @@ -151715,7 +165704,7 @@ static void TemplatedUpdateLoop(Vector &data_vector, Vector &update_vector, Vect static void UpdateChunk(Vector &data, Vector &updates, Vector &row_ids, idx_t count, idx_t base_index) { D_ASSERT(data.GetType() == updates.GetType()); - D_ASSERT(row_ids.GetType() == LOGICAL_ROW_TYPE); + D_ASSERT(row_ids.GetType() == LogicalType::ROW_TYPE); switch (data.GetType().InternalType()) { case PhysicalType::INT8: @@ -151950,7 +165939,13 @@ MetaBlockWriter::MetaBlockWriter(DatabaseInstance &db, block_id_t initial_block_ } MetaBlockWriter::~MetaBlockWriter() { - Flush(); + if (Exception::UncaughtException()) { + return; + } + try { + Flush(); + } catch (...) { + } } block_id_t MetaBlockWriter::GetNextBlockId() { @@ -152109,6 +166104,7 @@ class SingleFileBlockManager : public BlockManager { + #include #include @@ -152119,9 +166115,11 @@ const char MainHeader::MAGIC_BYTES[] = "DUCK"; void MainHeader::Serialize(Serializer &ser) { ser.WriteData((data_ptr_t)MAGIC_BYTES, MAGIC_BYTE_SIZE); ser.Write(version_number); + FieldWriter writer(ser); for (idx_t i = 0; i < FLAG_COUNT; i++) { - ser.Write(flags[i]); + writer.WriteField(flags[i]); } + writer.Finalize(); } void MainHeader::CheckMagicBytes(FileHandle &handle) { @@ -152144,9 +166142,11 @@ MainHeader MainHeader::Deserialize(Deserializer &source) { } header.version_number = source.Read(); // read the flags + FieldReader reader(source); for (idx_t i = 0; i < FLAG_COUNT; i++) { - header.flags[i] = source.Read(); + header.flags[i] = reader.ReadRequired(); } + reader.Finalize(); return header; } @@ -152513,7 +166513,7 @@ BaseStatistics::BaseStatistics(LogicalType type) : type(move(type)) { BaseStatistics::~BaseStatistics() { } -bool BaseStatistics::CanHaveNull() { +bool BaseStatistics::CanHaveNull() const { if (!validity_stats) { // we don't know // solid maybe @@ -152522,7 +166522,7 @@ bool BaseStatistics::CanHaveNull() { return ((ValidityStatistics &)*validity_stats).has_null; } -bool BaseStatistics::CanHaveNoNull() { +bool BaseStatistics::CanHaveNoNull() const { if (!validity_stats) { // we don't know // solid maybe @@ -152531,14 +166531,6 @@ bool BaseStatistics::CanHaveNoNull() { return ((ValidityStatistics &)*validity_stats).has_no_null; } -unique_ptr BaseStatistics::Copy() { - auto statistics = make_unique(type); - if (validity_stats) { - statistics->validity_stats = validity_stats->Copy(); - } - return statistics; -} - void BaseStatistics::Merge(const BaseStatistics &other) { D_ASSERT(type == other.type); if (other.validity_stats) { @@ -152581,18 +166573,33 @@ unique_ptr BaseStatistics::CreateEmpty(LogicalType type) { } } -void BaseStatistics::Serialize(Serializer &serializer) { - serializer.Write(CanHaveNull()); - serializer.Write(CanHaveNoNull()); +unique_ptr BaseStatistics::Copy() const { + auto statistics = make_unique(type); + if (validity_stats) { + statistics->validity_stats = validity_stats->Copy(); + } + return statistics; +} + +void BaseStatistics::Serialize(Serializer &serializer) const { + FieldWriter writer(serializer); + writer.WriteField(CanHaveNull()); + writer.WriteField(CanHaveNoNull()); + Serialize(writer); + writer.Finalize(); +} + +void BaseStatistics::Serialize(FieldWriter &writer) const { } unique_ptr BaseStatistics::Deserialize(Deserializer &source, LogicalType type) { - bool can_have_null = source.Read(); - bool can_have_no_null = source.Read(); + FieldReader reader(source); + bool can_have_null = reader.ReadRequired(); + bool can_have_no_null = reader.ReadRequired(); unique_ptr result; switch (type.InternalType()) { case PhysicalType::BIT: - return ValidityStatistics::Deserialize(source); + return ValidityStatistics::Deserialize(reader); case PhysicalType::BOOL: case PhysicalType::INT8: case PhysicalType::INT16: @@ -152605,16 +166612,16 @@ unique_ptr BaseStatistics::Deserialize(Deserializer &source, Log case PhysicalType::INT128: case PhysicalType::FLOAT: case PhysicalType::DOUBLE: - result = NumericStatistics::Deserialize(source, move(type)); + result = NumericStatistics::Deserialize(reader, move(type)); break; case PhysicalType::VARCHAR: - result = StringStatistics::Deserialize(source, move(type)); + result = StringStatistics::Deserialize(reader, move(type)); break; case PhysicalType::STRUCT: - result = StructStatistics::Deserialize(source, move(type)); + result = StructStatistics::Deserialize(reader, move(type)); break; case PhysicalType::LIST: - result = ListStatistics::Deserialize(source, move(type)); + result = ListStatistics::Deserialize(reader, move(type)); break; case PhysicalType::INTERVAL: result = make_unique(move(type)); @@ -152626,25 +166633,28 @@ unique_ptr BaseStatistics::Deserialize(Deserializer &source, Log return result; } -string BaseStatistics::ToString() { +string BaseStatistics::ToString() const { return StringUtil::Format("Base Statistics %s", validity_stats ? validity_stats->ToString() : "[]"); } -void BaseStatistics::Verify(Vector &vector, const SelectionVector &sel, idx_t count) { +void BaseStatistics::Verify(Vector &vector, const SelectionVector &sel, idx_t count) const { D_ASSERT(vector.GetType() == this->type); if (validity_stats) { validity_stats->Verify(vector, sel, count); } } -void BaseStatistics::Verify(Vector &vector, idx_t count) { - Verify(vector, FlatVector::INCREMENTAL_SELECTION_VECTOR, count); +void BaseStatistics::Verify(Vector &vector, idx_t count) const { + SelectionVector owned_sel; + auto sel = FlatVector::IncrementalSelectionVector(count, owned_sel); + Verify(vector, *sel, count); } } // namespace duckdb + namespace duckdb { ListStatistics::ListStatistics(LogicalType type_p) : BaseStatistics(move(type_p)) { @@ -152667,32 +166677,32 @@ void ListStatistics::Merge(const BaseStatistics &other_p) { } // LCOV_EXCL_START -FilterPropagateResult ListStatistics::CheckZonemap(ExpressionType comparison_type, const Value &constant) { +FilterPropagateResult ListStatistics::CheckZonemap(ExpressionType comparison_type, const Value &constant) const { throw InternalException("List zonemaps are not supported yet"); } // LCOV_EXCL_STOP -unique_ptr ListStatistics::Copy() { +unique_ptr ListStatistics::Copy() const { auto copy = make_unique(type); copy->validity_stats = validity_stats ? validity_stats->Copy() : nullptr; copy->child_stats = child_stats ? child_stats->Copy() : nullptr; return move(copy); } -void ListStatistics::Serialize(Serializer &serializer) { - BaseStatistics::Serialize(serializer); - child_stats->Serialize(serializer); +void ListStatistics::Serialize(FieldWriter &writer) const { + writer.WriteSerializable(*child_stats); } -unique_ptr ListStatistics::Deserialize(Deserializer &source, LogicalType type) { +unique_ptr ListStatistics::Deserialize(FieldReader &reader, LogicalType type) { D_ASSERT(type.InternalType() == PhysicalType::LIST); auto result = make_unique(move(type)); auto &child_type = ListType::GetChildType(result->type); + auto &source = reader.GetSource(); result->child_stats = BaseStatistics::Deserialize(source, child_type); return move(result); } -string ListStatistics::ToString() { +string ListStatistics::ToString() const { string result; result += " ["; result += child_stats ? child_stats->ToString() : "No Stats"; @@ -152701,7 +166711,7 @@ string ListStatistics::ToString() { return result; } -void ListStatistics::Verify(Vector &vector, const SelectionVector &sel, idx_t count) { +void ListStatistics::Verify(Vector &vector, const SelectionVector &sel, idx_t count) const { BaseStatistics::Verify(vector, sel, count); if (child_stats) { @@ -152743,73 +166753,8 @@ void ListStatistics::Verify(Vector &vector, const SelectionVector &sel, idx_t co -namespace duckdb { - -template <> -void NumericStatistics::Update(SegmentStatistics &stats, int8_t new_value) { - auto &nstats = (NumericStatistics &)*stats.statistics; - UpdateValue(new_value, nstats.min.value_.tinyint, nstats.max.value_.tinyint); -} - -template <> -void NumericStatistics::Update(SegmentStatistics &stats, int16_t new_value) { - auto &nstats = (NumericStatistics &)*stats.statistics; - UpdateValue(new_value, nstats.min.value_.smallint, nstats.max.value_.smallint); -} - -template <> -void NumericStatistics::Update(SegmentStatistics &stats, int32_t new_value) { - auto &nstats = (NumericStatistics &)*stats.statistics; - UpdateValue(new_value, nstats.min.value_.integer, nstats.max.value_.integer); -} - -template <> -void NumericStatistics::Update(SegmentStatistics &stats, int64_t new_value) { - auto &nstats = (NumericStatistics &)*stats.statistics; - UpdateValue(new_value, nstats.min.value_.bigint, nstats.max.value_.bigint); -} - -template <> -void NumericStatistics::Update(SegmentStatistics &stats, uint8_t new_value) { - auto &nstats = (NumericStatistics &)*stats.statistics; - UpdateValue(new_value, nstats.min.value_.utinyint, nstats.max.value_.utinyint); -} - -template <> -void NumericStatistics::Update(SegmentStatistics &stats, uint16_t new_value) { - auto &nstats = (NumericStatistics &)*stats.statistics; - UpdateValue(new_value, nstats.min.value_.usmallint, nstats.max.value_.usmallint); -} -template <> -void NumericStatistics::Update(SegmentStatistics &stats, uint32_t new_value) { - auto &nstats = (NumericStatistics &)*stats.statistics; - UpdateValue(new_value, nstats.min.value_.uinteger, nstats.max.value_.uinteger); -} - -template <> -void NumericStatistics::Update(SegmentStatistics &stats, uint64_t new_value) { - auto &nstats = (NumericStatistics &)*stats.statistics; - UpdateValue(new_value, nstats.min.value_.ubigint, nstats.max.value_.ubigint); -} - -template <> -void NumericStatistics::Update(SegmentStatistics &stats, hugeint_t new_value) { - auto &nstats = (NumericStatistics &)*stats.statistics; - UpdateValue(new_value, nstats.min.value_.hugeint, nstats.max.value_.hugeint); -} - -template <> -void NumericStatistics::Update(SegmentStatistics &stats, float new_value) { - auto &nstats = (NumericStatistics &)*stats.statistics; - UpdateValue(new_value, nstats.min.value_.float_, nstats.max.value_.float_); -} - -template <> -void NumericStatistics::Update(SegmentStatistics &stats, double new_value) { - auto &nstats = (NumericStatistics &)*stats.statistics; - UpdateValue(new_value, nstats.min.value_.double_, nstats.max.value_.double_); -} +namespace duckdb { template <> void NumericStatistics::Update(SegmentStatistics &stats, interval_t new_value) { @@ -152832,23 +166777,23 @@ NumericStatistics::NumericStatistics(LogicalType type_p, Value min_p, Value max_ void NumericStatistics::Merge(const BaseStatistics &other_p) { BaseStatistics::Merge(other_p); auto &other = (const NumericStatistics &)other_p; - if (other.min.is_null || min.is_null) { - min.is_null = true; + if (other.min.IsNull() || min.IsNull()) { + min = Value(type); } else if (other.min < min) { min = other.min; } - if (other.max.is_null || max.is_null) { - max.is_null = true; + if (other.max.IsNull() || max.IsNull()) { + max = Value(type); } else if (other.max > max) { max = other.max; } } -FilterPropagateResult NumericStatistics::CheckZonemap(ExpressionType comparison_type, const Value &constant) { - if (constant.is_null) { +FilterPropagateResult NumericStatistics::CheckZonemap(ExpressionType comparison_type, const Value &constant) const { + if (constant.IsNull()) { return FilterPropagateResult::FILTER_ALWAYS_FALSE; } - if (min.is_null || max.is_null) { + if (min.IsNull() || max.IsNull()) { return FilterPropagateResult::NO_PRUNING_POSSIBLE; } switch (comparison_type) { @@ -152860,6 +166805,14 @@ FilterPropagateResult NumericStatistics::CheckZonemap(ExpressionType comparison_ } else { return FilterPropagateResult::FILTER_ALWAYS_FALSE; } + case ExpressionType::COMPARE_NOTEQUAL: + if (constant < min || constant > max) { + return FilterPropagateResult::FILTER_ALWAYS_TRUE; + } else if (min == max && min == constant) { + // corner case of a cluster with one numeric equal to the target constant + return FilterPropagateResult::FILTER_ALWAYS_FALSE; + } + return FilterPropagateResult::NO_PRUNING_POSSIBLE; case ExpressionType::COMPARE_GREATERTHANOREQUALTO: // X >= C // this can be true only if max(X) >= C @@ -152909,7 +166862,7 @@ FilterPropagateResult NumericStatistics::CheckZonemap(ExpressionType comparison_ } } -unique_ptr NumericStatistics::Copy() { +unique_ptr NumericStatistics::Copy() const { auto stats = make_unique(type, min, max); if (validity_stats) { stats->validity_stats = validity_stats->Copy(); @@ -152917,29 +166870,28 @@ unique_ptr NumericStatistics::Copy() { return move(stats); } -bool NumericStatistics::IsConstant() { +bool NumericStatistics::IsConstant() const { return max <= min; } -void NumericStatistics::Serialize(Serializer &serializer) { - BaseStatistics::Serialize(serializer); - min.Serialize(serializer); - max.Serialize(serializer); +void NumericStatistics::Serialize(FieldWriter &writer) const { + writer.WriteSerializable(min); + writer.WriteSerializable(max); } -unique_ptr NumericStatistics::Deserialize(Deserializer &source, LogicalType type) { - auto min = Value::Deserialize(source); - auto max = Value::Deserialize(source); +unique_ptr NumericStatistics::Deserialize(FieldReader &reader, LogicalType type) { + auto min = reader.ReadRequiredSerializable(); + auto max = reader.ReadRequiredSerializable(); return make_unique_base(move(type), min, max); } -string NumericStatistics::ToString() { +string NumericStatistics::ToString() const { return StringUtil::Format("[Min: %s, Max: %s]%s", min.ToString(), max.ToString(), validity_stats ? validity_stats->ToString() : ""); } template -void NumericStatistics::TemplatedVerify(Vector &vector, const SelectionVector &sel, idx_t count) { +void NumericStatistics::TemplatedVerify(Vector &vector, const SelectionVector &sel, idx_t count) const { VectorData vdata; vector.Orrify(count, vdata); @@ -152950,18 +166902,18 @@ void NumericStatistics::TemplatedVerify(Vector &vector, const SelectionVector &s if (!vdata.validity.RowIsValid(index)) { continue; } - if (!min.is_null && LessThan::Operation(data[index], min.GetValueUnsafe())) { // LCOV_EXCL_START + if (!min.IsNull() && LessThan::Operation(data[index], min.GetValueUnsafe())) { // LCOV_EXCL_START throw InternalException("Statistics mismatch: value is smaller than min.\nStatistics: %s\nVector: %s", ToString(), vector.ToString(count)); } // LCOV_EXCL_STOP - if (!max.is_null && GreaterThan::Operation(data[index], max.GetValueUnsafe())) { + if (!max.IsNull() && GreaterThan::Operation(data[index], max.GetValueUnsafe())) { throw InternalException("Statistics mismatch: value is bigger than max.\nStatistics: %s\nVector: %s", ToString(), vector.ToString(count)); } } } -void NumericStatistics::Verify(Vector &vector, const SelectionVector &sel, idx_t count) { +void NumericStatistics::Verify(Vector &vector, const SelectionVector &sel, idx_t count) const { BaseStatistics::Verify(vector, sel, count); switch (type.InternalType()) { @@ -153050,35 +167002,33 @@ StringStatistics::StringStatistics(LogicalType type_p) : BaseStatistics(move(typ validity_stats = make_unique(false); } -unique_ptr StringStatistics::Copy() { +unique_ptr StringStatistics::Copy() const { auto stats = make_unique(type); memcpy(stats->min, min, MAX_STRING_MINMAX_SIZE); memcpy(stats->max, max, MAX_STRING_MINMAX_SIZE); stats->has_unicode = has_unicode; stats->max_string_length = max_string_length; - stats->max_string_length = max_string_length; if (validity_stats) { stats->validity_stats = validity_stats->Copy(); } return move(stats); } -void StringStatistics::Serialize(Serializer &serializer) { - BaseStatistics::Serialize(serializer); - serializer.WriteData(min, MAX_STRING_MINMAX_SIZE); - serializer.WriteData(max, MAX_STRING_MINMAX_SIZE); - serializer.Write(has_unicode); - serializer.Write(max_string_length); - serializer.Write(has_overflow_strings); +void StringStatistics::Serialize(FieldWriter &writer) const { + writer.WriteBlob(min, MAX_STRING_MINMAX_SIZE); + writer.WriteBlob(max, MAX_STRING_MINMAX_SIZE); + writer.WriteField(has_unicode); + writer.WriteField(max_string_length); + writer.WriteField(has_overflow_strings); } -unique_ptr StringStatistics::Deserialize(Deserializer &source, LogicalType type) { +unique_ptr StringStatistics::Deserialize(FieldReader &reader, LogicalType type) { auto stats = make_unique(move(type)); - source.ReadData(stats->min, MAX_STRING_MINMAX_SIZE); - source.ReadData(stats->max, MAX_STRING_MINMAX_SIZE); - stats->has_unicode = source.Read(); - stats->max_string_length = source.Read(); - stats->has_overflow_strings = source.Read(); + 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); } @@ -153146,7 +167096,7 @@ void StringStatistics::Merge(const BaseStatistics &other_p) { has_overflow_strings = has_overflow_strings || other.has_overflow_strings; } -FilterPropagateResult StringStatistics::CheckZonemap(ExpressionType comparison_type, const string &constant) { +FilterPropagateResult StringStatistics::CheckZonemap(ExpressionType comparison_type, const string &constant) const { auto data = (const_data_ptr_t)constant.c_str(); auto size = constant.size(); @@ -153160,6 +167110,11 @@ FilterPropagateResult StringStatistics::CheckZonemap(ExpressionType comparison_t } else { return FilterPropagateResult::FILTER_ALWAYS_FALSE; } + case ExpressionType::COMPARE_NOTEQUAL: + if (min_comp < 0 || max_comp > 0) { + return FilterPropagateResult::FILTER_ALWAYS_TRUE; + } + return FilterPropagateResult::NO_PRUNING_POSSIBLE; case ExpressionType::COMPARE_GREATERTHANOREQUALTO: case ExpressionType::COMPARE_GREATERTHAN: if (max_comp <= 0) { @@ -153179,7 +167134,7 @@ FilterPropagateResult StringStatistics::CheckZonemap(ExpressionType comparison_t } } -static idx_t GetValidMinMaxSubstring(data_ptr_t data) { +static idx_t GetValidMinMaxSubstring(const_data_ptr_t data) { for (idx_t i = 0; i < StringStatistics::MAX_STRING_MINMAX_SIZE; i++) { if (data[i] == '\0') { return i; @@ -153191,7 +167146,7 @@ static idx_t GetValidMinMaxSubstring(data_ptr_t data) { return StringStatistics::MAX_STRING_MINMAX_SIZE; } -string StringStatistics::ToString() { +string StringStatistics::ToString() const { idx_t min_len = GetValidMinMaxSubstring(min); idx_t max_len = GetValidMinMaxSubstring(max); return StringUtil::Format("[Min: %s, Max: %s, Has Unicode: %s, Max String Length: %lld]%s", @@ -153200,7 +167155,7 @@ string StringStatistics::ToString() { validity_stats ? validity_stats->ToString() : ""); } -void StringStatistics::Verify(Vector &vector, const SelectionVector &sel, idx_t count) { +void StringStatistics::Verify(Vector &vector, const SelectionVector &sel, idx_t count) const { BaseStatistics::Verify(vector, sel, count); string_t min_string((const char *)min, MAX_STRING_MINMAX_SIZE); @@ -153279,12 +167234,12 @@ void StructStatistics::Merge(const BaseStatistics &other_p) { } // LCOV_EXCL_START -FilterPropagateResult StructStatistics::CheckZonemap(ExpressionType comparison_type, const Value &constant) { +FilterPropagateResult StructStatistics::CheckZonemap(ExpressionType comparison_type, const Value &constant) const { throw InternalException("Struct zonemaps are not supported yet"); } // LCOV_EXCL_STOP -unique_ptr StructStatistics::Copy() { +unique_ptr StructStatistics::Copy() const { auto copy = make_unique(type); if (validity_stats) { copy->validity_stats = validity_stats->Copy(); @@ -153295,8 +167250,9 @@ unique_ptr StructStatistics::Copy() { return move(copy); } -void StructStatistics::Serialize(Serializer &serializer) { - BaseStatistics::Serialize(serializer); +void StructStatistics::Serialize(FieldWriter &writer) const { + writer.WriteField(child_stats.size()); + auto &serializer = writer.GetSerializer(); for (idx_t i = 0; i < child_stats.size(); i++) { serializer.Write(child_stats[i] ? true : false); if (child_stats[i]) { @@ -153305,10 +167261,16 @@ void StructStatistics::Serialize(Serializer &serializer) { } } -unique_ptr StructStatistics::Deserialize(Deserializer &source, LogicalType type) { +unique_ptr StructStatistics::Deserialize(FieldReader &reader, LogicalType type) { D_ASSERT(type.InternalType() == PhysicalType::STRUCT); auto result = make_unique(move(type)); auto &child_types = StructType::GetChildTypes(result->type); + + auto child_type_count = reader.ReadRequired(); + if (child_types.size() != child_type_count) { + throw InternalException("Struct stats deserialization failure: child count does not match type count!"); + } + auto &source = reader.GetSource(); for (idx_t i = 0; i < child_types.size(); i++) { auto has_child = source.Read(); if (has_child) { @@ -153320,7 +167282,7 @@ unique_ptr StructStatistics::Deserialize(Deserializer &source, L return move(result); } -string StructStatistics::ToString() { +string StructStatistics::ToString() const { string result; result += " {"; auto &child_types = StructType::GetChildTypes(type); @@ -153335,7 +167297,7 @@ string StructStatistics::ToString() { return result; } -void StructStatistics::Verify(Vector &vector, const SelectionVector &sel, idx_t count) { +void StructStatistics::Verify(Vector &vector, const SelectionVector &sel, idx_t count) const { BaseStatistics::Verify(vector, sel, count); auto &child_entries = StructVector::GetEntries(vector); @@ -153373,7 +167335,7 @@ unique_ptr ValidityStatistics::Combine(const unique_ptr ValidityStatistics::Copy() { +unique_ptr ValidityStatistics::Copy() const { return make_unique(has_null, has_no_null); } -void ValidityStatistics::Serialize(Serializer &serializer) { - BaseStatistics::Serialize(serializer); - serializer.Write(has_null); - serializer.Write(has_no_null); +void ValidityStatistics::Serialize(FieldWriter &writer) const { + writer.WriteField(has_null); + writer.WriteField(has_no_null); } -unique_ptr ValidityStatistics::Deserialize(Deserializer &source) { - bool has_null = source.Read(); - bool has_no_null = source.Read(); +unique_ptr ValidityStatistics::Deserialize(FieldReader &reader) { + bool has_null = reader.ReadRequired(); + bool has_no_null = reader.ReadRequired(); return make_unique(has_null, has_no_null); } -void ValidityStatistics::Verify(Vector &vector, const SelectionVector &sel, idx_t count) { +void ValidityStatistics::Verify(Vector &vector, const SelectionVector &sel, idx_t count) const { if (has_null && has_no_null) { // nothing to verify return; @@ -153429,7 +167390,7 @@ void ValidityStatistics::Verify(Vector &vector, const SelectionVector &sel, idx_ } } -string ValidityStatistics::ToString() { +string ValidityStatistics::ToString() const { return has_null ? "[Has Null: true]" : "[Has Null: false]"; } @@ -153438,7 +167399,7 @@ string ValidityStatistics::ToString() { namespace duckdb { -const uint64_t VERSION_NUMBER = 27; +const uint64_t VERSION_NUMBER = 31; } // namespace duckdb @@ -153910,7 +167871,7 @@ void ChunkVectorInfo::CommitAppend(transaction_t commit_id, idx_t start, idx_t e void ChunkVectorInfo::Serialize(Serializer &serializer) { SelectionVector sel(STANDARD_VECTOR_SIZE); transaction_t start_time = TRANSACTION_ID_START - 1; - transaction_t transaction_id = INVALID_INDEX; + transaction_t transaction_id = DConstants::INVALID_INDEX; idx_t count = GetSelVector(start_time, transaction_id, sel, STANDARD_VECTOR_SIZE); if (count == STANDARD_VECTOR_SIZE) { // nothing is deleted: skip writing anything @@ -154003,7 +167964,7 @@ class ListColumnData : public ColumnData { idx_t Fetch(ColumnScanState &state, row_t row_id, Vector &result) override; void FetchRow(Transaction &transaction, ColumnFetchState &state, row_t row_id, Vector &result, idx_t result_idx) override; - void Update(Transaction &transaction, idx_t column_index, Vector &update_vector, row_t *row_ids, idx_t offset, + void Update(Transaction &transaction, idx_t column_index, Vector &update_vector, row_t *row_ids, idx_t update_count) override; void UpdateColumn(Transaction &transaction, const vector &column_path, Vector &update_vector, row_t *row_ids, idx_t update_count, idx_t depth) override; @@ -154191,7 +168152,7 @@ class UpdateSegment { void FetchUpdates(Transaction &transaction, idx_t vector_index, Vector &result); void FetchCommitted(idx_t vector_index, Vector &result); void FetchCommittedRange(idx_t start_row, idx_t count, Vector &result); - void Update(Transaction &transaction, idx_t column_index, Vector &update, row_t *ids, idx_t offset, idx_t count, + void Update(Transaction &transaction, idx_t column_index, Vector &update, row_t *ids, idx_t count, Vector &base_data); void FetchRow(Transaction &transaction, idx_t row_id, Vector &result, idx_t result_idx); @@ -154232,7 +168193,7 @@ class UpdateSegment { idx_t row_idx, Vector &result, idx_t result_idx); typedef void (*rollback_update_function_t)(UpdateInfo *base_info, UpdateInfo *rollback_info); typedef idx_t (*statistics_update_function_t)(UpdateSegment *segment, SegmentStatistics &stats, Vector &update, - idx_t offset, idx_t count, SelectionVector &sel); + idx_t count, SelectionVector &sel); private: initialize_update_function_t initialize_update_function; @@ -154306,7 +168267,7 @@ class StructColumnData : public ColumnData { idx_t Fetch(ColumnScanState &state, row_t row_id, Vector &result) override; void FetchRow(Transaction &transaction, ColumnFetchState &state, row_t row_id, Vector &result, idx_t result_idx) override; - void Update(Transaction &transaction, idx_t column_index, Vector &update_vector, row_t *row_ids, idx_t offset, + void Update(Transaction &transaction, idx_t column_index, Vector &update_vector, row_t *row_ids, idx_t update_count) override; void UpdateColumn(Transaction &transaction, const vector &column_path, Vector &update_vector, row_t *row_ids, idx_t update_count, idx_t depth) override; @@ -154619,24 +168580,24 @@ void ColumnData::FetchRow(Transaction &transaction, ColumnFetchState &state, row } void ColumnData::Update(Transaction &transaction, idx_t column_index, Vector &update_vector, row_t *row_ids, - idx_t offset, idx_t update_count) { + idx_t update_count) { lock_guard update_guard(update_lock); if (!updates) { updates = make_unique(*this); } Vector base_vector(type); ColumnScanState state; - auto fetch_count = Fetch(state, row_ids[offset], base_vector); + auto fetch_count = Fetch(state, row_ids[0], base_vector); base_vector.Normalify(fetch_count); - updates->Update(transaction, column_index, update_vector, row_ids, offset, update_count, base_vector); + updates->Update(transaction, column_index, update_vector, row_ids, update_count, base_vector); } void ColumnData::UpdateColumn(Transaction &transaction, const vector &column_path, Vector &update_vector, row_t *row_ids, idx_t update_count, idx_t depth) { // this method should only be called at the end of the path in the base column case D_ASSERT(depth >= column_path.size()); - ColumnData::Update(transaction, column_path[0], update_vector, row_ids, 0, update_count); + ColumnData::Update(transaction, column_path[0], update_vector, row_ids, update_count); } unique_ptr ColumnData::GetUpdateStatistics() { @@ -154954,7 +168915,7 @@ unique_ptr ColumnDataCheckpointer::DetectBestCompressionMethod(idx // now that we have passed over all the data, we need to figure out the best method // we do this using the final_analyze method unique_ptr state; - compression_idx = INVALID_INDEX; + compression_idx = DConstants::INVALID_INDEX; idx_t best_score = NumericLimits::Maximum(); for (idx_t i = 0; i < compression_functions.size(); i++) { if (!compression_functions[i]) { @@ -155283,6 +169244,16 @@ static void FilterSelectionSwitch(T *vec, T *predicate, SelectionVector &sel, id } break; } + case ExpressionType::COMPARE_NOTEQUAL: { + if (mask.AllValid()) { + approved_tuple_count = + TemplatedFilterSelection(vec, predicate, sel, approved_tuple_count, mask, new_sel); + } else { + approved_tuple_count = + TemplatedFilterSelection(vec, predicate, sel, approved_tuple_count, mask, new_sel); + } + break; + } case ExpressionType::COMPARE_LESSTHAN: { if (mask.AllValid()) { approved_tuple_count = @@ -155352,15 +169323,44 @@ static idx_t TemplatedNullSelection(SelectionVector &sel, idx_t approved_tuple_c } } -void ColumnSegment::FilterSelection(SelectionVector &sel, Vector &result, const TableFilter &filter, - idx_t &approved_tuple_count, ValidityMask &mask) { +idx_t ColumnSegment::FilterSelection(SelectionVector &sel, Vector &result, const TableFilter &filter, + idx_t &approved_tuple_count, ValidityMask &mask) { switch (filter.filter_type) { + case TableFilterType::CONJUNCTION_OR: { + // 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; + for (auto &child_filter : conjunction_or.child_filters) { + SelectionVector temp_sel; + temp_sel.Initialize(sel); + idx_t temp_tuple_count = approved_tuple_count; + idx_t temp_count = FilterSelection(temp_sel, result, *child_filter, temp_tuple_count, mask); + // tuples passed, move them into the actual result vector + for (idx_t i = 0; i < temp_count; i++) { + auto new_idx = temp_sel.get_index(i); + bool is_new_idx = true; + for (idx_t res_idx = 0; res_idx < count_total; res_idx++) { + if (result_sel.get_index(res_idx) == new_idx) { + is_new_idx = false; + break; + } + } + if (is_new_idx) { + result_sel.set_index(count_total++, new_idx); + } + } + } + sel.Initialize(result_sel); + approved_tuple_count = count_total; + return approved_tuple_count; + } case TableFilterType::CONJUNCTION_AND: { auto &conjunction_and = (ConjunctionAndFilter &)filter; for (auto &child_filter : conjunction_and.child_filters) { FilterSelection(sel, result, *child_filter, approved_tuple_count, mask); } - break; + return approved_tuple_count; } case TableFilterType::CONSTANT_COMPARISON: { auto &constant_filter = (ConstantFilter &)filter; @@ -155456,7 +169456,7 @@ void ColumnSegment::FilterSelection(SelectionVector &sel, Vector &result, const } case PhysicalType::VARCHAR: { auto result_flat = FlatVector::GetData(result); - Vector predicate_vector(constant_filter.constant.str_value); + Vector predicate_vector(constant_filter.constant); auto predicate = FlatVector::GetData(predicate_vector); FilterSelectionSwitch(result_flat, predicate, sel, approved_tuple_count, constant_filter.comparison_type, mask); @@ -155473,14 +169473,12 @@ void ColumnSegment::FilterSelection(SelectionVector &sel, Vector &result, const default: throw InvalidTypeException(result.GetType(), "Invalid type for filter pushed down to table comparison"); } - break; + return approved_tuple_count; } case TableFilterType::IS_NULL: - TemplatedNullSelection(sel, approved_tuple_count, mask); - break; + return TemplatedNullSelection(sel, approved_tuple_count, mask); case TableFilterType::IS_NOT_NULL: - TemplatedNullSelection(sel, approved_tuple_count, mask); - break; + return TemplatedNullSelection(sel, approved_tuple_count, mask); default: throw InternalException("FIXME: unsupported type for filter selection"); } @@ -155677,7 +169675,7 @@ void ListColumnData::Append(BaseStatistics &stats_p, ColumnAppendState &state, V VectorData vdata; vdata.validity = list_validity; - vdata.sel = &FlatVector::INCREMENTAL_SELECTION_VECTOR; + vdata.sel = FlatVector::IncrementalSelectionVector(count, vdata.owned_sel); vdata.data = (data_ptr_t)append_offsets.get(); // append the list offsets @@ -155707,7 +169705,7 @@ idx_t ListColumnData::Fetch(ColumnScanState &state, row_t row_id, Vector &result } void ListColumnData::Update(Transaction &transaction, idx_t column_index, Vector &update_vector, row_t *row_ids, - idx_t offset, idx_t update_count) { + idx_t update_count) { throw NotImplementedException("List Update is not supported."); } @@ -155851,6 +169849,7 @@ PersistentTableData::~PersistentTableData() { + namespace duckdb { constexpr const idx_t RowGroup::ROW_GROUP_VECTOR_COUNT; @@ -156189,7 +170188,7 @@ void RowGroup::TemplatedScan(Transaction *transaction, RowGroupScanState &state, if (count != max_count) { sel.Initialize(valid_sel); } else { - sel.Initialize(FlatVector::INCREMENTAL_SELECTION_VECTOR); + sel.Initialize(nullptr); } //! first, we scan the columns with filters, fetch their data and generate a selection vector. //! get runtime statistics @@ -156447,7 +170446,13 @@ void RowGroup::Update(Transaction &transaction, DataChunk &update_chunk, row_t * auto column = column_ids[i]; D_ASSERT(column != COLUMN_IDENTIFIER_ROW_ID); D_ASSERT(columns[column]->type.id() == update_chunk.data[i].GetType().id()); - columns[column]->Update(transaction, column, update_chunk.data[i], ids, offset, count); + if (offset > 0) { + Vector sliced_vector(update_chunk.data[i], offset); + sliced_vector.Normalify(count); + columns[column]->Update(transaction, column, sliced_vector, ids + offset, count); + } else { + columns[column]->Update(transaction, column, update_chunk.data[i], ids, count); + } MergeStatistics(column, *columns[column]->GetUpdateStatistics()); } } @@ -156562,9 +170567,11 @@ shared_ptr RowGroup::DeserializeDeletes(Deserializer &source) { return version_info; } -void RowGroup::Serialize(RowGroupPointer &pointer, Serializer &serializer) { - serializer.Write(pointer.row_start); - serializer.Write(pointer.tuple_count); +void RowGroup::Serialize(RowGroupPointer &pointer, Serializer &main_serializer) { + FieldWriter writer(main_serializer); + writer.WriteField(pointer.row_start); + writer.WriteField(pointer.tuple_count); + auto &serializer = writer.GetSerializer(); for (auto &stats : pointer.statistics) { stats->Serialize(serializer); } @@ -156573,16 +170580,20 @@ void RowGroup::Serialize(RowGroupPointer &pointer, Serializer &serializer) { serializer.Write(data_pointer.offset); } CheckpointDeletes(pointer.versions.get(), serializer); + writer.Finalize(); } -RowGroupPointer RowGroup::Deserialize(Deserializer &source, const vector &columns) { +RowGroupPointer RowGroup::Deserialize(Deserializer &main_source, const vector &columns) { RowGroupPointer result; - result.row_start = source.Read(); - result.tuple_count = source.Read(); + + FieldReader reader(main_source); + result.row_start = reader.ReadRequired(); + result.tuple_count = reader.ReadRequired(); result.data_pointers.reserve(columns.size()); result.statistics.reserve(columns.size()); + auto &source = reader.GetSource(); for (idx_t i = 0; i < columns.size(); i++) { auto stats = BaseStatistics::Deserialize(source, columns[i].type); result.statistics.push_back(move(stats)); @@ -156594,6 +170605,8 @@ RowGroupPointer RowGroup::Deserialize(Deserializer &source, const vector> &resu class VersionDeleteState { public: VersionDeleteState(RowGroup &info, Transaction &transaction, DataTable *table, idx_t base_row) - : info(info), transaction(transaction), table(table), current_info(nullptr), current_chunk(INVALID_INDEX), - count(0), base_row(base_row), delete_count(0) { + : info(info), transaction(transaction), table(table), current_info(nullptr), + current_chunk(DConstants::INVALID_INDEX), count(0), base_row(base_row), delete_count(0) { } RowGroup &info; @@ -156870,16 +170883,16 @@ idx_t StandardColumnData::Fetch(ColumnScanState &state, row_t row_id, Vector &re } void StandardColumnData::Update(Transaction &transaction, idx_t column_index, Vector &update_vector, row_t *row_ids, - idx_t offset, idx_t update_count) { - ColumnData::Update(transaction, column_index, update_vector, row_ids, offset, update_count); - validity.Update(transaction, column_index, update_vector, row_ids, offset, update_count); + idx_t update_count) { + ColumnData::Update(transaction, column_index, update_vector, row_ids, update_count); + validity.Update(transaction, column_index, update_vector, row_ids, update_count); } void StandardColumnData::UpdateColumn(Transaction &transaction, const vector &column_path, Vector &update_vector, row_t *row_ids, idx_t update_count, idx_t depth) { if (depth >= column_path.size()) { // update this column - ColumnData::Update(transaction, column_path[0], update_vector, row_ids, 0, update_count); + ColumnData::Update(transaction, column_path[0], update_vector, row_ids, update_count); } else { // update the child column (i.e. the validity column) validity.UpdateColumn(transaction, column_path, update_vector, row_ids, update_count, depth + 1); @@ -157130,11 +171143,11 @@ idx_t StructColumnData::Fetch(ColumnScanState &state, row_t row_id, Vector &resu } void StructColumnData::Update(Transaction &transaction, idx_t column_index, Vector &update_vector, row_t *row_ids, - idx_t offset, idx_t update_count) { - validity.Update(transaction, column_index, update_vector, row_ids, offset, update_count); + idx_t update_count) { + validity.Update(transaction, column_index, update_vector, row_ids, update_count); auto &child_entries = StructVector::GetEntries(update_vector); for (idx_t i = 0; i < child_entries.size(); i++) { - sub_columns[i]->Update(transaction, column_index, *child_entries[i], row_ids, offset, update_count); + sub_columns[i]->Update(transaction, column_index, *child_entries[i], row_ids, update_count); } } @@ -157851,8 +171864,8 @@ void UpdateSegment::CleanupUpdate(UpdateInfo *info) { //===--------------------------------------------------------------------===// // Check for conflicts in update //===--------------------------------------------------------------------===// -static void CheckForConflicts(UpdateInfo *info, Transaction &transaction, row_t *ids, idx_t count, row_t offset, - UpdateInfo *&node) { +static void CheckForConflicts(UpdateInfo *info, Transaction &transaction, row_t *ids, const SelectionVector &sel, + idx_t count, row_t offset, UpdateInfo *&node) { if (!info) { return; } @@ -157864,7 +171877,7 @@ static void CheckForConflicts(UpdateInfo *info, Transaction &transaction, row_t // as both ids and info->tuples are sorted, this is similar to a merge join idx_t i = 0, j = 0; while (true) { - auto id = ids[i] - offset; + auto id = ids[sel.get_index(i)] - offset; if (id == info->tuples[j]) { throw TransactionException("Conflict on update!"); } else if (id < info->tuples[j]) { @@ -157882,7 +171895,7 @@ static void CheckForConflicts(UpdateInfo *info, Transaction &transaction, row_t } } } - CheckForConflicts(info->next, transaction, ids, count, offset, node); + CheckForConflicts(info->next, transaction, ids, sel, count, offset, node); } //===--------------------------------------------------------------------===// @@ -158216,74 +172229,69 @@ unique_ptr UpdateSegment::GetStatistics() { return stats.statistics->Copy(); } -idx_t UpdateValidityStatistics(UpdateSegment *segment, SegmentStatistics &stats, Vector &update, idx_t offset, - idx_t count, SelectionVector &sel) { +idx_t UpdateValidityStatistics(UpdateSegment *segment, SegmentStatistics &stats, Vector &update, idx_t count, + SelectionVector &sel) { auto &mask = FlatVector::Validity(update); auto &validity = (ValidityStatistics &)*stats.statistics; if (!mask.AllValid() && !validity.has_null) { for (idx_t i = 0; i < count; i++) { - auto idx = offset + i; - if (!mask.RowIsValid(idx)) { + if (!mask.RowIsValid(i)) { validity.has_null = true; break; } } } - sel.Initialize((sel_t *)(FlatVector::INCREMENTAL_VECTOR + offset)); + sel.Initialize(nullptr); return count; } template -idx_t TemplatedUpdateNumericStatistics(UpdateSegment *segment, SegmentStatistics &stats, Vector &update, idx_t offset, - idx_t count, SelectionVector &sel) { +idx_t TemplatedUpdateNumericStatistics(UpdateSegment *segment, SegmentStatistics &stats, Vector &update, idx_t count, + SelectionVector &sel) { auto update_data = FlatVector::GetData(update); auto &mask = FlatVector::Validity(update); if (mask.AllValid()) { for (idx_t i = 0; i < count; i++) { - auto idx = offset + i; - NumericStatistics::Update(stats, update_data[idx]); + NumericStatistics::Update(stats, update_data[i]); } - sel.Initialize((sel_t *)(FlatVector::INCREMENTAL_VECTOR + offset)); + sel.Initialize(nullptr); return count; } else { idx_t not_null_count = 0; sel.Initialize(STANDARD_VECTOR_SIZE); for (idx_t i = 0; i < count; i++) { - auto idx = offset + i; - if (mask.RowIsValid(idx)) { - sel.set_index(not_null_count++, idx); - NumericStatistics::Update(stats, update_data[idx]); + if (mask.RowIsValid(i)) { + sel.set_index(not_null_count++, i); + NumericStatistics::Update(stats, update_data[i]); } } return not_null_count; } } -idx_t UpdateStringStatistics(UpdateSegment *segment, SegmentStatistics &stats, Vector &update, idx_t offset, - idx_t count, SelectionVector &sel) { +idx_t UpdateStringStatistics(UpdateSegment *segment, SegmentStatistics &stats, Vector &update, idx_t count, + SelectionVector &sel) { auto update_data = FlatVector::GetData(update); auto &mask = FlatVector::Validity(update); if (mask.AllValid()) { for (idx_t i = 0; i < count; i++) { - auto idx = offset + i; - ((StringStatistics &)*stats.statistics).Update(update_data[idx]); - if (!update_data[idx].IsInlined()) { - update_data[idx] = segment->GetStringHeap().AddString(update_data[idx]); + ((StringStatistics &)*stats.statistics).Update(update_data[i]); + if (!update_data[i].IsInlined()) { + update_data[i] = segment->GetStringHeap().AddString(update_data[i]); } } - sel.Initialize(FlatVector::INCREMENTAL_SELECTION_VECTOR); + sel.Initialize(nullptr); return count; } else { idx_t not_null_count = 0; sel.Initialize(STANDARD_VECTOR_SIZE); for (idx_t i = 0; i < count; i++) { - auto idx = offset + i; - if (mask.RowIsValid(idx)) { - sel.set_index(not_null_count++, idx); - ((StringStatistics &)*stats.statistics).Update(update_data[idx]); - if (!update_data[idx].IsInlined()) { - update_data[idx] = segment->GetStringHeap().AddString(update_data[idx]); + if (mask.RowIsValid(i)) { + 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]); } } } @@ -158375,8 +172383,8 @@ static idx_t SortSelectionVector(SelectionVector &sel, idx_t count, row_t *ids) return pos; } -void UpdateSegment::Update(Transaction &transaction, idx_t column_index, Vector &update, row_t *ids, idx_t offset, - idx_t count, Vector &base_data) { +void UpdateSegment::Update(Transaction &transaction, idx_t column_index, Vector &update, row_t *ids, idx_t count, + Vector &base_data) { // obtain an exclusive lock auto write_lock = lock.GetExclusiveLock(); @@ -158386,7 +172394,7 @@ void UpdateSegment::Update(Transaction &transaction, idx_t column_index, Vector SelectionVector sel; { lock_guard stats_guard(stats_lock); - count = statistics_update_function(this, stats, update, offset, count, sel); + count = statistics_update_function(this, stats, update, count, sel); } if (count == 0) { return; @@ -158420,7 +172428,7 @@ void UpdateSegment::Update(Transaction &transaction, idx_t column_index, Vector // there is already a version here, check if there are any conflicts and search for the node that belongs to // this transaction in the version chain auto base_info = root->info[vector_index]->info.get(); - CheckForConflicts(base_info->next, transaction, ids, count, vector_offset, node); + CheckForConflicts(base_info->next, transaction, ids, sel, count, vector_offset, node); // there are no conflicts // first, check if this thread has already done any updates @@ -158561,8 +172569,11 @@ bool ValidityColumnData::CheckZonemap(ColumnScanState &state, TableFilter &filte + + namespace duckdb { + class ReplayState { public: ReplayState(DatabaseInstance &db, ClientContext &context, Deserializer &source) @@ -158858,18 +172869,13 @@ void ReplayState::ReplayDropSchema() { // Replay Custom Type //===--------------------------------------------------------------------===// void ReplayState::ReplayCreateType() { - CreateTypeInfo info; - - info.schema = source.Read(); - info.name = source.Read(); - info.type = make_unique(LogicalType::Deserialize(source)); - + auto info = TypeCatalogEntry::Deserialize(source); if (deserialize_only) { return; } auto &catalog = Catalog::GetCatalog(context); - catalog.CreateType(context, &info); + catalog.CreateType(context, info.get()); } void ReplayState::ReplayDropType() { @@ -158993,9 +172999,9 @@ void ReplayState::ReplayDelete() { throw InternalException("Corrupt WAL: delete without table"); } - D_ASSERT(chunk.ColumnCount() == 1 && chunk.data[0].GetType() == LOGICAL_ROW_TYPE); + D_ASSERT(chunk.ColumnCount() == 1 && chunk.data[0].GetType() == LogicalType::ROW_TYPE); row_t row_ids[1]; - Vector row_identifiers(LOGICAL_ROW_TYPE, (data_ptr_t)row_ids); + Vector row_identifiers(LogicalType::ROW_TYPE, (data_ptr_t)row_ids); auto source_ids = FlatVector::GetData(chunk.data[0]); // delete the tuples from the current table @@ -159260,7 +173266,7 @@ void WriteAheadLog::WriteDelete(DataChunk &chunk) { return; } D_ASSERT(chunk.size() > 0); - D_ASSERT(chunk.ColumnCount() == 1 && chunk.data[0].GetType() == LOGICAL_ROW_TYPE); + D_ASSERT(chunk.ColumnCount() == 1 && chunk.data[0].GetType() == LogicalType::ROW_TYPE); chunk.Verify(); writer->Write(WALType::DELETE_TUPLE); @@ -159273,7 +173279,7 @@ void WriteAheadLog::WriteUpdate(DataChunk &chunk, const vector &column } D_ASSERT(chunk.size() > 0); D_ASSERT(chunk.ColumnCount() == 2); - D_ASSERT(chunk.data[1].GetType().id() == LOGICAL_ROW_TYPE.id()); + D_ASSERT(chunk.data[1].GetType().id() == LogicalType::ROW_TYPE); chunk.Verify(); writer->Write(WALType::UPDATE_TUPLE); @@ -159451,7 +173457,7 @@ void CleanupState::Flush() { } // set up the row identifiers vector - Vector row_identifiers(LOGICAL_ROW_TYPE, (data_ptr_t)row_numbers); + Vector row_identifiers(LogicalType::ROW_TYPE, (data_ptr_t)row_numbers); // delete the tuples from all the indexes current_table->RemoveFromIndexes(row_identifiers, count); @@ -159673,7 +173679,7 @@ void CommitState::WriteDelete(DeleteInfo *info) { if (!delete_chunk) { delete_chunk = make_unique(); - vector delete_types = {LOGICAL_ROW_TYPE}; + vector delete_types = {LogicalType::ROW_TYPE}; delete_chunk->Initialize(delete_types); } auto rows = FlatVector::GetData(delete_chunk->data[0]); @@ -159695,11 +173701,11 @@ void CommitState::WriteUpdate(UpdateInfo *info) { // initialize the update chunk vector update_types; if (column_data.type.id() == LogicalTypeId::VALIDITY) { - update_types.push_back(LogicalType::BOOLEAN); + update_types.emplace_back(LogicalType::BOOLEAN); } else { update_types.push_back(column_data.type); } - update_types.push_back(LOGICAL_ROW_TYPE); + update_types.emplace_back(LogicalType::ROW_TYPE); update_chunk = make_unique(); update_chunk->Initialize(update_types); @@ -196184,6 +210190,1299 @@ void sdfree(void *ptr) { free(ptr); } // LICENSE_CHANGE_END +// LICENSE_CHANGE_BEGIN +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #10 +// See the end of this file for a list + + + +#include +#include + +namespace duckdb_fastpforlib { +namespace internal { + +// Used for uint8_t, uint16_t and uint32_t +template +typename std::enable_if<(DELTA + SHR) < TYPE_SIZE>::type unpack_single_out(const TYPE *__restrict in, + TYPE *__restrict out) { + *out = ((*in) >> SHR) % (1 << DELTA); +} + +// Used for uint8_t, uint16_t and uint32_t +template +typename std::enable_if<(DELTA + SHR) >= TYPE_SIZE>::type unpack_single_out(const TYPE *__restrict &in, + TYPE *__restrict out) { + *out = (*in) >> SHR; + ++in; + + static const TYPE NEXT_SHR = SHR + DELTA - TYPE_SIZE; + *out |= ((*in) % (1U << NEXT_SHR)) << (TYPE_SIZE - SHR); +} + +template +typename std::enable_if<(DELTA + SHR) < 32>::type unpack_single_out(const uint32_t *__restrict in, + uint64_t *__restrict out) { + *out = ((static_cast(*in)) >> SHR) % (1ULL << DELTA); +} + +template +typename std::enable_if<(DELTA + SHR) >= 32 && (DELTA + SHR) < 64>::type +unpack_single_out(const uint32_t *__restrict &in, uint64_t *__restrict out) { + *out = static_cast(*in) >> SHR; + ++in; + if (DELTA + SHR > 32) { + static const uint8_t NEXT_SHR = SHR + DELTA - 32; + *out |= static_cast((*in) % (1U << NEXT_SHR)) << (32 - SHR); + } +} + +template +typename std::enable_if<(DELTA + SHR) >= 64>::type unpack_single_out(const uint32_t *__restrict &in, + uint64_t *__restrict out) { + *out = static_cast(*in) >> SHR; + ++in; + + *out |= static_cast(*in) << (32 - SHR); + ++in; + + if (DELTA + SHR > 64) { + static const uint8_t NEXT_SHR = DELTA + SHR - 64; + *out |= static_cast((*in) % (1U << NEXT_SHR)) << (64 - SHR); + } +} + +// Used for uint8_t, uint16_t and uint32_t +template + typename std::enable_if < DELTA + SHL::type pack_single_in(const TYPE in, TYPE *__restrict out) { + if (SHL == 0) { + *out = in & MASK; + } else { + *out |= (in & MASK) << SHL; + } +} + +// Used for uint8_t, uint16_t and uint32_t +template +typename std::enable_if= TYPE_SIZE>::type pack_single_in(const TYPE in, TYPE *__restrict &out) { + *out |= in << SHL; + ++out; + + if (DELTA + SHL > TYPE_SIZE) { + *out = (in & MASK) >> (TYPE_SIZE - SHL); + } +} + +template + typename std::enable_if < DELTA + SHL<32>::type pack_single_in64(const uint64_t in, uint32_t *__restrict out) { + if (SHL == 0) { + *out = static_cast(in & MASK); + } else { + *out |= (in & MASK) << SHL; + } +} +template + typename std::enable_if < DELTA + SHL >= 32 && + DELTA + SHL<64>::type pack_single_in64(const uint64_t in, uint32_t *__restrict &out) { + if (SHL == 0) { + *out = static_cast(in & MASK); + } else { + *out |= (in & MASK) << SHL; + } + + ++out; + + if (DELTA + SHL > 32) { + *out = static_cast((in & MASK) >> (32 - SHL)); + } +} +template +typename std::enable_if= 64>::type pack_single_in64(const uint64_t in, uint32_t *__restrict &out) { + *out |= in << SHL; + ++out; + + *out = static_cast((in & MASK) >> (32 - SHL)); + ++out; + + if (DELTA + SHL > 64) { + *out = (in & MASK) >> (64 - SHL); + } +} +template +struct Unroller8 { + static void Unpack(const uint8_t *__restrict &in, uint8_t *__restrict out) { + unpack_single_out(in, out + OINDEX); + + Unroller8::Unpack(in, out); + } + + static void Pack(const uint8_t *__restrict in, uint8_t *__restrict out) { + pack_single_in(in[OINDEX], out); + + Unroller8::Pack(in, out); + } + +};\ +template +struct Unroller8 { + enum { SHIFT = (DELTA * 7) % 8 }; + + static void Unpack(const uint8_t *__restrict in, uint8_t *__restrict out) { + out[7] = (*in) >> SHIFT; + } + + static void Pack(const uint8_t *__restrict in, uint8_t *__restrict out) { + *out |= (in[7] << SHIFT); + } +}; + +template +struct Unroller16 { + static void Unpack(const uint16_t *__restrict &in, uint16_t *__restrict out) { + unpack_single_out(in, out + OINDEX); + + Unroller16::Unpack(in, out); + } + + static void Pack(const uint16_t *__restrict in, uint16_t *__restrict out) { + pack_single_in(in[OINDEX], out); + + Unroller16::Pack(in, out); + } + +}; + +template +struct Unroller16 { + enum { SHIFT = (DELTA * 15) % 16 }; + + static void Unpack(const uint16_t *__restrict in, uint16_t *__restrict out) { + out[15] = (*in) >> SHIFT; + } + + static void Pack(const uint16_t *__restrict in, uint16_t *__restrict out) { + *out |= (in[15] << SHIFT); + } +}; + +template +struct Unroller { + static void Unpack(const uint32_t *__restrict &in, uint32_t *__restrict out) { + unpack_single_out(in, out + OINDEX); + + Unroller::Unpack(in, out); + } + + static void Unpack(const uint32_t *__restrict &in, uint64_t *__restrict out) { + unpack_single_out(in, out + OINDEX); + + Unroller::Unpack(in, out); + } + + static void Pack(const uint32_t *__restrict in, uint32_t *__restrict out) { + pack_single_in(in[OINDEX], out); + + Unroller::Pack(in, out); + } + + static void Pack(const uint64_t *__restrict in, uint32_t *__restrict out) { + pack_single_in64(in[OINDEX], out); + + Unroller::Pack(in, out); + } +}; + +template +struct Unroller { + enum { SHIFT = (DELTA * 31) % 32 }; + + static void Unpack(const uint32_t *__restrict in, uint32_t *__restrict out) { + out[31] = (*in) >> SHIFT; + } + + static void Unpack(const uint32_t *__restrict in, uint64_t *__restrict out) { + out[31] = (*in) >> SHIFT; + if (DELTA > 32) { + ++in; + out[31] |= static_cast(*in) << (32 - SHIFT); + } + } + + static void Pack(const uint32_t *__restrict in, uint32_t *__restrict out) { + *out |= (in[31] << SHIFT); + } + + static void Pack(const uint64_t *__restrict in, uint32_t *__restrict out) { + *out |= (in[31] << SHIFT); + if (DELTA > 32) { + ++out; + *out = static_cast(in[31] >> (32 - SHIFT)); + } + } +}; + +// Special cases +void __fastunpack0(const uint8_t *__restrict, uint8_t *__restrict out) { + for (uint8_t i = 0; i < 8; ++i) + *(out++) = 0; +} + +void __fastunpack0(const uint16_t *__restrict, uint16_t *__restrict out) { + for (uint16_t i = 0; i < 16; ++i) + *(out++) = 0; +} + +void __fastunpack0(const uint32_t *__restrict, uint32_t *__restrict out) { + for (uint32_t i = 0; i < 32; ++i) + *(out++) = 0; +} + +void __fastunpack0(const uint32_t *__restrict, uint64_t *__restrict out) { + for (uint32_t i = 0; i < 32; ++i) + *(out++) = 0; +} + +void __fastpack0(const uint8_t *__restrict, uint8_t *__restrict) { +} +void __fastpack0(const uint16_t *__restrict, uint16_t *__restrict) { +} +void __fastpack0(const uint32_t *__restrict, uint32_t *__restrict) { +} +void __fastpack0(const uint64_t *__restrict, uint32_t *__restrict) { +} + +// fastunpack for 8 bits +void __fastunpack1(const uint8_t *__restrict in, uint8_t *__restrict out) { + Unroller8<1>::Unpack(in, out); +} + +void __fastunpack2(const uint8_t *__restrict in, uint8_t *__restrict out) { + Unroller8<2>::Unpack(in, out); +} + +void __fastunpack3(const uint8_t *__restrict in, uint8_t *__restrict out) { + Unroller8<3>::Unpack(in, out); +} + +void __fastunpack4(const uint8_t *__restrict in, uint8_t *__restrict out) { + for (uint8_t outer = 0; outer < 4; ++outer) { + for (uint8_t inwordpointer = 0; inwordpointer < 8; inwordpointer += 4) + *(out++) = ((*in) >> inwordpointer) % (1U << 4); + ++in; + } +} + +void __fastunpack5(const uint8_t *__restrict in, uint8_t *__restrict out) { + Unroller8<5>::Unpack(in, out); +} + +void __fastunpack6(const uint8_t *__restrict in, uint8_t *__restrict out) { + Unroller8<6>::Unpack(in, out); +} + +void __fastunpack7(const uint8_t *__restrict in, uint8_t *__restrict out) { + Unroller8<7>::Unpack(in, out); +} + +void __fastunpack8(const uint8_t *__restrict in, uint8_t *__restrict out) { + for (int k = 0; k < 8; ++k) + out[k] = in[k]; +} + + +// fastunpack for 16 bits +void __fastunpack1(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<1>::Unpack(in, out); +} + +void __fastunpack2(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<2>::Unpack(in, out); +} + +void __fastunpack3(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<3>::Unpack(in, out); +} + +void __fastunpack4(const uint16_t *__restrict in, uint16_t *__restrict out) { + for (uint16_t outer = 0; outer < 4; ++outer) { + for (uint16_t inwordpointer = 0; inwordpointer < 16; inwordpointer += 4) + *(out++) = ((*in) >> inwordpointer) % (1U << 4); + ++in; + } +} + +void __fastunpack5(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<5>::Unpack(in, out); +} + +void __fastunpack6(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<6>::Unpack(in, out); +} + +void __fastunpack7(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<7>::Unpack(in, out); +} + +void __fastunpack8(const uint16_t *__restrict in, uint16_t *__restrict out) { + for (uint16_t outer = 0; outer < 8; ++outer) { + for (uint16_t inwordpointer = 0; inwordpointer < 16; inwordpointer += 8) + *(out++) = ((*in) >> inwordpointer) % (1U << 8); + ++in; + } +} + +void __fastunpack9(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<9>::Unpack(in, out); +} + +void __fastunpack10(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<10>::Unpack(in, out); +} + +void __fastunpack11(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<11>::Unpack(in, out); +} + +void __fastunpack12(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<12>::Unpack(in, out); +} + +void __fastunpack13(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<13>::Unpack(in, out); +} + +void __fastunpack14(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<14>::Unpack(in, out); +} + +void __fastunpack15(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<15>::Unpack(in, out); +} + +void __fastunpack16(const uint16_t *__restrict in, uint16_t *__restrict out) { + for (int k = 0; k < 16; ++k) + out[k] = in[k]; +} + +// fastunpack for 32 bits +void __fastunpack1(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<1>::Unpack(in, out); +} + +void __fastunpack2(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<2>::Unpack(in, out); +} + +void __fastunpack3(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<3>::Unpack(in, out); +} + +void __fastunpack4(const uint32_t *__restrict in, uint32_t *__restrict out) { + for (uint32_t outer = 0; outer < 4; ++outer) { + for (uint32_t inwordpointer = 0; inwordpointer < 32; inwordpointer += 4) + *(out++) = ((*in) >> inwordpointer) % (1U << 4); + ++in; + } +} + +void __fastunpack5(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<5>::Unpack(in, out); +} + +void __fastunpack6(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<6>::Unpack(in, out); +} + +void __fastunpack7(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<7>::Unpack(in, out); +} + +void __fastunpack8(const uint32_t *__restrict in, uint32_t *__restrict out) { + for (uint32_t outer = 0; outer < 8; ++outer) { + for (uint32_t inwordpointer = 0; inwordpointer < 32; inwordpointer += 8) + *(out++) = ((*in) >> inwordpointer) % (1U << 8); + ++in; + } +} + +void __fastunpack9(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<9>::Unpack(in, out); +} + +void __fastunpack10(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<10>::Unpack(in, out); +} + +void __fastunpack11(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<11>::Unpack(in, out); +} + +void __fastunpack12(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<12>::Unpack(in, out); +} + +void __fastunpack13(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<13>::Unpack(in, out); +} + +void __fastunpack14(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<14>::Unpack(in, out); +} + +void __fastunpack15(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<15>::Unpack(in, out); +} + +void __fastunpack16(const uint32_t *__restrict in, uint32_t *__restrict out) { + for (uint32_t outer = 0; outer < 16; ++outer) { + for (uint32_t inwordpointer = 0; inwordpointer < 32; inwordpointer += 16) + *(out++) = ((*in) >> inwordpointer) % (1U << 16); + ++in; + } +} + +void __fastunpack17(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<17>::Unpack(in, out); +} + +void __fastunpack18(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<18>::Unpack(in, out); +} + +void __fastunpack19(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<19>::Unpack(in, out); +} + +void __fastunpack20(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<20>::Unpack(in, out); +} + +void __fastunpack21(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<21>::Unpack(in, out); +} + +void __fastunpack22(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<22>::Unpack(in, out); +} + +void __fastunpack23(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<23>::Unpack(in, out); +} + +void __fastunpack24(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<24>::Unpack(in, out); +} + +void __fastunpack25(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<25>::Unpack(in, out); +} + +void __fastunpack26(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<26>::Unpack(in, out); +} + +void __fastunpack27(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<27>::Unpack(in, out); +} + +void __fastunpack28(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<28>::Unpack(in, out); +} + +void __fastunpack29(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<29>::Unpack(in, out); +} + +void __fastunpack30(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<30>::Unpack(in, out); +} + +void __fastunpack31(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<31>::Unpack(in, out); +} + +void __fastunpack32(const uint32_t *__restrict in, uint32_t *__restrict out) { + for (int k = 0; k < 32; ++k) + out[k] = in[k]; +} + +// fastupack for 64 bits +void __fastunpack1(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<1>::Unpack(in, out); +} + +void __fastunpack2(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<2>::Unpack(in, out); +} + +void __fastunpack3(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<3>::Unpack(in, out); +} + +void __fastunpack4(const uint32_t *__restrict in, uint64_t *__restrict out) { + for (uint32_t outer = 0; outer < 4; ++outer) { + for (uint32_t inwordpointer = 0; inwordpointer < 32; inwordpointer += 4) + *(out++) = ((*in) >> inwordpointer) % (1U << 4); + ++in; + } +} + +void __fastunpack5(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<5>::Unpack(in, out); +} + +void __fastunpack6(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<6>::Unpack(in, out); +} + +void __fastunpack7(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<7>::Unpack(in, out); +} + +void __fastunpack8(const uint32_t *__restrict in, uint64_t *__restrict out) { + for (uint32_t outer = 0; outer < 8; ++outer) { + for (uint32_t inwordpointer = 0; inwordpointer < 32; inwordpointer += 8) { + *(out++) = ((*in) >> inwordpointer) % (1U << 8); + } + ++in; + } +} + +void __fastunpack9(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<9>::Unpack(in, out); +} + +void __fastunpack10(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<10>::Unpack(in, out); +} + +void __fastunpack11(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<11>::Unpack(in, out); +} + +void __fastunpack12(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<12>::Unpack(in, out); +} + +void __fastunpack13(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<13>::Unpack(in, out); +} + +void __fastunpack14(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<14>::Unpack(in, out); +} + +void __fastunpack15(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<15>::Unpack(in, out); +} + +void __fastunpack16(const uint32_t *__restrict in, uint64_t *__restrict out) { + for (uint32_t outer = 0; outer < 16; ++outer) { + for (uint32_t inwordpointer = 0; inwordpointer < 32; inwordpointer += 16) + *(out++) = ((*in) >> inwordpointer) % (1U << 16); + ++in; + } +} + +void __fastunpack17(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<17>::Unpack(in, out); +} + +void __fastunpack18(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<18>::Unpack(in, out); +} + +void __fastunpack19(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<19>::Unpack(in, out); +} + +void __fastunpack20(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<20>::Unpack(in, out); +} + +void __fastunpack21(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<21>::Unpack(in, out); +} + +void __fastunpack22(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<22>::Unpack(in, out); +} + +void __fastunpack23(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<23>::Unpack(in, out); +} + +void __fastunpack24(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<24>::Unpack(in, out); +} + +void __fastunpack25(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<25>::Unpack(in, out); +} + +void __fastunpack26(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<26>::Unpack(in, out); +} + +void __fastunpack27(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<27>::Unpack(in, out); +} + +void __fastunpack28(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<28>::Unpack(in, out); +} + +void __fastunpack29(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<29>::Unpack(in, out); +} + +void __fastunpack30(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<30>::Unpack(in, out); +} + +void __fastunpack31(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<31>::Unpack(in, out); +} + +void __fastunpack32(const uint32_t *__restrict in, uint64_t *__restrict out) { + for (int k = 0; k < 32; ++k) + out[k] = in[k]; +} + +void __fastunpack33(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<33>::Unpack(in, out); +} + +void __fastunpack34(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<34>::Unpack(in, out); +} + +void __fastunpack35(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<35>::Unpack(in, out); +} + +void __fastunpack36(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<36>::Unpack(in, out); +} + +void __fastunpack37(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<37>::Unpack(in, out); +} + +void __fastunpack38(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<38>::Unpack(in, out); +} + +void __fastunpack39(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<39>::Unpack(in, out); +} + +void __fastunpack40(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<40>::Unpack(in, out); +} + +void __fastunpack41(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<41>::Unpack(in, out); +} + +void __fastunpack42(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<42>::Unpack(in, out); +} + +void __fastunpack43(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<43>::Unpack(in, out); +} + +void __fastunpack44(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<44>::Unpack(in, out); +} + +void __fastunpack45(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<45>::Unpack(in, out); +} + +void __fastunpack46(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<46>::Unpack(in, out); +} + +void __fastunpack47(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<47>::Unpack(in, out); +} + +void __fastunpack48(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<48>::Unpack(in, out); +} + +void __fastunpack49(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<49>::Unpack(in, out); +} + +void __fastunpack50(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<50>::Unpack(in, out); +} + +void __fastunpack51(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<51>::Unpack(in, out); +} + +void __fastunpack52(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<52>::Unpack(in, out); +} + +void __fastunpack53(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<53>::Unpack(in, out); +} + +void __fastunpack54(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<54>::Unpack(in, out); +} + +void __fastunpack55(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<55>::Unpack(in, out); +} + +void __fastunpack56(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<56>::Unpack(in, out); +} + +void __fastunpack57(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<57>::Unpack(in, out); +} + +void __fastunpack58(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<58>::Unpack(in, out); +} + +void __fastunpack59(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<59>::Unpack(in, out); +} + +void __fastunpack60(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<60>::Unpack(in, out); +} + +void __fastunpack61(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<61>::Unpack(in, out); +} + +void __fastunpack62(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<62>::Unpack(in, out); +} + +void __fastunpack63(const uint32_t *__restrict in, uint64_t *__restrict out) { + Unroller<63>::Unpack(in, out); +} + +void __fastunpack64(const uint32_t *__restrict in, uint64_t *__restrict out) { + for (int k = 0; k < 32; ++k) { + out[k] = in[k * 2]; + out[k] |= static_cast(in[k * 2 + 1]) << 32; + } +} + +// fastpack for 8 bits + +void __fastpack1(const uint8_t *__restrict in, uint8_t *__restrict out) { + Unroller8<1>::Pack(in, out); +} + +void __fastpack2(const uint8_t *__restrict in, uint8_t *__restrict out) { + Unroller8<2>::Pack(in, out); +} + +void __fastpack3(const uint8_t *__restrict in, uint8_t *__restrict out) { + Unroller8<3>::Pack(in, out); +} + +void __fastpack4(const uint8_t *__restrict in, uint8_t *__restrict out) { + Unroller8<4>::Pack(in, out); +} + +void __fastpack5(const uint8_t *__restrict in, uint8_t *__restrict out) { + Unroller8<5>::Pack(in, out); +} + +void __fastpack6(const uint8_t *__restrict in, uint8_t *__restrict out) { + Unroller8<6>::Pack(in, out); +} + +void __fastpack7(const uint8_t *__restrict in, uint8_t *__restrict out) { + Unroller8<7>::Pack(in, out); +} + +void __fastpack8(const uint8_t *__restrict in, uint8_t *__restrict out) { + for (int k = 0; k < 8; ++k) + out[k] = in[k]; +} + +// fastpack for 16 bits + +void __fastpack1(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<1>::Pack(in, out); +} + +void __fastpack2(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<2>::Pack(in, out); +} + +void __fastpack3(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<3>::Pack(in, out); +} + +void __fastpack4(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<4>::Pack(in, out); +} + +void __fastpack5(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<5>::Pack(in, out); +} + +void __fastpack6(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<6>::Pack(in, out); +} + +void __fastpack7(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<7>::Pack(in, out); +} + +void __fastpack8(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<8>::Pack(in, out); +} + +void __fastpack9(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<9>::Pack(in, out); +} + +void __fastpack10(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<10>::Pack(in, out); +} + +void __fastpack11(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<11>::Pack(in, out); +} + +void __fastpack12(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<12>::Pack(in, out); +} + +void __fastpack13(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<13>::Pack(in, out); +} + +void __fastpack14(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<14>::Pack(in, out); +} + +void __fastpack15(const uint16_t *__restrict in, uint16_t *__restrict out) { + Unroller16<15>::Pack(in, out); +} + +void __fastpack16(const uint16_t *__restrict in, uint16_t *__restrict out) { + for (int k = 0; k < 16; ++k) + out[k] = in[k]; +} + + +// fastpack for 32 bits + +void __fastpack1(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<1>::Pack(in, out); +} + +void __fastpack2(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<2>::Pack(in, out); +} + +void __fastpack3(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<3>::Pack(in, out); +} + +void __fastpack4(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<4>::Pack(in, out); +} + +void __fastpack5(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<5>::Pack(in, out); +} + +void __fastpack6(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<6>::Pack(in, out); +} + +void __fastpack7(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<7>::Pack(in, out); +} + +void __fastpack8(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<8>::Pack(in, out); +} + +void __fastpack9(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<9>::Pack(in, out); +} + +void __fastpack10(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<10>::Pack(in, out); +} + +void __fastpack11(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<11>::Pack(in, out); +} + +void __fastpack12(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<12>::Pack(in, out); +} + +void __fastpack13(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<13>::Pack(in, out); +} + +void __fastpack14(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<14>::Pack(in, out); +} + +void __fastpack15(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<15>::Pack(in, out); +} + +void __fastpack16(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<16>::Pack(in, out); +} + +void __fastpack17(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<17>::Pack(in, out); +} + +void __fastpack18(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<18>::Pack(in, out); +} + +void __fastpack19(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<19>::Pack(in, out); +} + +void __fastpack20(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<20>::Pack(in, out); +} + +void __fastpack21(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<21>::Pack(in, out); +} + +void __fastpack22(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<22>::Pack(in, out); +} + +void __fastpack23(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<23>::Pack(in, out); +} + +void __fastpack24(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<24>::Pack(in, out); +} + +void __fastpack25(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<25>::Pack(in, out); +} + +void __fastpack26(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<26>::Pack(in, out); +} + +void __fastpack27(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<27>::Pack(in, out); +} + +void __fastpack28(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<28>::Pack(in, out); +} + +void __fastpack29(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<29>::Pack(in, out); +} + +void __fastpack30(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<30>::Pack(in, out); +} + +void __fastpack31(const uint32_t *__restrict in, uint32_t *__restrict out) { + Unroller<31>::Pack(in, out); +} + +void __fastpack32(const uint32_t *__restrict in, uint32_t *__restrict out) { + for (int k = 0; k < 32; ++k) + out[k] = in[k]; +} + +// fastpack for 64 bits + +void __fastpack1(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<1>::Pack(in, out); +} + +void __fastpack2(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<2>::Pack(in, out); +} + +void __fastpack3(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<3>::Pack(in, out); +} + +void __fastpack4(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<4>::Pack(in, out); +} + +void __fastpack5(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<5>::Pack(in, out); +} + +void __fastpack6(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<6>::Pack(in, out); +} + +void __fastpack7(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<7>::Pack(in, out); +} + +void __fastpack8(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<8>::Pack(in, out); +} + +void __fastpack9(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<9>::Pack(in, out); +} + +void __fastpack10(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<10>::Pack(in, out); +} + +void __fastpack11(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<11>::Pack(in, out); +} + +void __fastpack12(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<12>::Pack(in, out); +} + +void __fastpack13(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<13>::Pack(in, out); +} + +void __fastpack14(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<14>::Pack(in, out); +} + +void __fastpack15(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<15>::Pack(in, out); +} + +void __fastpack16(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<16>::Pack(in, out); +} + +void __fastpack17(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<17>::Pack(in, out); +} + +void __fastpack18(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<18>::Pack(in, out); +} + +void __fastpack19(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<19>::Pack(in, out); +} + +void __fastpack20(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<20>::Pack(in, out); +} + +void __fastpack21(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<21>::Pack(in, out); +} + +void __fastpack22(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<22>::Pack(in, out); +} + +void __fastpack23(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<23>::Pack(in, out); +} + +void __fastpack24(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<24>::Pack(in, out); +} + +void __fastpack25(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<25>::Pack(in, out); +} + +void __fastpack26(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<26>::Pack(in, out); +} + +void __fastpack27(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<27>::Pack(in, out); +} + +void __fastpack28(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<28>::Pack(in, out); +} + +void __fastpack29(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<29>::Pack(in, out); +} + +void __fastpack30(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<30>::Pack(in, out); +} + +void __fastpack31(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<31>::Pack(in, out); +} + +void __fastpack32(const uint64_t *__restrict in, uint32_t *__restrict out) { + for (int k = 0; k < 32; ++k) { + out[k] = static_cast(in[k]); + } +} + +void __fastpack33(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<33>::Pack(in, out); +} + +void __fastpack34(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<34>::Pack(in, out); +} + +void __fastpack35(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<35>::Pack(in, out); +} + +void __fastpack36(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<36>::Pack(in, out); +} + +void __fastpack37(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<37>::Pack(in, out); +} + +void __fastpack38(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<38>::Pack(in, out); +} + +void __fastpack39(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<39>::Pack(in, out); +} + +void __fastpack40(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<40>::Pack(in, out); +} + +void __fastpack41(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<41>::Pack(in, out); +} + +void __fastpack42(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<42>::Pack(in, out); +} + +void __fastpack43(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<43>::Pack(in, out); +} + +void __fastpack44(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<44>::Pack(in, out); +} + +void __fastpack45(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<45>::Pack(in, out); +} + +void __fastpack46(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<46>::Pack(in, out); +} + +void __fastpack47(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<47>::Pack(in, out); +} + +void __fastpack48(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<48>::Pack(in, out); +} + +void __fastpack49(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<49>::Pack(in, out); +} + +void __fastpack50(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<50>::Pack(in, out); +} + +void __fastpack51(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<51>::Pack(in, out); +} + +void __fastpack52(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<52>::Pack(in, out); +} + +void __fastpack53(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<53>::Pack(in, out); +} + +void __fastpack54(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<54>::Pack(in, out); +} + +void __fastpack55(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<55>::Pack(in, out); +} + +void __fastpack56(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<56>::Pack(in, out); +} + +void __fastpack57(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<57>::Pack(in, out); +} + +void __fastpack58(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<58>::Pack(in, out); +} + +void __fastpack59(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<59>::Pack(in, out); +} + +void __fastpack60(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<60>::Pack(in, out); +} + +void __fastpack61(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<61>::Pack(in, out); +} + +void __fastpack62(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<62>::Pack(in, out); +} + +void __fastpack63(const uint64_t *__restrict in, uint32_t *__restrict out) { + Unroller<63>::Pack(in, out); +} + +void __fastpack64(const uint64_t *__restrict in, uint32_t *__restrict out) { + for (int i = 0; i < 32; ++i) { + out[2 * i] = static_cast(in[i]); + out[2 * i + 1] = in[i] >> 32; + } +} +} // namespace internal +} // namespace duckdb_fastpforlib + + +// LICENSE_CHANGE_END + + // LICENSE_CHANGE_BEGIN // The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #2 // See the end of this file for a list @@ -212031,7 +227330,7 @@ size_t Utf8Proc::RenderWidth(const char *s, size_t len, size_t pos) { // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list #include @@ -212041,7 +227340,7 @@ size_t Utf8Proc::RenderWidth(const char *s, size_t len, size_t pos) { // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list @@ -212115,7 +227414,6 @@ unsigned char *unicode_to_utf8(pg_wchar c, unsigned char *utf8string); // max parse tree size approx 100 MB, should be enough #define PG_MALLOC_SIZE 10240 -#define PG_MALLOC_LIMIT 1000 namespace duckdb_libpgquery { @@ -212127,7 +227425,8 @@ struct pg_parser_state_str { size_t malloc_pos; size_t malloc_ptr_idx; - char *malloc_ptrs[PG_MALLOC_LIMIT]; + char **malloc_ptrs; + size_t malloc_ptr_size; }; static __thread parser_state pg_parser_state; @@ -212137,8 +227436,13 @@ __thread PGNode *duckdb_newNodeMacroHolder; #endif static void allocate_new(parser_state *state, size_t n) { - if (state->malloc_ptr_idx + 1 >= PG_MALLOC_LIMIT) { - throw std::runtime_error("Memory allocation failure"); + if (state->malloc_ptr_idx >= state->malloc_ptr_size) { + size_t new_size = state->malloc_ptr_size * 2; + auto new_malloc_ptrs = (char **) malloc(sizeof(char *) * new_size); + memcpy(new_malloc_ptrs, state->malloc_ptrs, state->malloc_ptr_size * sizeof(char*)); + free(state->malloc_ptrs); + state->malloc_ptr_size = new_size; + state->malloc_ptrs = new_malloc_ptrs; } if (n < PG_MALLOC_SIZE) { n = PG_MALLOC_SIZE; @@ -212154,12 +227458,17 @@ static void allocate_new(parser_state *state, size_t n) { void *palloc(size_t n) { // we need to align our pointers for the sanitizer - auto aligned_n = ((n + 7) / 8) * 8; + auto allocate_n = n + sizeof(size_t); + auto aligned_n = ((allocate_n + 7) / 8) * 8; if (pg_parser_state.malloc_pos + aligned_n > PG_MALLOC_SIZE) { allocate_new(&pg_parser_state, aligned_n); } - void *ptr = pg_parser_state.malloc_ptrs[pg_parser_state.malloc_ptr_idx - 1] + pg_parser_state.malloc_pos; + // store the length of the allocation + char *base_ptr = pg_parser_state.malloc_ptrs[pg_parser_state.malloc_ptr_idx - 1] + pg_parser_state.malloc_pos; + memcpy(base_ptr, &n, sizeof(size_t)); + // store the actual pointer + char *ptr = (char*) base_ptr + sizeof(size_t); memset(ptr, 0, n); pg_parser_state.malloc_pos += aligned_n; return ptr; @@ -212169,6 +227478,8 @@ void pg_parser_init() { pg_parser_state.pg_err_code = PGUNDEFINED; pg_parser_state.pg_err_msg[0] = '\0'; + pg_parser_state.malloc_ptr_size = 4; + pg_parser_state.malloc_ptrs = (char **) malloc(sizeof(char *) * pg_parser_state.malloc_ptr_size); pg_parser_state.malloc_ptr_idx = 0; allocate_new(&pg_parser_state, 1); } @@ -212178,8 +227489,16 @@ void pg_parser_parse(const char *query, parse_result *res) { try { res->parse_tree = duckdb_libpgquery::raw_parser(query); res->success = pg_parser_state.pg_err_code == PGUNDEFINED; - } catch (...) { + } catch (std::exception &ex) { res->success = false; + // copy the error message of the exception + auto error_message = ex.what(); + uint32_t pos = 0; + while(pos < 1023 && error_message[pos]) { + pg_parser_state.pg_err_msg[pos] = error_message[pos]; + pos++; + } + pg_parser_state.pg_err_msg[pos] = '\0'; } res->error_message = pg_parser_state.pg_err_msg; res->error_location = pg_parser_state.pg_err_pos; @@ -212193,6 +227512,7 @@ void pg_parser_cleanup() { pg_parser_state.malloc_ptrs[ptr_idx] = nullptr; } } + free(pg_parser_state.malloc_ptrs); } int ereport(int code, ...) { @@ -212261,7 +227581,14 @@ void *palloc0fast(size_t n) { // very fast return palloc(n); } void *repalloc(void *ptr, size_t n) { - return palloc(n); + // get the length of the allocation + size_t old_len; + char *old_len_ptr = (char *) ptr - sizeof(size_t); + memcpy((void *) &old_len, old_len_ptr, sizeof(size_t)); + // re-allocate and copy the data + void *new_buf = palloc(n); + memcpy(new_buf, ptr, old_len); + return new_buf; } char *NameListToString(PGList *names) { throw std::runtime_error("NameListToString NOT IMPLEMENTED"); @@ -212341,7 +227668,7 @@ PGNode *newNode(size_t size, PGNodeTag type) { // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list @@ -212351,7 +227678,46 @@ PGNode *newNode(size_t size, PGNodeTag type) { // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 +// See the end of this file for a list + +/*------------------------------------------------------------------------- + * + * scansup.h + * scanner support routines. used by both the bootstrap lexer + * as well as the normal lexer + * + * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/parser/scansup.h + * + *------------------------------------------------------------------------- + */ + + + +namespace duckdb_libpgquery { + +char *scanstr(const char *s); + +char *downcase_truncate_identifier(const char *ident, int len, bool warn); + +char *downcase_identifier(const char *ident, int len, bool warn, bool truncate); + +bool scanner_isspace(char ch); + +void set_preserve_identifier_case(bool downcase); +bool get_preserve_identifier_case(); + +} + +// LICENSE_CHANGE_END + + + +// LICENSE_CHANGE_BEGIN +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /*------------------------------------------------------------------------- @@ -212426,6 +227792,14 @@ bool PostgresParser::IsKeyword(const std::string &text) { return duckdb_libpgquery::is_keyword(text.c_str()); } +vector PostgresParser::KeywordList() { + return duckdb_libpgquery::keyword_list(); +} + +void PostgresParser::SetPreserveIdentifierCase(bool preserve) { + duckdb_libpgquery::set_preserve_identifier_case(preserve); +} + } @@ -212433,7 +227807,7 @@ bool PostgresParser::IsKeyword(const std::string &text) { // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /*-------------------------------------------------------------------- @@ -212981,7 +228355,7 @@ int length(const PGList *list); // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /*-------------------------------------------------------------------- @@ -213022,7 +228396,7 @@ int length(const PGList *list); // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /*------------------------------------------------------------------------- @@ -213057,7 +228431,7 @@ typedef struct PGFunctionCallInfoData *PGFunctionCallInfo; // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /*------------------------------------------------------------------------- @@ -213135,7 +228509,7 @@ PGGroupingSet *makeGroupingSet(GroupingSetKind kind, PGList *content, int locati // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /*------------------------------------------------------------------------- @@ -213482,7 +228856,7 @@ PGGroupingSet *makeGroupingSet(GroupingSetKind kind, PGList *content, int locati // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /*-------------------------------------------------------------------- @@ -213564,7 +228938,7 @@ PGValue *makeString(const char *str) { // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /* A Bison parser, made by GNU Bison 2.3. */ @@ -213828,296 +229202,300 @@ PGValue *makeString(const char *str) { HOURS_P = 440, IDENTITY_P = 441, IF_P = 442, - ILIKE = 443, - IMMEDIATE = 444, - IMMUTABLE = 445, - IMPLICIT_P = 446, - IMPORT_P = 447, - IN_P = 448, - INCLUDING = 449, - INCREMENT = 450, - INDEX = 451, - INDEXES = 452, - INHERIT = 453, - INHERITS = 454, - INITIALLY = 455, - INLINE_P = 456, - INNER_P = 457, - INOUT = 458, - INPUT_P = 459, - INSENSITIVE = 460, - INSERT = 461, - INSTEAD = 462, - INT_P = 463, - INTEGER = 464, - INTERSECT = 465, - INTERVAL = 466, - INTO = 467, - INVOKER = 468, - IS = 469, - ISNULL = 470, - ISOLATION = 471, - JOIN = 472, - KEY = 473, - LABEL = 474, - LANGUAGE = 475, - LARGE_P = 476, - LAST_P = 477, - LATERAL_P = 478, - LEADING = 479, - LEAKPROOF = 480, - LEFT = 481, - LEVEL = 482, - LIKE = 483, - LIMIT = 484, - LISTEN = 485, - LOAD = 486, - LOCAL = 487, - LOCALTIME = 488, - LOCALTIMESTAMP = 489, - LOCATION = 490, - LOCK_P = 491, - LOCKED = 492, - LOGGED = 493, - MACRO = 494, - MAP = 495, - MAPPING = 496, - MATCH = 497, - MATERIALIZED = 498, - MAXVALUE = 499, - METHOD = 500, - MICROSECOND_P = 501, - MICROSECONDS_P = 502, - MILLISECOND_P = 503, - MILLISECONDS_P = 504, - MINUTE_P = 505, - MINUTES_P = 506, - MINVALUE = 507, - MODE = 508, - MONTH_P = 509, - MONTHS_P = 510, - MOVE = 511, - NAME_P = 512, - NAMES = 513, - NATIONAL = 514, - NATURAL = 515, - NCHAR = 516, - NEW = 517, - NEXT = 518, - NO = 519, - NONE = 520, - NOT = 521, - NOTHING = 522, - NOTIFY = 523, - NOTNULL = 524, - NOWAIT = 525, - NULL_P = 526, - NULLIF = 527, - NULLS_P = 528, - NUMERIC = 529, - OBJECT_P = 530, - OF = 531, - OFF = 532, - OFFSET = 533, - OIDS = 534, - OLD = 535, - ON = 536, - ONLY = 537, - OPERATOR = 538, - OPTION = 539, - OPTIONS = 540, - OR = 541, - ORDER = 542, - ORDINALITY = 543, - OUT_P = 544, - OUTER_P = 545, - OVER = 546, - OVERLAPS = 547, - OVERLAY = 548, - OVERRIDING = 549, - OWNED = 550, - OWNER = 551, - PARALLEL = 552, - PARSER = 553, - PARTIAL = 554, - PARTITION = 555, - PASSING = 556, - PASSWORD = 557, - PERCENT = 558, - PLACING = 559, - PLANS = 560, - POLICY = 561, - POSITION = 562, - PRAGMA_P = 563, - PRECEDING = 564, - PRECISION = 565, - PREPARE = 566, - PREPARED = 567, - PRESERVE = 568, - PRIMARY = 569, - PRIOR = 570, - PRIVILEGES = 571, - PROCEDURAL = 572, - PROCEDURE = 573, - PROGRAM = 574, - PUBLICATION = 575, - QUOTE = 576, - RANGE = 577, - READ_P = 578, - REAL = 579, - REASSIGN = 580, - RECHECK = 581, - RECURSIVE = 582, - REF = 583, - REFERENCES = 584, - REFERENCING = 585, - REFRESH = 586, - REINDEX = 587, - RELATIVE_P = 588, - RELEASE = 589, - RENAME = 590, - REPEATABLE = 591, - REPLACE = 592, - REPLICA = 593, - RESET = 594, - RESTART = 595, - RESTRICT = 596, - RETURNING = 597, - RETURNS = 598, - REVOKE = 599, - RIGHT = 600, - ROLE = 601, - ROLLBACK = 602, - ROLLUP = 603, - ROW = 604, - ROWS = 605, - RULE = 606, - SAMPLE = 607, - SAVEPOINT = 608, - SCHEMA = 609, - SCHEMAS = 610, - SCROLL = 611, - SEARCH = 612, - SECOND_P = 613, - SECONDS_P = 614, - SECURITY = 615, - SELECT = 616, - SEQUENCE = 617, - SEQUENCES = 618, - SERIALIZABLE = 619, - SERVER = 620, - SESSION = 621, - SESSION_USER = 622, - SET = 623, - SETOF = 624, - SETS = 625, - SHARE = 626, - SHOW = 627, - SIMILAR = 628, - SIMPLE = 629, - SKIP = 630, - SMALLINT = 631, - SNAPSHOT = 632, - SOME = 633, - SQL_P = 634, - STABLE = 635, - STANDALONE_P = 636, - START = 637, - STATEMENT = 638, - STATISTICS = 639, - STDIN = 640, - STDOUT = 641, - STORAGE = 642, - STRICT_P = 643, - STRIP_P = 644, - STRUCT = 645, - SUBSCRIPTION = 646, - SUBSTRING = 647, - SUMMARIZE = 648, - SYMMETRIC = 649, - SYSID = 650, - SYSTEM_P = 651, - TABLE = 652, - TABLES = 653, - TABLESAMPLE = 654, - TABLESPACE = 655, - TEMP = 656, - TEMPLATE = 657, - TEMPORARY = 658, - TEXT_P = 659, - THEN = 660, - TIME = 661, - TIMESTAMP = 662, - TO = 663, - TRAILING = 664, - TRANSACTION = 665, - TRANSFORM = 666, - TREAT = 667, - TRIGGER = 668, - TRIM = 669, - TRUE_P = 670, - TRUNCATE = 671, - TRUSTED = 672, - TRY_CAST = 673, - TYPE_P = 674, - TYPES_P = 675, - UNBOUNDED = 676, - UNCOMMITTED = 677, - UNENCRYPTED = 678, - UNION = 679, - UNIQUE = 680, - UNKNOWN = 681, - UNLISTEN = 682, - UNLOGGED = 683, - UNTIL = 684, - UPDATE = 685, - USER = 686, - USING = 687, - VACUUM = 688, - VALID = 689, - VALIDATE = 690, - VALIDATOR = 691, - VALUE_P = 692, - VALUES = 693, - VARCHAR = 694, - VARIADIC = 695, - VARYING = 696, - VERBOSE = 697, - VERSION_P = 698, - VIEW = 699, - VIEWS = 700, - VOLATILE = 701, - WHEN = 702, - WHERE = 703, - WHITESPACE_P = 704, - WINDOW = 705, - WITH = 706, - WITHIN = 707, - WITHOUT = 708, - WORK = 709, - WRAPPER = 710, - WRITE_P = 711, - XML_P = 712, - XMLATTRIBUTES = 713, - XMLCONCAT = 714, - XMLELEMENT = 715, - XMLEXISTS = 716, - XMLFOREST = 717, - XMLNAMESPACES = 718, - XMLPARSE = 719, - XMLPI = 720, - XMLROOT = 721, - XMLSERIALIZE = 722, - XMLTABLE = 723, - YEAR_P = 724, - YEARS_P = 725, - YES_P = 726, - ZONE = 727, - NOT_LA = 728, - NULLS_LA = 729, - WITH_LA = 730, - POSTFIXOP = 731, - UMINUS = 732 + IGNORE_P = 443, + ILIKE = 444, + IMMEDIATE = 445, + IMMUTABLE = 446, + IMPLICIT_P = 447, + IMPORT_P = 448, + IN_P = 449, + INCLUDING = 450, + INCREMENT = 451, + INDEX = 452, + INDEXES = 453, + INHERIT = 454, + INHERITS = 455, + INITIALLY = 456, + INLINE_P = 457, + INNER_P = 458, + INOUT = 459, + INPUT_P = 460, + INSENSITIVE = 461, + INSERT = 462, + INSTALL = 463, + INSTEAD = 464, + INT_P = 465, + INTEGER = 466, + INTERSECT = 467, + INTERVAL = 468, + INTO = 469, + INVOKER = 470, + IS = 471, + ISNULL = 472, + ISOLATION = 473, + JOIN = 474, + KEY = 475, + LABEL = 476, + LANGUAGE = 477, + LARGE_P = 478, + LAST_P = 479, + LATERAL_P = 480, + LEADING = 481, + LEAKPROOF = 482, + LEFT = 483, + LEVEL = 484, + LIKE = 485, + LIMIT = 486, + LISTEN = 487, + LOAD = 488, + LOCAL = 489, + LOCALTIME = 490, + LOCALTIMESTAMP = 491, + LOCATION = 492, + LOCK_P = 493, + LOCKED = 494, + LOGGED = 495, + MACRO = 496, + MAP = 497, + MAPPING = 498, + MATCH = 499, + MATERIALIZED = 500, + MAXVALUE = 501, + METHOD = 502, + MICROSECOND_P = 503, + MICROSECONDS_P = 504, + MILLISECOND_P = 505, + MILLISECONDS_P = 506, + MINUTE_P = 507, + MINUTES_P = 508, + MINVALUE = 509, + MODE = 510, + MONTH_P = 511, + MONTHS_P = 512, + MOVE = 513, + NAME_P = 514, + NAMES = 515, + NATIONAL = 516, + NATURAL = 517, + NCHAR = 518, + NEW = 519, + NEXT = 520, + NO = 521, + NONE = 522, + NOT = 523, + NOTHING = 524, + NOTIFY = 525, + NOTNULL = 526, + NOWAIT = 527, + NULL_P = 528, + NULLIF = 529, + NULLS_P = 530, + NUMERIC = 531, + OBJECT_P = 532, + OF = 533, + OFF = 534, + OFFSET = 535, + OIDS = 536, + OLD = 537, + ON = 538, + ONLY = 539, + OPERATOR = 540, + OPTION = 541, + OPTIONS = 542, + OR = 543, + ORDER = 544, + ORDINALITY = 545, + OUT_P = 546, + OUTER_P = 547, + OVER = 548, + OVERLAPS = 549, + OVERLAY = 550, + OVERRIDING = 551, + OWNED = 552, + OWNER = 553, + PARALLEL = 554, + PARSER = 555, + PARTIAL = 556, + PARTITION = 557, + PASSING = 558, + PASSWORD = 559, + PERCENT = 560, + PLACING = 561, + PLANS = 562, + POLICY = 563, + POSITION = 564, + PRAGMA_P = 565, + PRECEDING = 566, + PRECISION = 567, + PREPARE = 568, + PREPARED = 569, + PRESERVE = 570, + PRIMARY = 571, + PRIOR = 572, + PRIVILEGES = 573, + PROCEDURAL = 574, + PROCEDURE = 575, + PROGRAM = 576, + PUBLICATION = 577, + QUALIFY = 578, + QUOTE = 579, + RANGE = 580, + READ_P = 581, + REAL = 582, + REASSIGN = 583, + RECHECK = 584, + RECURSIVE = 585, + REF = 586, + REFERENCES = 587, + REFERENCING = 588, + REFRESH = 589, + REINDEX = 590, + RELATIVE_P = 591, + RELEASE = 592, + RENAME = 593, + REPEATABLE = 594, + REPLACE = 595, + REPLICA = 596, + RESET = 597, + RESPECT_P = 598, + RESTART = 599, + RESTRICT = 600, + RETURNING = 601, + RETURNS = 602, + REVOKE = 603, + RIGHT = 604, + ROLE = 605, + ROLLBACK = 606, + ROLLUP = 607, + ROW = 608, + ROWS = 609, + RULE = 610, + SAMPLE = 611, + SAVEPOINT = 612, + SCHEMA = 613, + SCHEMAS = 614, + SCROLL = 615, + SEARCH = 616, + SECOND_P = 617, + SECONDS_P = 618, + SECURITY = 619, + SELECT = 620, + SEQUENCE = 621, + SEQUENCES = 622, + SERIALIZABLE = 623, + SERVER = 624, + SESSION = 625, + SESSION_USER = 626, + SET = 627, + SETOF = 628, + SETS = 629, + SHARE = 630, + SHOW = 631, + SIMILAR = 632, + SIMPLE = 633, + SKIP = 634, + SMALLINT = 635, + SNAPSHOT = 636, + SOME = 637, + SQL_P = 638, + STABLE = 639, + STANDALONE_P = 640, + START = 641, + STATEMENT = 642, + STATISTICS = 643, + STDIN = 644, + STDOUT = 645, + STORAGE = 646, + STRICT_P = 647, + STRIP_P = 648, + STRUCT = 649, + SUBSCRIPTION = 650, + SUBSTRING = 651, + SUMMARIZE = 652, + SYMMETRIC = 653, + SYSID = 654, + SYSTEM_P = 655, + TABLE = 656, + TABLES = 657, + TABLESAMPLE = 658, + TABLESPACE = 659, + TEMP = 660, + TEMPLATE = 661, + TEMPORARY = 662, + TEXT_P = 663, + THEN = 664, + TIME = 665, + TIMESTAMP = 666, + TO = 667, + TRAILING = 668, + TRANSACTION = 669, + TRANSFORM = 670, + TREAT = 671, + TRIGGER = 672, + TRIM = 673, + TRUE_P = 674, + TRUNCATE = 675, + TRUSTED = 676, + TRY_CAST = 677, + TYPE_P = 678, + TYPES_P = 679, + UNBOUNDED = 680, + UNCOMMITTED = 681, + UNENCRYPTED = 682, + UNION = 683, + UNIQUE = 684, + UNKNOWN = 685, + UNLISTEN = 686, + UNLOGGED = 687, + UNTIL = 688, + UPDATE = 689, + USER = 690, + USING = 691, + VACUUM = 692, + VALID = 693, + VALIDATE = 694, + VALIDATOR = 695, + VALUE_P = 696, + VALUES = 697, + VARCHAR = 698, + VARIADIC = 699, + VARYING = 700, + VERBOSE = 701, + VERSION_P = 702, + VIEW = 703, + VIEWS = 704, + VOLATILE = 705, + WHEN = 706, + WHERE = 707, + WHITESPACE_P = 708, + WINDOW = 709, + WITH = 710, + WITHIN = 711, + WITHOUT = 712, + WORK = 713, + WRAPPER = 714, + WRITE_P = 715, + XML_P = 716, + XMLATTRIBUTES = 717, + XMLCONCAT = 718, + XMLELEMENT = 719, + XMLEXISTS = 720, + XMLFOREST = 721, + XMLNAMESPACES = 722, + XMLPARSE = 723, + XMLPI = 724, + XMLROOT = 725, + XMLSERIALIZE = 726, + XMLTABLE = 727, + YEAR_P = 728, + YEARS_P = 729, + YES_P = 730, + ZONE = 731, + NOT_LA = 732, + NULLS_LA = 733, + WITH_LA = 734, + POSTFIXOP = 735, + UMINUS = 736 }; #endif /* Tokens. */ @@ -214306,296 +229684,300 @@ PGValue *makeString(const char *str) { #define HOURS_P 440 #define IDENTITY_P 441 #define IF_P 442 -#define ILIKE 443 -#define IMMEDIATE 444 -#define IMMUTABLE 445 -#define IMPLICIT_P 446 -#define IMPORT_P 447 -#define IN_P 448 -#define INCLUDING 449 -#define INCREMENT 450 -#define INDEX 451 -#define INDEXES 452 -#define INHERIT 453 -#define INHERITS 454 -#define INITIALLY 455 -#define INLINE_P 456 -#define INNER_P 457 -#define INOUT 458 -#define INPUT_P 459 -#define INSENSITIVE 460 -#define INSERT 461 -#define INSTEAD 462 -#define INT_P 463 -#define INTEGER 464 -#define INTERSECT 465 -#define INTERVAL 466 -#define INTO 467 -#define INVOKER 468 -#define IS 469 -#define ISNULL 470 -#define ISOLATION 471 -#define JOIN 472 -#define KEY 473 -#define LABEL 474 -#define LANGUAGE 475 -#define LARGE_P 476 -#define LAST_P 477 -#define LATERAL_P 478 -#define LEADING 479 -#define LEAKPROOF 480 -#define LEFT 481 -#define LEVEL 482 -#define LIKE 483 -#define LIMIT 484 -#define LISTEN 485 -#define LOAD 486 -#define LOCAL 487 -#define LOCALTIME 488 -#define LOCALTIMESTAMP 489 -#define LOCATION 490 -#define LOCK_P 491 -#define LOCKED 492 -#define LOGGED 493 -#define MACRO 494 -#define MAP 495 -#define MAPPING 496 -#define MATCH 497 -#define MATERIALIZED 498 -#define MAXVALUE 499 -#define METHOD 500 -#define MICROSECOND_P 501 -#define MICROSECONDS_P 502 -#define MILLISECOND_P 503 -#define MILLISECONDS_P 504 -#define MINUTE_P 505 -#define MINUTES_P 506 -#define MINVALUE 507 -#define MODE 508 -#define MONTH_P 509 -#define MONTHS_P 510 -#define MOVE 511 -#define NAME_P 512 -#define NAMES 513 -#define NATIONAL 514 -#define NATURAL 515 -#define NCHAR 516 -#define NEW 517 -#define NEXT 518 -#define NO 519 -#define NONE 520 -#define NOT 521 -#define NOTHING 522 -#define NOTIFY 523 -#define NOTNULL 524 -#define NOWAIT 525 -#define NULL_P 526 -#define NULLIF 527 -#define NULLS_P 528 -#define NUMERIC 529 -#define OBJECT_P 530 -#define OF 531 -#define OFF 532 -#define OFFSET 533 -#define OIDS 534 -#define OLD 535 -#define ON 536 -#define ONLY 537 -#define OPERATOR 538 -#define OPTION 539 -#define OPTIONS 540 -#define OR 541 -#define ORDER 542 -#define ORDINALITY 543 -#define OUT_P 544 -#define OUTER_P 545 -#define OVER 546 -#define OVERLAPS 547 -#define OVERLAY 548 -#define OVERRIDING 549 -#define OWNED 550 -#define OWNER 551 -#define PARALLEL 552 -#define PARSER 553 -#define PARTIAL 554 -#define PARTITION 555 -#define PASSING 556 -#define PASSWORD 557 -#define PERCENT 558 -#define PLACING 559 -#define PLANS 560 -#define POLICY 561 -#define POSITION 562 -#define PRAGMA_P 563 -#define PRECEDING 564 -#define PRECISION 565 -#define PREPARE 566 -#define PREPARED 567 -#define PRESERVE 568 -#define PRIMARY 569 -#define PRIOR 570 -#define PRIVILEGES 571 -#define PROCEDURAL 572 -#define PROCEDURE 573 -#define PROGRAM 574 -#define PUBLICATION 575 -#define QUOTE 576 -#define RANGE 577 -#define READ_P 578 -#define REAL 579 -#define REASSIGN 580 -#define RECHECK 581 -#define RECURSIVE 582 -#define REF 583 -#define REFERENCES 584 -#define REFERENCING 585 -#define REFRESH 586 -#define REINDEX 587 -#define RELATIVE_P 588 -#define RELEASE 589 -#define RENAME 590 -#define REPEATABLE 591 -#define REPLACE 592 -#define REPLICA 593 -#define RESET 594 -#define RESTART 595 -#define RESTRICT 596 -#define RETURNING 597 -#define RETURNS 598 -#define REVOKE 599 -#define RIGHT 600 -#define ROLE 601 -#define ROLLBACK 602 -#define ROLLUP 603 -#define ROW 604 -#define ROWS 605 -#define RULE 606 -#define SAMPLE 607 -#define SAVEPOINT 608 -#define SCHEMA 609 -#define SCHEMAS 610 -#define SCROLL 611 -#define SEARCH 612 -#define SECOND_P 613 -#define SECONDS_P 614 -#define SECURITY 615 -#define SELECT 616 -#define SEQUENCE 617 -#define SEQUENCES 618 -#define SERIALIZABLE 619 -#define SERVER 620 -#define SESSION 621 -#define SESSION_USER 622 -#define SET 623 -#define SETOF 624 -#define SETS 625 -#define SHARE 626 -#define SHOW 627 -#define SIMILAR 628 -#define SIMPLE 629 -#define SKIP 630 -#define SMALLINT 631 -#define SNAPSHOT 632 -#define SOME 633 -#define SQL_P 634 -#define STABLE 635 -#define STANDALONE_P 636 -#define START 637 -#define STATEMENT 638 -#define STATISTICS 639 -#define STDIN 640 -#define STDOUT 641 -#define STORAGE 642 -#define STRICT_P 643 -#define STRIP_P 644 -#define STRUCT 645 -#define SUBSCRIPTION 646 -#define SUBSTRING 647 -#define SUMMARIZE 648 -#define SYMMETRIC 649 -#define SYSID 650 -#define SYSTEM_P 651 -#define TABLE 652 -#define TABLES 653 -#define TABLESAMPLE 654 -#define TABLESPACE 655 -#define TEMP 656 -#define TEMPLATE 657 -#define TEMPORARY 658 -#define TEXT_P 659 -#define THEN 660 -#define TIME 661 -#define TIMESTAMP 662 -#define TO 663 -#define TRAILING 664 -#define TRANSACTION 665 -#define TRANSFORM 666 -#define TREAT 667 -#define TRIGGER 668 -#define TRIM 669 -#define TRUE_P 670 -#define TRUNCATE 671 -#define TRUSTED 672 -#define TRY_CAST 673 -#define TYPE_P 674 -#define TYPES_P 675 -#define UNBOUNDED 676 -#define UNCOMMITTED 677 -#define UNENCRYPTED 678 -#define UNION 679 -#define UNIQUE 680 -#define UNKNOWN 681 -#define UNLISTEN 682 -#define UNLOGGED 683 -#define UNTIL 684 -#define UPDATE 685 -#define USER 686 -#define USING 687 -#define VACUUM 688 -#define VALID 689 -#define VALIDATE 690 -#define VALIDATOR 691 -#define VALUE_P 692 -#define VALUES 693 -#define VARCHAR 694 -#define VARIADIC 695 -#define VARYING 696 -#define VERBOSE 697 -#define VERSION_P 698 -#define VIEW 699 -#define VIEWS 700 -#define VOLATILE 701 -#define WHEN 702 -#define WHERE 703 -#define WHITESPACE_P 704 -#define WINDOW 705 -#define WITH 706 -#define WITHIN 707 -#define WITHOUT 708 -#define WORK 709 -#define WRAPPER 710 -#define WRITE_P 711 -#define XML_P 712 -#define XMLATTRIBUTES 713 -#define XMLCONCAT 714 -#define XMLELEMENT 715 -#define XMLEXISTS 716 -#define XMLFOREST 717 -#define XMLNAMESPACES 718 -#define XMLPARSE 719 -#define XMLPI 720 -#define XMLROOT 721 -#define XMLSERIALIZE 722 -#define XMLTABLE 723 -#define YEAR_P 724 -#define YEARS_P 725 -#define YES_P 726 -#define ZONE 727 -#define NOT_LA 728 -#define NULLS_LA 729 -#define WITH_LA 730 -#define POSTFIXOP 731 -#define UMINUS 732 +#define IGNORE_P 443 +#define ILIKE 444 +#define IMMEDIATE 445 +#define IMMUTABLE 446 +#define IMPLICIT_P 447 +#define IMPORT_P 448 +#define IN_P 449 +#define INCLUDING 450 +#define INCREMENT 451 +#define INDEX 452 +#define INDEXES 453 +#define INHERIT 454 +#define INHERITS 455 +#define INITIALLY 456 +#define INLINE_P 457 +#define INNER_P 458 +#define INOUT 459 +#define INPUT_P 460 +#define INSENSITIVE 461 +#define INSERT 462 +#define INSTALL 463 +#define INSTEAD 464 +#define INT_P 465 +#define INTEGER 466 +#define INTERSECT 467 +#define INTERVAL 468 +#define INTO 469 +#define INVOKER 470 +#define IS 471 +#define ISNULL 472 +#define ISOLATION 473 +#define JOIN 474 +#define KEY 475 +#define LABEL 476 +#define LANGUAGE 477 +#define LARGE_P 478 +#define LAST_P 479 +#define LATERAL_P 480 +#define LEADING 481 +#define LEAKPROOF 482 +#define LEFT 483 +#define LEVEL 484 +#define LIKE 485 +#define LIMIT 486 +#define LISTEN 487 +#define LOAD 488 +#define LOCAL 489 +#define LOCALTIME 490 +#define LOCALTIMESTAMP 491 +#define LOCATION 492 +#define LOCK_P 493 +#define LOCKED 494 +#define LOGGED 495 +#define MACRO 496 +#define MAP 497 +#define MAPPING 498 +#define MATCH 499 +#define MATERIALIZED 500 +#define MAXVALUE 501 +#define METHOD 502 +#define MICROSECOND_P 503 +#define MICROSECONDS_P 504 +#define MILLISECOND_P 505 +#define MILLISECONDS_P 506 +#define MINUTE_P 507 +#define MINUTES_P 508 +#define MINVALUE 509 +#define MODE 510 +#define MONTH_P 511 +#define MONTHS_P 512 +#define MOVE 513 +#define NAME_P 514 +#define NAMES 515 +#define NATIONAL 516 +#define NATURAL 517 +#define NCHAR 518 +#define NEW 519 +#define NEXT 520 +#define NO 521 +#define NONE 522 +#define NOT 523 +#define NOTHING 524 +#define NOTIFY 525 +#define NOTNULL 526 +#define NOWAIT 527 +#define NULL_P 528 +#define NULLIF 529 +#define NULLS_P 530 +#define NUMERIC 531 +#define OBJECT_P 532 +#define OF 533 +#define OFF 534 +#define OFFSET 535 +#define OIDS 536 +#define OLD 537 +#define ON 538 +#define ONLY 539 +#define OPERATOR 540 +#define OPTION 541 +#define OPTIONS 542 +#define OR 543 +#define ORDER 544 +#define ORDINALITY 545 +#define OUT_P 546 +#define OUTER_P 547 +#define OVER 548 +#define OVERLAPS 549 +#define OVERLAY 550 +#define OVERRIDING 551 +#define OWNED 552 +#define OWNER 553 +#define PARALLEL 554 +#define PARSER 555 +#define PARTIAL 556 +#define PARTITION 557 +#define PASSING 558 +#define PASSWORD 559 +#define PERCENT 560 +#define PLACING 561 +#define PLANS 562 +#define POLICY 563 +#define POSITION 564 +#define PRAGMA_P 565 +#define PRECEDING 566 +#define PRECISION 567 +#define PREPARE 568 +#define PREPARED 569 +#define PRESERVE 570 +#define PRIMARY 571 +#define PRIOR 572 +#define PRIVILEGES 573 +#define PROCEDURAL 574 +#define PROCEDURE 575 +#define PROGRAM 576 +#define PUBLICATION 577 +#define QUALIFY 578 +#define QUOTE 579 +#define RANGE 580 +#define READ_P 581 +#define REAL 582 +#define REASSIGN 583 +#define RECHECK 584 +#define RECURSIVE 585 +#define REF 586 +#define REFERENCES 587 +#define REFERENCING 588 +#define REFRESH 589 +#define REINDEX 590 +#define RELATIVE_P 591 +#define RELEASE 592 +#define RENAME 593 +#define REPEATABLE 594 +#define REPLACE 595 +#define REPLICA 596 +#define RESET 597 +#define RESPECT_P 598 +#define RESTART 599 +#define RESTRICT 600 +#define RETURNING 601 +#define RETURNS 602 +#define REVOKE 603 +#define RIGHT 604 +#define ROLE 605 +#define ROLLBACK 606 +#define ROLLUP 607 +#define ROW 608 +#define ROWS 609 +#define RULE 610 +#define SAMPLE 611 +#define SAVEPOINT 612 +#define SCHEMA 613 +#define SCHEMAS 614 +#define SCROLL 615 +#define SEARCH 616 +#define SECOND_P 617 +#define SECONDS_P 618 +#define SECURITY 619 +#define SELECT 620 +#define SEQUENCE 621 +#define SEQUENCES 622 +#define SERIALIZABLE 623 +#define SERVER 624 +#define SESSION 625 +#define SESSION_USER 626 +#define SET 627 +#define SETOF 628 +#define SETS 629 +#define SHARE 630 +#define SHOW 631 +#define SIMILAR 632 +#define SIMPLE 633 +#define SKIP 634 +#define SMALLINT 635 +#define SNAPSHOT 636 +#define SOME 637 +#define SQL_P 638 +#define STABLE 639 +#define STANDALONE_P 640 +#define START 641 +#define STATEMENT 642 +#define STATISTICS 643 +#define STDIN 644 +#define STDOUT 645 +#define STORAGE 646 +#define STRICT_P 647 +#define STRIP_P 648 +#define STRUCT 649 +#define SUBSCRIPTION 650 +#define SUBSTRING 651 +#define SUMMARIZE 652 +#define SYMMETRIC 653 +#define SYSID 654 +#define SYSTEM_P 655 +#define TABLE 656 +#define TABLES 657 +#define TABLESAMPLE 658 +#define TABLESPACE 659 +#define TEMP 660 +#define TEMPLATE 661 +#define TEMPORARY 662 +#define TEXT_P 663 +#define THEN 664 +#define TIME 665 +#define TIMESTAMP 666 +#define TO 667 +#define TRAILING 668 +#define TRANSACTION 669 +#define TRANSFORM 670 +#define TREAT 671 +#define TRIGGER 672 +#define TRIM 673 +#define TRUE_P 674 +#define TRUNCATE 675 +#define TRUSTED 676 +#define TRY_CAST 677 +#define TYPE_P 678 +#define TYPES_P 679 +#define UNBOUNDED 680 +#define UNCOMMITTED 681 +#define UNENCRYPTED 682 +#define UNION 683 +#define UNIQUE 684 +#define UNKNOWN 685 +#define UNLISTEN 686 +#define UNLOGGED 687 +#define UNTIL 688 +#define UPDATE 689 +#define USER 690 +#define USING 691 +#define VACUUM 692 +#define VALID 693 +#define VALIDATE 694 +#define VALIDATOR 695 +#define VALUE_P 696 +#define VALUES 697 +#define VARCHAR 698 +#define VARIADIC 699 +#define VARYING 700 +#define VERBOSE 701 +#define VERSION_P 702 +#define VIEW 703 +#define VIEWS 704 +#define VOLATILE 705 +#define WHEN 706 +#define WHERE 707 +#define WHITESPACE_P 708 +#define WINDOW 709 +#define WITH 710 +#define WITHIN 711 +#define WITHOUT 712 +#define WORK 713 +#define WRAPPER 714 +#define WRITE_P 715 +#define XML_P 716 +#define XMLATTRIBUTES 717 +#define XMLCONCAT 718 +#define XMLELEMENT 719 +#define XMLEXISTS 720 +#define XMLFOREST 721 +#define XMLNAMESPACES 722 +#define XMLPARSE 723 +#define XMLPI 724 +#define XMLROOT 725 +#define XMLSERIALIZE 726 +#define XMLTABLE 727 +#define YEAR_P 728 +#define YEARS_P 729 +#define YES_P 730 +#define ZONE 731 +#define NOT_LA 732 +#define NULLS_LA 733 +#define WITH_LA 734 +#define POSTFIXOP 735 +#define UMINUS 736 @@ -214658,7 +230040,7 @@ PGValue *makeString(const char *str) { // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /*------------------------------------------------------------------------- @@ -214685,7 +230067,7 @@ PGValue *makeString(const char *str) { // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /*------------------------------------------------------------------------- @@ -214823,7 +230205,7 @@ namespace duckdb_libpgquery { // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /* A Bison parser, made by GNU Bison 2.3. */ @@ -215052,296 +230434,300 @@ namespace duckdb_libpgquery { HOURS_P = 440, IDENTITY_P = 441, IF_P = 442, - ILIKE = 443, - IMMEDIATE = 444, - IMMUTABLE = 445, - IMPLICIT_P = 446, - IMPORT_P = 447, - IN_P = 448, - INCLUDING = 449, - INCREMENT = 450, - INDEX = 451, - INDEXES = 452, - INHERIT = 453, - INHERITS = 454, - INITIALLY = 455, - INLINE_P = 456, - INNER_P = 457, - INOUT = 458, - INPUT_P = 459, - INSENSITIVE = 460, - INSERT = 461, - INSTEAD = 462, - INT_P = 463, - INTEGER = 464, - INTERSECT = 465, - INTERVAL = 466, - INTO = 467, - INVOKER = 468, - IS = 469, - ISNULL = 470, - ISOLATION = 471, - JOIN = 472, - KEY = 473, - LABEL = 474, - LANGUAGE = 475, - LARGE_P = 476, - LAST_P = 477, - LATERAL_P = 478, - LEADING = 479, - LEAKPROOF = 480, - LEFT = 481, - LEVEL = 482, - LIKE = 483, - LIMIT = 484, - LISTEN = 485, - LOAD = 486, - LOCAL = 487, - LOCALTIME = 488, - LOCALTIMESTAMP = 489, - LOCATION = 490, - LOCK_P = 491, - LOCKED = 492, - LOGGED = 493, - MACRO = 494, - MAP = 495, - MAPPING = 496, - MATCH = 497, - MATERIALIZED = 498, - MAXVALUE = 499, - METHOD = 500, - MICROSECOND_P = 501, - MICROSECONDS_P = 502, - MILLISECOND_P = 503, - MILLISECONDS_P = 504, - MINUTE_P = 505, - MINUTES_P = 506, - MINVALUE = 507, - MODE = 508, - MONTH_P = 509, - MONTHS_P = 510, - MOVE = 511, - NAME_P = 512, - NAMES = 513, - NATIONAL = 514, - NATURAL = 515, - NCHAR = 516, - NEW = 517, - NEXT = 518, - NO = 519, - NONE = 520, - NOT = 521, - NOTHING = 522, - NOTIFY = 523, - NOTNULL = 524, - NOWAIT = 525, - NULL_P = 526, - NULLIF = 527, - NULLS_P = 528, - NUMERIC = 529, - OBJECT_P = 530, - OF = 531, - OFF = 532, - OFFSET = 533, - OIDS = 534, - OLD = 535, - ON = 536, - ONLY = 537, - OPERATOR = 538, - OPTION = 539, - OPTIONS = 540, - OR = 541, - ORDER = 542, - ORDINALITY = 543, - OUT_P = 544, - OUTER_P = 545, - OVER = 546, - OVERLAPS = 547, - OVERLAY = 548, - OVERRIDING = 549, - OWNED = 550, - OWNER = 551, - PARALLEL = 552, - PARSER = 553, - PARTIAL = 554, - PARTITION = 555, - PASSING = 556, - PASSWORD = 557, - PERCENT = 558, - PLACING = 559, - PLANS = 560, - POLICY = 561, - POSITION = 562, - PRAGMA_P = 563, - PRECEDING = 564, - PRECISION = 565, - PREPARE = 566, - PREPARED = 567, - PRESERVE = 568, - PRIMARY = 569, - PRIOR = 570, - PRIVILEGES = 571, - PROCEDURAL = 572, - PROCEDURE = 573, - PROGRAM = 574, - PUBLICATION = 575, - QUOTE = 576, - RANGE = 577, - READ_P = 578, - REAL = 579, - REASSIGN = 580, - RECHECK = 581, - RECURSIVE = 582, - REF = 583, - REFERENCES = 584, - REFERENCING = 585, - REFRESH = 586, - REINDEX = 587, - RELATIVE_P = 588, - RELEASE = 589, - RENAME = 590, - REPEATABLE = 591, - REPLACE = 592, - REPLICA = 593, - RESET = 594, - RESTART = 595, - RESTRICT = 596, - RETURNING = 597, - RETURNS = 598, - REVOKE = 599, - RIGHT = 600, - ROLE = 601, - ROLLBACK = 602, - ROLLUP = 603, - ROW = 604, - ROWS = 605, - RULE = 606, - SAMPLE = 607, - SAVEPOINT = 608, - SCHEMA = 609, - SCHEMAS = 610, - SCROLL = 611, - SEARCH = 612, - SECOND_P = 613, - SECONDS_P = 614, - SECURITY = 615, - SELECT = 616, - SEQUENCE = 617, - SEQUENCES = 618, - SERIALIZABLE = 619, - SERVER = 620, - SESSION = 621, - SESSION_USER = 622, - SET = 623, - SETOF = 624, - SETS = 625, - SHARE = 626, - SHOW = 627, - SIMILAR = 628, - SIMPLE = 629, - SKIP = 630, - SMALLINT = 631, - SNAPSHOT = 632, - SOME = 633, - SQL_P = 634, - STABLE = 635, - STANDALONE_P = 636, - START = 637, - STATEMENT = 638, - STATISTICS = 639, - STDIN = 640, - STDOUT = 641, - STORAGE = 642, - STRICT_P = 643, - STRIP_P = 644, - STRUCT = 645, - SUBSCRIPTION = 646, - SUBSTRING = 647, - SUMMARIZE = 648, - SYMMETRIC = 649, - SYSID = 650, - SYSTEM_P = 651, - TABLE = 652, - TABLES = 653, - TABLESAMPLE = 654, - TABLESPACE = 655, - TEMP = 656, - TEMPLATE = 657, - TEMPORARY = 658, - TEXT_P = 659, - THEN = 660, - TIME = 661, - TIMESTAMP = 662, - TO = 663, - TRAILING = 664, - TRANSACTION = 665, - TRANSFORM = 666, - TREAT = 667, - TRIGGER = 668, - TRIM = 669, - TRUE_P = 670, - TRUNCATE = 671, - TRUSTED = 672, - TRY_CAST = 673, - TYPE_P = 674, - TYPES_P = 675, - UNBOUNDED = 676, - UNCOMMITTED = 677, - UNENCRYPTED = 678, - UNION = 679, - UNIQUE = 680, - UNKNOWN = 681, - UNLISTEN = 682, - UNLOGGED = 683, - UNTIL = 684, - UPDATE = 685, - USER = 686, - USING = 687, - VACUUM = 688, - VALID = 689, - VALIDATE = 690, - VALIDATOR = 691, - VALUE_P = 692, - VALUES = 693, - VARCHAR = 694, - VARIADIC = 695, - VARYING = 696, - VERBOSE = 697, - VERSION_P = 698, - VIEW = 699, - VIEWS = 700, - VOLATILE = 701, - WHEN = 702, - WHERE = 703, - WHITESPACE_P = 704, - WINDOW = 705, - WITH = 706, - WITHIN = 707, - WITHOUT = 708, - WORK = 709, - WRAPPER = 710, - WRITE_P = 711, - XML_P = 712, - XMLATTRIBUTES = 713, - XMLCONCAT = 714, - XMLELEMENT = 715, - XMLEXISTS = 716, - XMLFOREST = 717, - XMLNAMESPACES = 718, - XMLPARSE = 719, - XMLPI = 720, - XMLROOT = 721, - XMLSERIALIZE = 722, - XMLTABLE = 723, - YEAR_P = 724, - YEARS_P = 725, - YES_P = 726, - ZONE = 727, - NOT_LA = 728, - NULLS_LA = 729, - WITH_LA = 730, - POSTFIXOP = 731, - UMINUS = 732 + IGNORE_P = 443, + ILIKE = 444, + IMMEDIATE = 445, + IMMUTABLE = 446, + IMPLICIT_P = 447, + IMPORT_P = 448, + IN_P = 449, + INCLUDING = 450, + INCREMENT = 451, + INDEX = 452, + INDEXES = 453, + INHERIT = 454, + INHERITS = 455, + INITIALLY = 456, + INLINE_P = 457, + INNER_P = 458, + INOUT = 459, + INPUT_P = 460, + INSENSITIVE = 461, + INSERT = 462, + INSTALL = 463, + INSTEAD = 464, + INT_P = 465, + INTEGER = 466, + INTERSECT = 467, + INTERVAL = 468, + INTO = 469, + INVOKER = 470, + IS = 471, + ISNULL = 472, + ISOLATION = 473, + JOIN = 474, + KEY = 475, + LABEL = 476, + LANGUAGE = 477, + LARGE_P = 478, + LAST_P = 479, + LATERAL_P = 480, + LEADING = 481, + LEAKPROOF = 482, + LEFT = 483, + LEVEL = 484, + LIKE = 485, + LIMIT = 486, + LISTEN = 487, + LOAD = 488, + LOCAL = 489, + LOCALTIME = 490, + LOCALTIMESTAMP = 491, + LOCATION = 492, + LOCK_P = 493, + LOCKED = 494, + LOGGED = 495, + MACRO = 496, + MAP = 497, + MAPPING = 498, + MATCH = 499, + MATERIALIZED = 500, + MAXVALUE = 501, + METHOD = 502, + MICROSECOND_P = 503, + MICROSECONDS_P = 504, + MILLISECOND_P = 505, + MILLISECONDS_P = 506, + MINUTE_P = 507, + MINUTES_P = 508, + MINVALUE = 509, + MODE = 510, + MONTH_P = 511, + MONTHS_P = 512, + MOVE = 513, + NAME_P = 514, + NAMES = 515, + NATIONAL = 516, + NATURAL = 517, + NCHAR = 518, + NEW = 519, + NEXT = 520, + NO = 521, + NONE = 522, + NOT = 523, + NOTHING = 524, + NOTIFY = 525, + NOTNULL = 526, + NOWAIT = 527, + NULL_P = 528, + NULLIF = 529, + NULLS_P = 530, + NUMERIC = 531, + OBJECT_P = 532, + OF = 533, + OFF = 534, + OFFSET = 535, + OIDS = 536, + OLD = 537, + ON = 538, + ONLY = 539, + OPERATOR = 540, + OPTION = 541, + OPTIONS = 542, + OR = 543, + ORDER = 544, + ORDINALITY = 545, + OUT_P = 546, + OUTER_P = 547, + OVER = 548, + OVERLAPS = 549, + OVERLAY = 550, + OVERRIDING = 551, + OWNED = 552, + OWNER = 553, + PARALLEL = 554, + PARSER = 555, + PARTIAL = 556, + PARTITION = 557, + PASSING = 558, + PASSWORD = 559, + PERCENT = 560, + PLACING = 561, + PLANS = 562, + POLICY = 563, + POSITION = 564, + PRAGMA_P = 565, + PRECEDING = 566, + PRECISION = 567, + PREPARE = 568, + PREPARED = 569, + PRESERVE = 570, + PRIMARY = 571, + PRIOR = 572, + PRIVILEGES = 573, + PROCEDURAL = 574, + PROCEDURE = 575, + PROGRAM = 576, + PUBLICATION = 577, + QUALIFY = 578, + QUOTE = 579, + RANGE = 580, + READ_P = 581, + REAL = 582, + REASSIGN = 583, + RECHECK = 584, + RECURSIVE = 585, + REF = 586, + REFERENCES = 587, + REFERENCING = 588, + REFRESH = 589, + REINDEX = 590, + RELATIVE_P = 591, + RELEASE = 592, + RENAME = 593, + REPEATABLE = 594, + REPLACE = 595, + REPLICA = 596, + RESET = 597, + RESPECT_P = 598, + RESTART = 599, + RESTRICT = 600, + RETURNING = 601, + RETURNS = 602, + REVOKE = 603, + RIGHT = 604, + ROLE = 605, + ROLLBACK = 606, + ROLLUP = 607, + ROW = 608, + ROWS = 609, + RULE = 610, + SAMPLE = 611, + SAVEPOINT = 612, + SCHEMA = 613, + SCHEMAS = 614, + SCROLL = 615, + SEARCH = 616, + SECOND_P = 617, + SECONDS_P = 618, + SECURITY = 619, + SELECT = 620, + SEQUENCE = 621, + SEQUENCES = 622, + SERIALIZABLE = 623, + SERVER = 624, + SESSION = 625, + SESSION_USER = 626, + SET = 627, + SETOF = 628, + SETS = 629, + SHARE = 630, + SHOW = 631, + SIMILAR = 632, + SIMPLE = 633, + SKIP = 634, + SMALLINT = 635, + SNAPSHOT = 636, + SOME = 637, + SQL_P = 638, + STABLE = 639, + STANDALONE_P = 640, + START = 641, + STATEMENT = 642, + STATISTICS = 643, + STDIN = 644, + STDOUT = 645, + STORAGE = 646, + STRICT_P = 647, + STRIP_P = 648, + STRUCT = 649, + SUBSCRIPTION = 650, + SUBSTRING = 651, + SUMMARIZE = 652, + SYMMETRIC = 653, + SYSID = 654, + SYSTEM_P = 655, + TABLE = 656, + TABLES = 657, + TABLESAMPLE = 658, + TABLESPACE = 659, + TEMP = 660, + TEMPLATE = 661, + TEMPORARY = 662, + TEXT_P = 663, + THEN = 664, + TIME = 665, + TIMESTAMP = 666, + TO = 667, + TRAILING = 668, + TRANSACTION = 669, + TRANSFORM = 670, + TREAT = 671, + TRIGGER = 672, + TRIM = 673, + TRUE_P = 674, + TRUNCATE = 675, + TRUSTED = 676, + TRY_CAST = 677, + TYPE_P = 678, + TYPES_P = 679, + UNBOUNDED = 680, + UNCOMMITTED = 681, + UNENCRYPTED = 682, + UNION = 683, + UNIQUE = 684, + UNKNOWN = 685, + UNLISTEN = 686, + UNLOGGED = 687, + UNTIL = 688, + UPDATE = 689, + USER = 690, + USING = 691, + VACUUM = 692, + VALID = 693, + VALIDATE = 694, + VALIDATOR = 695, + VALUE_P = 696, + VALUES = 697, + VARCHAR = 698, + VARIADIC = 699, + VARYING = 700, + VERBOSE = 701, + VERSION_P = 702, + VIEW = 703, + VIEWS = 704, + VOLATILE = 705, + WHEN = 706, + WHERE = 707, + WHITESPACE_P = 708, + WINDOW = 709, + WITH = 710, + WITHIN = 711, + WITHOUT = 712, + WORK = 713, + WRAPPER = 714, + WRITE_P = 715, + XML_P = 716, + XMLATTRIBUTES = 717, + XMLCONCAT = 718, + XMLELEMENT = 719, + XMLEXISTS = 720, + XMLFOREST = 721, + XMLNAMESPACES = 722, + XMLPARSE = 723, + XMLPI = 724, + XMLROOT = 725, + XMLSERIALIZE = 726, + XMLTABLE = 727, + YEAR_P = 728, + YEARS_P = 729, + YES_P = 730, + ZONE = 731, + NOT_LA = 732, + NULLS_LA = 733, + WITH_LA = 734, + POSTFIXOP = 735, + UMINUS = 736 }; #endif /* Tokens. */ @@ -215530,296 +230916,300 @@ namespace duckdb_libpgquery { #define HOURS_P 440 #define IDENTITY_P 441 #define IF_P 442 -#define ILIKE 443 -#define IMMEDIATE 444 -#define IMMUTABLE 445 -#define IMPLICIT_P 446 -#define IMPORT_P 447 -#define IN_P 448 -#define INCLUDING 449 -#define INCREMENT 450 -#define INDEX 451 -#define INDEXES 452 -#define INHERIT 453 -#define INHERITS 454 -#define INITIALLY 455 -#define INLINE_P 456 -#define INNER_P 457 -#define INOUT 458 -#define INPUT_P 459 -#define INSENSITIVE 460 -#define INSERT 461 -#define INSTEAD 462 -#define INT_P 463 -#define INTEGER 464 -#define INTERSECT 465 -#define INTERVAL 466 -#define INTO 467 -#define INVOKER 468 -#define IS 469 -#define ISNULL 470 -#define ISOLATION 471 -#define JOIN 472 -#define KEY 473 -#define LABEL 474 -#define LANGUAGE 475 -#define LARGE_P 476 -#define LAST_P 477 -#define LATERAL_P 478 -#define LEADING 479 -#define LEAKPROOF 480 -#define LEFT 481 -#define LEVEL 482 -#define LIKE 483 -#define LIMIT 484 -#define LISTEN 485 -#define LOAD 486 -#define LOCAL 487 -#define LOCALTIME 488 -#define LOCALTIMESTAMP 489 -#define LOCATION 490 -#define LOCK_P 491 -#define LOCKED 492 -#define LOGGED 493 -#define MACRO 494 -#define MAP 495 -#define MAPPING 496 -#define MATCH 497 -#define MATERIALIZED 498 -#define MAXVALUE 499 -#define METHOD 500 -#define MICROSECOND_P 501 -#define MICROSECONDS_P 502 -#define MILLISECOND_P 503 -#define MILLISECONDS_P 504 -#define MINUTE_P 505 -#define MINUTES_P 506 -#define MINVALUE 507 -#define MODE 508 -#define MONTH_P 509 -#define MONTHS_P 510 -#define MOVE 511 -#define NAME_P 512 -#define NAMES 513 -#define NATIONAL 514 -#define NATURAL 515 -#define NCHAR 516 -#define NEW 517 -#define NEXT 518 -#define NO 519 -#define NONE 520 -#define NOT 521 -#define NOTHING 522 -#define NOTIFY 523 -#define NOTNULL 524 -#define NOWAIT 525 -#define NULL_P 526 -#define NULLIF 527 -#define NULLS_P 528 -#define NUMERIC 529 -#define OBJECT_P 530 -#define OF 531 -#define OFF 532 -#define OFFSET 533 -#define OIDS 534 -#define OLD 535 -#define ON 536 -#define ONLY 537 -#define OPERATOR 538 -#define OPTION 539 -#define OPTIONS 540 -#define OR 541 -#define ORDER 542 -#define ORDINALITY 543 -#define OUT_P 544 -#define OUTER_P 545 -#define OVER 546 -#define OVERLAPS 547 -#define OVERLAY 548 -#define OVERRIDING 549 -#define OWNED 550 -#define OWNER 551 -#define PARALLEL 552 -#define PARSER 553 -#define PARTIAL 554 -#define PARTITION 555 -#define PASSING 556 -#define PASSWORD 557 -#define PERCENT 558 -#define PLACING 559 -#define PLANS 560 -#define POLICY 561 -#define POSITION 562 -#define PRAGMA_P 563 -#define PRECEDING 564 -#define PRECISION 565 -#define PREPARE 566 -#define PREPARED 567 -#define PRESERVE 568 -#define PRIMARY 569 -#define PRIOR 570 -#define PRIVILEGES 571 -#define PROCEDURAL 572 -#define PROCEDURE 573 -#define PROGRAM 574 -#define PUBLICATION 575 -#define QUOTE 576 -#define RANGE 577 -#define READ_P 578 -#define REAL 579 -#define REASSIGN 580 -#define RECHECK 581 -#define RECURSIVE 582 -#define REF 583 -#define REFERENCES 584 -#define REFERENCING 585 -#define REFRESH 586 -#define REINDEX 587 -#define RELATIVE_P 588 -#define RELEASE 589 -#define RENAME 590 -#define REPEATABLE 591 -#define REPLACE 592 -#define REPLICA 593 -#define RESET 594 -#define RESTART 595 -#define RESTRICT 596 -#define RETURNING 597 -#define RETURNS 598 -#define REVOKE 599 -#define RIGHT 600 -#define ROLE 601 -#define ROLLBACK 602 -#define ROLLUP 603 -#define ROW 604 -#define ROWS 605 -#define RULE 606 -#define SAMPLE 607 -#define SAVEPOINT 608 -#define SCHEMA 609 -#define SCHEMAS 610 -#define SCROLL 611 -#define SEARCH 612 -#define SECOND_P 613 -#define SECONDS_P 614 -#define SECURITY 615 -#define SELECT 616 -#define SEQUENCE 617 -#define SEQUENCES 618 -#define SERIALIZABLE 619 -#define SERVER 620 -#define SESSION 621 -#define SESSION_USER 622 -#define SET 623 -#define SETOF 624 -#define SETS 625 -#define SHARE 626 -#define SHOW 627 -#define SIMILAR 628 -#define SIMPLE 629 -#define SKIP 630 -#define SMALLINT 631 -#define SNAPSHOT 632 -#define SOME 633 -#define SQL_P 634 -#define STABLE 635 -#define STANDALONE_P 636 -#define START 637 -#define STATEMENT 638 -#define STATISTICS 639 -#define STDIN 640 -#define STDOUT 641 -#define STORAGE 642 -#define STRICT_P 643 -#define STRIP_P 644 -#define STRUCT 645 -#define SUBSCRIPTION 646 -#define SUBSTRING 647 -#define SUMMARIZE 648 -#define SYMMETRIC 649 -#define SYSID 650 -#define SYSTEM_P 651 -#define TABLE 652 -#define TABLES 653 -#define TABLESAMPLE 654 -#define TABLESPACE 655 -#define TEMP 656 -#define TEMPLATE 657 -#define TEMPORARY 658 -#define TEXT_P 659 -#define THEN 660 -#define TIME 661 -#define TIMESTAMP 662 -#define TO 663 -#define TRAILING 664 -#define TRANSACTION 665 -#define TRANSFORM 666 -#define TREAT 667 -#define TRIGGER 668 -#define TRIM 669 -#define TRUE_P 670 -#define TRUNCATE 671 -#define TRUSTED 672 -#define TRY_CAST 673 -#define TYPE_P 674 -#define TYPES_P 675 -#define UNBOUNDED 676 -#define UNCOMMITTED 677 -#define UNENCRYPTED 678 -#define UNION 679 -#define UNIQUE 680 -#define UNKNOWN 681 -#define UNLISTEN 682 -#define UNLOGGED 683 -#define UNTIL 684 -#define UPDATE 685 -#define USER 686 -#define USING 687 -#define VACUUM 688 -#define VALID 689 -#define VALIDATE 690 -#define VALIDATOR 691 -#define VALUE_P 692 -#define VALUES 693 -#define VARCHAR 694 -#define VARIADIC 695 -#define VARYING 696 -#define VERBOSE 697 -#define VERSION_P 698 -#define VIEW 699 -#define VIEWS 700 -#define VOLATILE 701 -#define WHEN 702 -#define WHERE 703 -#define WHITESPACE_P 704 -#define WINDOW 705 -#define WITH 706 -#define WITHIN 707 -#define WITHOUT 708 -#define WORK 709 -#define WRAPPER 710 -#define WRITE_P 711 -#define XML_P 712 -#define XMLATTRIBUTES 713 -#define XMLCONCAT 714 -#define XMLELEMENT 715 -#define XMLEXISTS 716 -#define XMLFOREST 717 -#define XMLNAMESPACES 718 -#define XMLPARSE 719 -#define XMLPI 720 -#define XMLROOT 721 -#define XMLSERIALIZE 722 -#define XMLTABLE 723 -#define YEAR_P 724 -#define YEARS_P 725 -#define YES_P 726 -#define ZONE 727 -#define NOT_LA 728 -#define NULLS_LA 729 -#define WITH_LA 730 -#define POSTFIXOP 731 -#define UMINUS 732 +#define IGNORE_P 443 +#define ILIKE 444 +#define IMMEDIATE 445 +#define IMMUTABLE 446 +#define IMPLICIT_P 447 +#define IMPORT_P 448 +#define IN_P 449 +#define INCLUDING 450 +#define INCREMENT 451 +#define INDEX 452 +#define INDEXES 453 +#define INHERIT 454 +#define INHERITS 455 +#define INITIALLY 456 +#define INLINE_P 457 +#define INNER_P 458 +#define INOUT 459 +#define INPUT_P 460 +#define INSENSITIVE 461 +#define INSERT 462 +#define INSTALL 463 +#define INSTEAD 464 +#define INT_P 465 +#define INTEGER 466 +#define INTERSECT 467 +#define INTERVAL 468 +#define INTO 469 +#define INVOKER 470 +#define IS 471 +#define ISNULL 472 +#define ISOLATION 473 +#define JOIN 474 +#define KEY 475 +#define LABEL 476 +#define LANGUAGE 477 +#define LARGE_P 478 +#define LAST_P 479 +#define LATERAL_P 480 +#define LEADING 481 +#define LEAKPROOF 482 +#define LEFT 483 +#define LEVEL 484 +#define LIKE 485 +#define LIMIT 486 +#define LISTEN 487 +#define LOAD 488 +#define LOCAL 489 +#define LOCALTIME 490 +#define LOCALTIMESTAMP 491 +#define LOCATION 492 +#define LOCK_P 493 +#define LOCKED 494 +#define LOGGED 495 +#define MACRO 496 +#define MAP 497 +#define MAPPING 498 +#define MATCH 499 +#define MATERIALIZED 500 +#define MAXVALUE 501 +#define METHOD 502 +#define MICROSECOND_P 503 +#define MICROSECONDS_P 504 +#define MILLISECOND_P 505 +#define MILLISECONDS_P 506 +#define MINUTE_P 507 +#define MINUTES_P 508 +#define MINVALUE 509 +#define MODE 510 +#define MONTH_P 511 +#define MONTHS_P 512 +#define MOVE 513 +#define NAME_P 514 +#define NAMES 515 +#define NATIONAL 516 +#define NATURAL 517 +#define NCHAR 518 +#define NEW 519 +#define NEXT 520 +#define NO 521 +#define NONE 522 +#define NOT 523 +#define NOTHING 524 +#define NOTIFY 525 +#define NOTNULL 526 +#define NOWAIT 527 +#define NULL_P 528 +#define NULLIF 529 +#define NULLS_P 530 +#define NUMERIC 531 +#define OBJECT_P 532 +#define OF 533 +#define OFF 534 +#define OFFSET 535 +#define OIDS 536 +#define OLD 537 +#define ON 538 +#define ONLY 539 +#define OPERATOR 540 +#define OPTION 541 +#define OPTIONS 542 +#define OR 543 +#define ORDER 544 +#define ORDINALITY 545 +#define OUT_P 546 +#define OUTER_P 547 +#define OVER 548 +#define OVERLAPS 549 +#define OVERLAY 550 +#define OVERRIDING 551 +#define OWNED 552 +#define OWNER 553 +#define PARALLEL 554 +#define PARSER 555 +#define PARTIAL 556 +#define PARTITION 557 +#define PASSING 558 +#define PASSWORD 559 +#define PERCENT 560 +#define PLACING 561 +#define PLANS 562 +#define POLICY 563 +#define POSITION 564 +#define PRAGMA_P 565 +#define PRECEDING 566 +#define PRECISION 567 +#define PREPARE 568 +#define PREPARED 569 +#define PRESERVE 570 +#define PRIMARY 571 +#define PRIOR 572 +#define PRIVILEGES 573 +#define PROCEDURAL 574 +#define PROCEDURE 575 +#define PROGRAM 576 +#define PUBLICATION 577 +#define QUALIFY 578 +#define QUOTE 579 +#define RANGE 580 +#define READ_P 581 +#define REAL 582 +#define REASSIGN 583 +#define RECHECK 584 +#define RECURSIVE 585 +#define REF 586 +#define REFERENCES 587 +#define REFERENCING 588 +#define REFRESH 589 +#define REINDEX 590 +#define RELATIVE_P 591 +#define RELEASE 592 +#define RENAME 593 +#define REPEATABLE 594 +#define REPLACE 595 +#define REPLICA 596 +#define RESET 597 +#define RESPECT_P 598 +#define RESTART 599 +#define RESTRICT 600 +#define RETURNING 601 +#define RETURNS 602 +#define REVOKE 603 +#define RIGHT 604 +#define ROLE 605 +#define ROLLBACK 606 +#define ROLLUP 607 +#define ROW 608 +#define ROWS 609 +#define RULE 610 +#define SAMPLE 611 +#define SAVEPOINT 612 +#define SCHEMA 613 +#define SCHEMAS 614 +#define SCROLL 615 +#define SEARCH 616 +#define SECOND_P 617 +#define SECONDS_P 618 +#define SECURITY 619 +#define SELECT 620 +#define SEQUENCE 621 +#define SEQUENCES 622 +#define SERIALIZABLE 623 +#define SERVER 624 +#define SESSION 625 +#define SESSION_USER 626 +#define SET 627 +#define SETOF 628 +#define SETS 629 +#define SHARE 630 +#define SHOW 631 +#define SIMILAR 632 +#define SIMPLE 633 +#define SKIP 634 +#define SMALLINT 635 +#define SNAPSHOT 636 +#define SOME 637 +#define SQL_P 638 +#define STABLE 639 +#define STANDALONE_P 640 +#define START 641 +#define STATEMENT 642 +#define STATISTICS 643 +#define STDIN 644 +#define STDOUT 645 +#define STORAGE 646 +#define STRICT_P 647 +#define STRIP_P 648 +#define STRUCT 649 +#define SUBSCRIPTION 650 +#define SUBSTRING 651 +#define SUMMARIZE 652 +#define SYMMETRIC 653 +#define SYSID 654 +#define SYSTEM_P 655 +#define TABLE 656 +#define TABLES 657 +#define TABLESAMPLE 658 +#define TABLESPACE 659 +#define TEMP 660 +#define TEMPLATE 661 +#define TEMPORARY 662 +#define TEXT_P 663 +#define THEN 664 +#define TIME 665 +#define TIMESTAMP 666 +#define TO 667 +#define TRAILING 668 +#define TRANSACTION 669 +#define TRANSFORM 670 +#define TREAT 671 +#define TRIGGER 672 +#define TRIM 673 +#define TRUE_P 674 +#define TRUNCATE 675 +#define TRUSTED 676 +#define TRY_CAST 677 +#define TYPE_P 678 +#define TYPES_P 679 +#define UNBOUNDED 680 +#define UNCOMMITTED 681 +#define UNENCRYPTED 682 +#define UNION 683 +#define UNIQUE 684 +#define UNKNOWN 685 +#define UNLISTEN 686 +#define UNLOGGED 687 +#define UNTIL 688 +#define UPDATE 689 +#define USER 690 +#define USING 691 +#define VACUUM 692 +#define VALID 693 +#define VALIDATE 694 +#define VALIDATOR 695 +#define VALUE_P 696 +#define VALUES 697 +#define VARCHAR 698 +#define VARIADIC 699 +#define VARYING 700 +#define VERBOSE 701 +#define VERSION_P 702 +#define VIEW 703 +#define VIEWS 704 +#define VOLATILE 705 +#define WHEN 706 +#define WHERE 707 +#define WHITESPACE_P 708 +#define WINDOW 709 +#define WITH 710 +#define WITHIN 711 +#define WITHOUT 712 +#define WORK 713 +#define WRAPPER 714 +#define WRITE_P 715 +#define XML_P 716 +#define XMLATTRIBUTES 717 +#define XMLCONCAT 718 +#define XMLELEMENT 719 +#define XMLEXISTS 720 +#define XMLFOREST 721 +#define XMLNAMESPACES 722 +#define XMLPARSE 723 +#define XMLPI 724 +#define XMLROOT 725 +#define XMLSERIALIZE 726 +#define XMLTABLE 727 +#define YEAR_P 728 +#define YEARS_P 729 +#define YES_P 730 +#define ZONE 731 +#define NOT_LA 732 +#define NULLS_LA 733 +#define WITH_LA 734 +#define POSTFIXOP 735 +#define UMINUS 736 @@ -215871,7 +231261,7 @@ typedef union YYSTYPE PGViewCheckOption viewcheckoption; } /* Line 1529 of yacc.c. */ -#line 1047 "third_party/libpg_query/grammar/grammar_out.hpp" +#line 1055 "third_party/libpg_query/grammar/grammar_out.hpp" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 @@ -215948,7 +231338,7 @@ int base_yyparse(core_yyscan_t yyscanner); // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /*------------------------------------------------------------------------- @@ -215972,7 +231362,7 @@ int base_yyparse(core_yyscan_t yyscanner); // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /*------------------------------------------------------------------------- @@ -215992,7 +231382,7 @@ int base_yyparse(core_yyscan_t yyscanner); // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /*------------------------------------------------------------------------- @@ -216053,7 +231443,7 @@ typedef struct { // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /*------------------------------------------------------------------------- @@ -216311,6 +231701,7 @@ static void processCASbits(int cas_bits, int location, const char *constrType, bool *deferrable, bool *initdeferred, bool *not_valid, bool *no_inherit, core_yyscan_t yyscanner); static PGNode *makeRecursiveViewSelect(char *relname, PGList *aliases, PGNode *query); +static PGNode *makeLimitPercent(PGNode *limit_percent); @@ -216379,7 +231770,7 @@ typedef union YYSTYPE PGViewCheckOption viewcheckoption; } /* Line 193 of yacc.c. */ -#line 1267 "third_party/libpg_query/grammar/grammar_out.cpp" +#line 1276 "third_party/libpg_query/grammar/grammar_out.cpp" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 @@ -216404,7 +231795,7 @@ typedef struct YYLTYPE /* Line 216 of yacc.c. */ -#line 1292 "third_party/libpg_query/grammar/grammar_out.cpp" +#line 1301 "third_party/libpg_query/grammar/grammar_out.cpp" #ifdef short # undef short @@ -216619,22 +232010,22 @@ union yyalloc #endif /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 589 +#define YYFINAL 596 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 51076 +#define YYLAST 54005 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 499 +#define YYNTOKENS 503 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 382 +#define YYNNTS 384 /* YYNRULES -- Number of rules. */ -#define YYNRULES 1789 +#define YYNRULES 1808 /* YYNRULES -- Number of states. */ -#define YYNSTATES 2955 +#define YYNSTATES 2991 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 732 +#define YYMAXUTOK 736 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -216645,16 +232036,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, 496, 2, 484, 2, 2, - 489, 490, 482, 480, 493, 481, 491, 483, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 498, 492, - 476, 478, 477, 497, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 500, 2, 488, 2, 2, + 493, 494, 486, 484, 497, 485, 495, 487, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 502, 496, + 480, 482, 481, 501, 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, 487, 2, 488, 485, 2, 2, 2, 2, 2, + 2, 491, 2, 492, 489, 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, 494, 2, 495, 2, 2, 2, 2, + 2, 2, 2, 498, 2, 499, 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, @@ -216715,7 +232106,7 @@ static const yytype_uint16 yytranslate[] = 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, 479, 486 + 475, 476, 477, 478, 479, 483, 490 }; #if YYDEBUG @@ -216768,682 +232159,691 @@ static const yytype_uint16 yyprhs[] = 1473, 1475, 1477, 1479, 1483, 1487, 1489, 1491, 1495, 1499, 1503, 1507, 1512, 1516, 1519, 1521, 1523, 1525, 1527, 1529, 1533, 1535, 1537, 1541, 1545, 1547, 1550, 1555, 1560, 1563, - 1567, 1573, 1579, 1581, 1583, 1594, 1605, 1607, 1610, 1615, - 1620, 1625, 1628, 1631, 1635, 1637, 1641, 1648, 1651, 1652, - 1656, 1660, 1665, 1670, 1675, 1680, 1684, 1687, 1689, 1691, - 1692, 1694, 1696, 1697, 1699, 1705, 1707, 1708, 1710, 1711, - 1715, 1717, 1721, 1726, 1730, 1732, 1734, 1735, 1738, 1741, - 1742, 1745, 1748, 1750, 1752, 1754, 1755, 1758, 1763, 1769, - 1774, 1777, 1781, 1784, 1787, 1790, 1793, 1795, 1798, 1802, - 1803, 1805, 1806, 1812, 1814, 1819, 1826, 1829, 1831, 1832, - 1837, 1838, 1840, 1842, 1844, 1846, 1849, 1852, 1854, 1856, - 1858, 1860, 1862, 1864, 1868, 1869, 1871, 1875, 1877, 1879, - 1881, 1883, 1885, 1888, 1893, 1898, 1904, 1906, 1908, 1911, - 1912, 1914, 1918, 1920, 1921, 1923, 1926, 1930, 1933, 1938, - 1941, 1945, 1948, 1949, 1951, 1954, 1955, 1960, 1966, 1969, - 1970, 1972, 1976, 1980, 1984, 1988, 1992, 1996, 1998, 2003, - 2007, 2012, 2018, 2023, 2029, 2034, 2040, 2043, 2048, 2050, - 2052, 2053, 2055, 2060, 2066, 2071, 2072, 2075, 2078, 2081, - 2083, 2085, 2086, 2091, 2094, 2096, 2099, 2102, 2107, 2110, - 2117, 2120, 2122, 2126, 2131, 2132, 2135, 2136, 2139, 2140, - 2142, 2146, 2150, 2153, 2154, 2157, 2162, 2164, 2166, 2169, - 2173, 2179, 2186, 2189, 2193, 2199, 2205, 2209, 2214, 2215, - 2217, 2219, 2221, 2223, 2225, 2228, 2233, 2235, 2237, 2239, - 2241, 2244, 2248, 2249, 2251, 2253, 2255, 2257, 2259, 2262, - 2265, 2268, 2271, 2274, 2276, 2280, 2281, 2283, 2285, 2287, - 2289, 2295, 2298, 2300, 2302, 2304, 2306, 2311, 2313, 2316, - 2319, 2321, 2325, 2329, 2332, 2334, 2335, 2341, 2344, 2350, - 2353, 2355, 2359, 2363, 2364, 2366, 2368, 2370, 2372, 2374, - 2376, 2378, 2380, 2382, 2384, 2386, 2388, 2390, 2392, 2394, - 2396, 2398, 2400, 2402, 2404, 2406, 2408, 2410, 2412, 2416, - 2420, 2424, 2428, 2432, 2436, 2440, 2441, 2443, 2447, 2451, - 2457, 2460, 2463, 2467, 2471, 2475, 2479, 2483, 2487, 2491, - 2495, 2499, 2503, 2507, 2511, 2515, 2518, 2521, 2525, 2529, - 2532, 2535, 2539, 2543, 2549, 2554, 2561, 2565, 2571, 2576, - 2583, 2588, 2595, 2601, 2609, 2613, 2616, 2621, 2625, 2628, - 2630, 2634, 2638, 2642, 2646, 2650, 2654, 2659, 2663, 2668, - 2672, 2677, 2683, 2690, 2697, 2705, 2712, 2720, 2727, 2735, - 2739, 2744, 2749, 2756, 2758, 2763, 2765, 2769, 2772, 2775, - 2779, 2783, 2787, 2791, 2795, 2799, 2803, 2807, 2811, 2815, - 2819, 2823, 2827, 2830, 2833, 2839, 2846, 2853, 2861, 2863, - 2865, 2868, 2871, 2874, 2879, 2881, 2884, 2886, 2889, 2892, - 2897, 2901, 2907, 2914, 2923, 2930, 2937, 2942, 2947, 2949, - 2951, 2953, 2959, 2961, 2963, 2968, 2970, 2975, 2977, 2982, - 2984, 2989, 2991, 2993, 2995, 2997, 2999, 3001, 3008, 3015, - 3020, 3025, 3030, 3035, 3042, 3048, 3054, 3060, 3065, 3072, - 3077, 3083, 3084, 3090, 3091, 3094, 3095, 3097, 3101, 3105, - 3108, 3111, 3112, 3119, 3121, 3122, 3126, 3127, 3130, 3133, - 3134, 3136, 3141, 3144, 3147, 3150, 3153, 3156, 3161, 3165, - 3167, 3173, 3177, 3179, 3183, 3185, 3187, 3189, 3191, 3193, - 3195, 3197, 3199, 3201, 3203, 3205, 3207, 3209, 3211, 3213, - 3215, 3217, 3219, 3224, 3226, 3231, 3233, 3238, 3240, 3243, - 3245, 3248, 3250, 3253, 3255, 3259, 3261, 3265, 3267, 3268, - 3270, 3274, 3276, 3280, 3284, 3286, 3290, 3294, 3295, 3297, - 3299, 3301, 3303, 3305, 3307, 3309, 3311, 3313, 3315, 3320, - 3324, 3327, 3331, 3332, 3336, 3340, 3343, 3346, 3348, 3349, - 3352, 3355, 3359, 3362, 3364, 3366, 3370, 3376, 3378, 3381, - 3386, 3389, 3390, 3392, 3393, 3395, 3398, 3401, 3405, 3411, - 3413, 3414, 3416, 3419, 3420, 3423, 3425, 3426, 3428, 3429, - 3431, 3435, 3439, 3442, 3444, 3448, 3454, 3459, 3462, 3464, - 3465, 3469, 3471, 3475, 3480, 3483, 3484, 3486, 3490, 3492, - 3495, 3497, 3501, 3503, 3505, 3507, 3510, 3512, 3514, 3517, - 3519, 3521, 3524, 3531, 3534, 3540, 3544, 3548, 3550, 3552, - 3554, 3556, 3558, 3560, 3562, 3564, 3566, 3568, 3570, 3572, - 3574, 3576, 3578, 3580, 3582, 3584, 3586, 3588, 3591, 3594, - 3598, 3602, 3603, 3605, 3607, 3609, 3611, 3613, 3615, 3617, - 3623, 3627, 3628, 3630, 3632, 3634, 3636, 3641, 3649, 3652, - 3653, 3655, 3657, 3659, 3661, 3675, 3692, 3694, 3697, 3698, - 3700, 3701, 3703, 3704, 3707, 3708, 3710, 3711, 3718, 3727, - 3734, 3743, 3750, 3759, 3762, 3764, 3769, 3773, 3776, 3781, - 3785, 3791, 3793, 3794, 3796, 3798, 3799, 3801, 3803, 3805, - 3807, 3809, 3811, 3813, 3815, 3817, 3819, 3821, 3825, 3827, - 3829, 3831, 3833, 3835, 3837, 3840, 3842, 3844, 3847, 3851, - 3855, 3859, 3861, 3865, 3869, 3872, 3876, 3880, 3884, 3888, - 3890, 3892, 3894, 3896, 3900, 3906, 3908, 3910, 3912, 3914, - 3918, 3921, 3923, 3928, 3934, 3940, 3945, 3952, 3954, 3956, - 3958, 3960, 3962, 3964, 3965, 3967, 3971, 3973, 3974, 3982, - 3984, 3987, 3991, 3994, 3995, 3998, 3999, 4002, 4007, 4010, - 4012, 4014, 4016, 4019, 4023, 4026, 4029, 4032, 4035, 4039, - 4044, 4047, 4049, 4051, 4053, 4057, 4060, 4070, 4082, 4095, - 4110, 4114, 4119, 4124, 4125, 4133, 4144, 4147, 4151, 4152, - 4157, 4159, 4161, 4163, 4165, 4167, 4169, 4171, 4173, 4175, - 4177, 4179, 4181, 4183, 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, 4259, 4261, 4263, 4265, 4267, 4269, 4271, 4273, 4275, - 4277, 4279, 4281, 4283, 4285, 4287, 4289, 4291, 4293, 4295, - 4297, 4299, 4301, 4303, 4305, 4307, 4309, 4311, 4313, 4315, - 4317, 4319, 4321, 4323, 4325, 4327, 4329, 4331, 4333, 4335, - 4337, 4339, 4341, 4343, 4345, 4347, 4349, 4351, 4353, 4355, - 4357, 4359, 4361, 4363, 4365, 4367, 4369, 4371, 4373, 4375, - 4377, 4379, 4381, 4383, 4385, 4387, 4389, 4391, 4393, 4395, - 4397, 4399, 4401, 4403, 4405, 4407, 4409, 4411, 4413, 4415, - 4417, 4419, 4421, 4423, 4425, 4427, 4429, 4431, 4433, 4435, - 4437, 4439, 4441, 4443, 4445, 4447, 4449, 4451, 4453, 4455, - 4457, 4459, 4461, 4463, 4465, 4467, 4469, 4471, 4473, 4475, - 4477, 4479, 4481, 4483, 4485, 4487, 4489, 4491, 4493, 4495, - 4497, 4499, 4501, 4503, 4505, 4507, 4509, 4511, 4513, 4515, - 4517, 4519, 4521, 4523, 4525, 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 + 1567, 1573, 1579, 1581, 1583, 1595, 1607, 1609, 1612, 1617, + 1622, 1627, 1630, 1633, 1637, 1639, 1643, 1650, 1653, 1654, + 1658, 1662, 1667, 1672, 1677, 1682, 1686, 1689, 1691, 1693, + 1694, 1696, 1698, 1699, 1701, 1707, 1709, 1710, 1713, 1716, + 1717, 1719, 1720, 1724, 1730, 1736, 1738, 1742, 1747, 1751, + 1753, 1755, 1756, 1759, 1762, 1763, 1766, 1769, 1771, 1773, + 1775, 1776, 1779, 1784, 1790, 1795, 1798, 1802, 1805, 1808, + 1811, 1814, 1816, 1819, 1823, 1824, 1826, 1827, 1833, 1835, + 1840, 1847, 1850, 1852, 1853, 1858, 1859, 1861, 1863, 1866, + 1869, 1872, 1874, 1876, 1879, 1882, 1884, 1886, 1888, 1890, + 1892, 1894, 1898, 1902, 1906, 1907, 1909, 1913, 1915, 1917, + 1919, 1921, 1923, 1926, 1931, 1936, 1942, 1944, 1946, 1949, + 1950, 1953, 1954, 1956, 1960, 1962, 1963, 1965, 1968, 1972, + 1975, 1980, 1983, 1987, 1990, 1991, 1993, 1996, 1997, 2002, + 2008, 2011, 2012, 2014, 2018, 2022, 2026, 2030, 2034, 2038, + 2040, 2045, 2049, 2054, 2060, 2065, 2071, 2076, 2082, 2085, + 2090, 2092, 2094, 2095, 2097, 2102, 2108, 2113, 2114, 2117, + 2120, 2123, 2125, 2127, 2128, 2133, 2136, 2138, 2141, 2144, + 2149, 2152, 2159, 2162, 2164, 2168, 2173, 2174, 2177, 2178, + 2181, 2182, 2184, 2188, 2192, 2195, 2196, 2199, 2204, 2206, + 2208, 2211, 2215, 2221, 2228, 2231, 2235, 2241, 2247, 2251, + 2256, 2257, 2259, 2261, 2263, 2265, 2267, 2270, 2275, 2277, + 2279, 2281, 2283, 2286, 2290, 2291, 2293, 2295, 2297, 2299, + 2301, 2304, 2307, 2310, 2313, 2316, 2318, 2322, 2323, 2325, + 2327, 2329, 2331, 2337, 2340, 2342, 2344, 2346, 2348, 2353, + 2355, 2358, 2361, 2363, 2367, 2371, 2374, 2376, 2377, 2383, + 2386, 2392, 2395, 2397, 2401, 2405, 2406, 2408, 2410, 2412, + 2414, 2416, 2418, 2420, 2422, 2424, 2426, 2428, 2430, 2432, + 2434, 2436, 2438, 2440, 2442, 2444, 2446, 2448, 2450, 2452, + 2454, 2458, 2462, 2466, 2470, 2474, 2478, 2482, 2483, 2485, + 2489, 2493, 2499, 2502, 2505, 2509, 2513, 2517, 2521, 2525, + 2529, 2533, 2537, 2541, 2545, 2549, 2553, 2557, 2560, 2563, + 2567, 2571, 2574, 2577, 2581, 2585, 2591, 2596, 2603, 2607, + 2613, 2618, 2625, 2630, 2637, 2643, 2651, 2655, 2658, 2663, + 2667, 2670, 2672, 2676, 2680, 2684, 2688, 2692, 2696, 2701, + 2705, 2710, 2714, 2719, 2725, 2732, 2739, 2747, 2754, 2762, + 2769, 2777, 2781, 2786, 2791, 2798, 2800, 2805, 2807, 2811, + 2814, 2817, 2821, 2825, 2829, 2833, 2837, 2841, 2845, 2849, + 2853, 2857, 2861, 2865, 2869, 2872, 2875, 2881, 2888, 2895, + 2903, 2905, 2907, 2910, 2913, 2916, 2921, 2923, 2926, 2928, + 2931, 2934, 2939, 2943, 2950, 2958, 2968, 2976, 2984, 2989, + 2994, 2996, 2998, 3000, 3006, 3008, 3010, 3015, 3017, 3022, + 3024, 3029, 3031, 3036, 3038, 3040, 3042, 3044, 3046, 3048, + 3055, 3062, 3067, 3072, 3077, 3082, 3089, 3095, 3101, 3107, + 3112, 3119, 3124, 3130, 3131, 3137, 3138, 3141, 3142, 3144, + 3148, 3152, 3155, 3158, 3159, 3166, 3168, 3169, 3173, 3174, + 3177, 3180, 3181, 3183, 3188, 3191, 3194, 3197, 3200, 3203, + 3208, 3212, 3214, 3220, 3224, 3226, 3230, 3232, 3234, 3236, + 3238, 3240, 3242, 3244, 3246, 3248, 3250, 3252, 3254, 3256, + 3258, 3260, 3262, 3264, 3266, 3271, 3273, 3278, 3280, 3285, + 3287, 3290, 3292, 3295, 3297, 3300, 3302, 3306, 3308, 3312, + 3314, 3315, 3317, 3321, 3323, 3327, 3331, 3333, 3337, 3341, + 3342, 3344, 3346, 3348, 3350, 3352, 3354, 3356, 3358, 3360, + 3362, 3367, 3371, 3374, 3378, 3379, 3383, 3387, 3390, 3393, + 3395, 3396, 3399, 3402, 3406, 3409, 3411, 3413, 3417, 3423, + 3425, 3428, 3433, 3436, 3437, 3439, 3440, 3442, 3445, 3448, + 3452, 3458, 3460, 3461, 3463, 3466, 3467, 3470, 3472, 3473, + 3475, 3476, 3478, 3482, 3486, 3489, 3491, 3495, 3501, 3506, + 3509, 3511, 3512, 3516, 3518, 3522, 3527, 3530, 3531, 3533, + 3537, 3539, 3542, 3544, 3548, 3550, 3552, 3554, 3557, 3559, + 3561, 3564, 3566, 3568, 3571, 3579, 3582, 3588, 3592, 3596, + 3598, 3600, 3602, 3604, 3606, 3608, 3610, 3612, 3614, 3616, + 3618, 3620, 3622, 3624, 3626, 3628, 3630, 3632, 3634, 3636, + 3639, 3642, 3646, 3650, 3651, 3653, 3655, 3657, 3659, 3661, + 3663, 3665, 3671, 3675, 3676, 3678, 3680, 3682, 3684, 3689, + 3697, 3700, 3701, 3703, 3705, 3707, 3709, 3723, 3740, 3742, + 3745, 3746, 3748, 3749, 3751, 3752, 3755, 3756, 3758, 3759, + 3766, 3775, 3782, 3791, 3798, 3807, 3810, 3812, 3817, 3821, + 3824, 3829, 3833, 3839, 3841, 3842, 3844, 3846, 3847, 3849, + 3851, 3853, 3855, 3857, 3859, 3861, 3863, 3865, 3867, 3869, + 3873, 3875, 3877, 3879, 3881, 3883, 3885, 3888, 3890, 3892, + 3895, 3899, 3903, 3907, 3909, 3913, 3917, 3920, 3924, 3928, + 3932, 3936, 3938, 3940, 3942, 3944, 3948, 3954, 3956, 3958, + 3960, 3962, 3966, 3969, 3972, 3976, 3978, 3980, 3985, 3991, + 3997, 4002, 4009, 4011, 4013, 4015, 4017, 4019, 4021, 4022, + 4024, 4028, 4030, 4031, 4039, 4041, 4044, 4048, 4051, 4052, + 4055, 4056, 4059, 4064, 4067, 4069, 4071, 4073, 4076, 4080, + 4083, 4086, 4089, 4092, 4096, 4101, 4104, 4106, 4108, 4110, + 4114, 4117, 4127, 4139, 4152, 4167, 4171, 4176, 4181, 4182, + 4190, 4201, 4204, 4208, 4209, 4214, 4216, 4218, 4220, 4222, + 4224, 4226, 4228, 4230, 4232, 4234, 4236, 4238, 4240, 4242, + 4244, 4246, 4248, 4250, 4252, 4254, 4256, 4258, 4260, 4262, + 4264, 4266, 4268, 4270, 4272, 4274, 4276, 4278, 4280, 4282, + 4284, 4286, 4288, 4290, 4292, 4294, 4296, 4298, 4300, 4302, + 4304, 4306, 4308, 4310, 4312, 4314, 4316, 4318, 4320, 4322, + 4324, 4326, 4328, 4330, 4332, 4334, 4336, 4338, 4340, 4342, + 4344, 4346, 4348, 4350, 4352, 4354, 4356, 4358, 4360, 4362, + 4364, 4366, 4368, 4370, 4372, 4374, 4376, 4378, 4380, 4382, + 4384, 4386, 4388, 4390, 4392, 4394, 4396, 4398, 4400, 4402, + 4404, 4406, 4408, 4410, 4412, 4414, 4416, 4418, 4420, 4422, + 4424, 4426, 4428, 4430, 4432, 4434, 4436, 4438, 4440, 4442, + 4444, 4446, 4448, 4450, 4452, 4454, 4456, 4458, 4460, 4462, + 4464, 4466, 4468, 4470, 4472, 4474, 4476, 4478, 4480, 4482, + 4484, 4486, 4488, 4490, 4492, 4494, 4496, 4498, 4500, 4502, + 4504, 4506, 4508, 4510, 4512, 4514, 4516, 4518, 4520, 4522, + 4524, 4526, 4528, 4530, 4532, 4534, 4536, 4538, 4540, 4542, + 4544, 4546, 4548, 4550, 4552, 4554, 4556, 4558, 4560, 4562, + 4564, 4566, 4568, 4570, 4572, 4574, 4576, 4578, 4580, 4582, + 4584, 4586, 4588, 4590, 4592, 4594, 4596, 4598, 4600, 4602, + 4604, 4606, 4608, 4610, 4612, 4614, 4616, 4618, 4620, 4622, + 4624, 4626, 4628, 4630, 4632, 4634, 4636, 4638, 4640, 4642, + 4644, 4646, 4648, 4650, 4652, 4654, 4656, 4658, 4660, 4662, + 4664, 4666, 4668, 4670, 4672, 4674, 4676, 4678, 4680, 4682, + 4684, 4686, 4688, 4690, 4692, 4694, 4696, 4698, 4700, 4702, + 4704, 4706, 4708, 4710, 4712, 4714, 4716, 4718, 4720, 4722, + 4724, 4726, 4728, 4730, 4732, 4734, 4736, 4738, 4740, 4742, + 4744, 4746, 4748, 4750, 4752, 4754, 4756, 4758, 4760, 4762, + 4764, 4766, 4768, 4770, 4772, 4774, 4776, 4778, 4780, 4782, + 4784, 4786, 4788, 4790, 4792, 4794, 4796, 4798, 4800, 4802, + 4804, 4806, 4808, 4810, 4812, 4814, 4816, 4818, 4820, 4822, + 4824, 4826, 4828, 4830, 4832, 4834, 4836, 4838, 4840, 4842, + 4844, 4846, 4848, 4850, 4852, 4854, 4856, 4858, 4860, 4862, + 4864, 4866, 4868, 4870, 4872, 4874, 4876, 4878, 4880, 4882, + 4884, 4886, 4888, 4890, 4892, 4894, 4896, 4898, 4900, 4902, + 4904, 4906, 4908, 4910, 4912, 4914, 4916, 4918, 4920, 4922, + 4924, 4926, 4928, 4930, 4932, 4934, 4936, 4938, 4940, 4942, + 4944, 4946, 4948, 4950, 4952, 4954, 4956, 4958, 4960, 4962, + 4964, 4966, 4968, 4970, 4972, 4974, 4976, 4978, 4980, 4982, + 4984, 4986, 4988, 4990, 4992, 4994, 4996, 4998, 5000, 5002, + 5004, 5006, 5008, 5010, 5012, 5014, 5016, 5018, 5020, 5022, + 5024, 5026, 5028, 5030, 5032, 5034, 5036, 5038, 5040, 5042, + 5044, 5046, 5048, 5050, 5052, 5054, 5056, 5058, 5060, 5062, + 5064, 5066, 5068, 5070, 5072, 5074, 5076, 5078, 5080, 5082, + 5084, 5086, 5088, 5090, 5092, 5094, 5096, 5098, 5100, 5102, + 5104, 5106, 5108, 5110, 5112, 5114, 5116, 5118, 5120, 5122, + 5124, 5126, 5128, 5130, 5132, 5134, 5136, 5138, 5140, 5142, + 5144, 5146, 5148, 5150, 5152, 5154, 5156, 5158, 5160, 5162, + 5164, 5166, 5168, 5170, 5172, 5174, 5176, 5178, 5180, 5182, + 5184, 5186, 5188, 5190, 5192, 5194, 5196, 5198, 5200, 5202, + 5204, 5206, 5208, 5210, 5212, 5214, 5216, 5218, 5220, 5222, + 5224, 5226, 5228, 5230, 5232, 5234, 5236, 5238, 5240, 5242, + 5244, 5246, 5248, 5250, 5252, 5254, 5256, 5258, 5260, 5262, + 5264, 5266, 5268, 5270, 5272, 5274, 5276, 5278, 5280, 5282, + 5284, 5286, 5288, 5290, 5292, 5294, 5296, 5298, 5300, 5302, + 5304, 5306, 5308, 5310, 5312, 5314, 5316, 5318, 5320, 5322, + 5324, 5326, 5328, 5330, 5332, 5334, 5336, 5338, 5340 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int16 yyrhs[] = { - 500, 0, -1, 501, -1, 501, 492, 502, -1, 502, - -1, 829, -1, 543, -1, 503, -1, 861, -1, 868, - -1, 830, -1, 609, -1, 871, -1, 515, -1, 605, - -1, 819, -1, 539, -1, 552, -1, 514, -1, 857, - -1, 598, -1, 541, -1, 833, -1, 831, -1, 832, - -1, 822, -1, 520, -1, 850, -1, 538, -1, 816, - -1, 518, -1, 626, -1, 550, -1, 608, -1, 852, - -1, 862, -1, 844, -1, 865, -1, 869, -1, -1, - 29, 397, 690, 511, -1, 29, 397, 187, 150, 690, - 511, -1, 29, 196, 797, 511, -1, 29, 196, 187, - 150, 797, 511, -1, 29, 362, 797, 511, -1, 29, - 362, 187, 150, 797, 511, -1, 29, 444, 797, 511, - -1, 29, 444, 187, 150, 797, 511, -1, 506, -1, - 504, 506, -1, 368, 115, 732, -1, 135, 115, -1, - 340, -1, 340, 545, 546, -1, 368, 547, -1, 368, - 172, 597, -1, 510, -1, 507, 493, 510, -1, 23, - 577, -1, 23, 187, 266, 150, 577, -1, 23, 75, - 577, -1, 23, 75, 187, 266, 150, 577, -1, 29, - 519, 805, 505, -1, 29, 519, 805, 135, 266, 271, - -1, 29, 519, 805, 368, 266, 271, -1, 29, 519, - 805, 368, 384, 549, -1, 29, 519, 805, 368, 565, - -1, 29, 519, 805, 339, 565, -1, 29, 519, 805, - 368, 387, 805, -1, 29, 519, 805, 23, 172, 597, - 36, 186, 555, -1, 29, 519, 805, 504, -1, 29, - 519, 805, 135, 186, -1, 29, 519, 805, 135, 186, - 187, 150, -1, 135, 519, 187, 150, 805, 602, -1, - 135, 519, 805, 602, -1, 29, 519, 805, 513, 419, - 702, 699, 509, -1, 29, 519, 805, 512, -1, 23, - 567, -1, 29, 86, 799, 553, -1, 435, 86, 799, - -1, 135, 86, 187, 150, 799, 602, -1, 135, 86, - 799, 602, -1, 368, 238, -1, 368, 428, -1, 368, - 565, -1, 339, 565, -1, 512, -1, 432, 732, -1, - -1, 560, -1, 368, 560, -1, 23, 560, -1, 135, - 575, -1, 508, -1, 511, 493, 508, -1, 285, 489, - 507, 490, -1, 368, 107, -1, 368, -1, -1, 111, - 799, -1, 111, 311, 799, -1, 111, 27, -1, 111, - 311, 27, -1, 93, 419, 810, 36, 142, 489, 516, - 490, -1, 517, -1, -1, 804, -1, 517, 493, 804, - -1, 29, 354, 799, 335, 408, 799, -1, 29, 397, - 690, 335, 408, 799, -1, 29, 397, 187, 150, 690, - 335, 408, 799, -1, 29, 362, 797, 335, 408, 799, - -1, 29, 362, 187, 150, 797, 335, 408, 799, -1, - 29, 444, 797, 335, 408, 799, -1, 29, 444, 187, - 150, 797, 335, 408, 799, -1, 29, 196, 797, 335, - 408, 799, -1, 29, 196, 187, 150, 797, 335, 408, - 799, -1, 29, 397, 690, 335, 519, 799, 408, 799, - -1, 29, 397, 187, 150, 690, 335, 519, 799, 408, - 799, -1, 29, 397, 690, 335, 86, 799, 408, 799, - -1, 29, 397, 187, 150, 690, 335, 86, 799, 408, - 799, -1, 75, -1, -1, 524, 206, 212, 522, 521, - 527, 529, -1, 626, -1, 294, 530, 437, 626, -1, - 489, 534, 490, 626, -1, 489, 534, 490, 294, 530, - 437, 626, -1, 115, 438, -1, 797, -1, 797, 36, - 805, -1, 489, 536, 490, 696, -1, 281, 86, 799, - -1, -1, 631, -1, -1, 805, 786, -1, 537, 478, - 732, -1, 489, 531, 490, 478, 732, -1, 281, 84, - 523, 131, 430, 368, 535, 696, -1, 281, 84, 523, - 131, 267, -1, -1, 805, 532, 533, 644, 645, -1, - 737, 532, 533, 644, 645, -1, 489, 732, 490, 532, - 533, 644, 645, -1, 342, 789, -1, -1, 431, -1, - 396, -1, 537, -1, 531, 493, 537, -1, 73, 810, - -1, -1, 810, -1, -1, 525, -1, 534, 493, 525, - -1, 526, -1, 535, 493, 526, -1, 528, -1, 536, - 493, 528, -1, 805, 786, -1, 308, 805, -1, 308, - 805, 478, 849, -1, 308, 805, 489, 764, 490, -1, - 93, 596, 362, 797, 540, -1, 93, 596, 362, 187, - 266, 150, 797, 540, -1, 544, -1, -1, 149, 799, - 542, -1, 93, 596, 397, 873, 36, 149, 799, 542, - 872, -1, 93, 596, 397, 187, 266, 150, 873, 36, - 149, 799, 542, 872, -1, 489, 762, 490, -1, -1, - 29, 362, 797, 544, -1, 29, 362, 187, 150, 797, - 544, -1, 547, -1, 544, 547, -1, 451, -1, 475, - -1, -1, 4, -1, 480, 4, -1, 481, 4, -1, - 549, -1, 36, 704, -1, 55, 546, -1, 106, -1, - 264, 106, -1, 195, 548, 546, -1, 244, 546, -1, - 252, 546, -1, 264, 244, -1, 264, 252, -1, 295, - 54, 810, -1, 362, 257, 810, -1, 382, 545, 546, - -1, 340, -1, 340, 545, 546, -1, 54, -1, -1, - 803, -1, 480, 803, -1, 481, 803, -1, 19, 551, - -1, 47, 551, -1, 382, 551, -1, 79, 551, -1, - 141, 551, -1, 347, 551, -1, 454, -1, 410, -1, - -1, 93, 596, 397, 797, 489, 584, 490, 572, 564, - -1, 93, 596, 397, 187, 266, 150, 797, 489, 584, - 490, 572, 564, -1, 93, 286, 337, 596, 397, 797, - 489, 584, 490, 572, 564, -1, -1, 553, 576, -1, - 591, -1, 880, -1, 759, -1, 546, -1, 804, -1, - 265, -1, 489, 544, 490, -1, -1, 804, -1, 264, - 22, -1, 341, -1, 58, -1, 368, 271, -1, 368, - 115, -1, 86, 799, 559, -1, 559, -1, 571, -1, - 73, 810, -1, 266, 271, -1, 271, -1, 425, 583, - -1, 314, 218, 583, -1, 67, 489, 732, 490, 566, - -1, 432, 81, 799, -1, 115, 733, -1, 172, 597, - 36, 186, 555, -1, 329, 797, 586, 594, 562, -1, - 575, 556, -1, 281, 430, 557, -1, 561, -1, 588, - -1, 561, 588, -1, 588, 561, -1, -1, 285, 489, - 578, 490, -1, -1, 281, 79, 135, -1, 281, 79, - 120, 350, -1, 281, 79, 313, 350, -1, -1, 489, - 569, 490, -1, 264, 198, -1, -1, 86, 799, 592, - -1, 592, -1, 78, -1, 87, -1, 116, -1, 186, - -1, 197, -1, 384, -1, 387, -1, 27, -1, 589, - -1, 569, 493, 589, -1, 432, 196, 580, -1, 117, - -1, 266, 117, -1, 200, 118, -1, 200, 189, -1, - 451, 565, -1, 451, 279, -1, 453, 279, -1, -1, - 489, 579, 490, -1, 574, 194, 568, -1, 574, 147, - 568, -1, -1, 814, -1, 266, 117, -1, 117, -1, - 200, 189, -1, 200, 118, -1, 266, 434, -1, 264, - 198, -1, 805, 702, 563, 587, -1, 560, -1, 578, - 493, 560, -1, 582, -1, 579, 493, 582, -1, 805, - -1, 577, -1, 595, -1, 567, -1, 814, 478, 554, - -1, 814, -1, 451, 573, -1, -1, 593, -1, -1, - 805, -1, 489, 590, 490, -1, -1, 587, 558, -1, - -1, 281, 120, 557, -1, 814, 478, 554, -1, 814, - -1, 814, 491, 814, 478, 554, -1, 814, 491, 814, - -1, 585, -1, 590, 493, 585, -1, 702, -1, 807, - 811, 484, 419, -1, 369, 807, 811, 484, 419, -1, - 67, 489, 732, 490, 553, -1, 425, 489, 590, 490, - 583, 553, -1, 425, 570, 553, -1, 314, 218, 489, - 590, 490, 583, 553, -1, 314, 218, 570, 553, -1, - 165, 218, 489, 590, 490, 329, 797, 586, 594, 562, - 553, -1, 581, -1, 593, 493, 581, -1, 242, 169, - -1, 242, 299, -1, 242, 374, -1, -1, 228, 797, - 574, -1, 403, -1, 401, -1, 232, 403, -1, 232, - 401, -1, 174, 403, -1, 174, 401, -1, 428, -1, - -1, 30, -1, 54, 115, -1, 135, 599, 187, 150, - 601, 602, -1, 135, 599, 601, 602, -1, 135, 600, - 187, 150, 798, 602, -1, 135, 600, 798, 602, -1, - 135, 603, 799, 281, 810, 602, -1, 135, 603, 187, - 150, 799, 281, 810, 602, -1, 135, 419, 604, 602, - -1, 135, 419, 187, 150, 604, 602, -1, 397, -1, - 362, -1, 170, -1, 239, -1, 444, -1, 243, 444, - -1, 196, -1, 165, 397, -1, 74, -1, 90, -1, - 384, -1, 404, 357, 298, -1, 404, 357, 127, -1, - 404, 357, 402, -1, 404, 357, 83, -1, 21, 245, - -1, 144, 413, -1, 153, -1, 165, 107, 455, -1, - 320, -1, 354, -1, 365, -1, 810, -1, 601, 493, - 810, -1, 58, -1, 341, -1, -1, 306, -1, 351, - -1, 413, -1, 702, -1, 604, 493, 702, -1, 93, - 606, 797, 607, 36, 732, -1, 170, -1, 239, -1, - 489, 490, -1, 489, 764, 490, -1, 524, 430, 858, - 368, 535, 680, 859, 529, -1, 91, 621, 797, 586, - 619, 610, 615, 624, 611, 545, 616, -1, 91, 489, - 818, 490, 408, 615, 624, 545, 616, -1, 168, -1, - 408, -1, 613, 122, 804, -1, -1, 623, -1, 612, - 493, 623, -1, 432, -1, -1, 36, -1, -1, 319, - -1, -1, 620, -1, 489, 625, 490, -1, 841, -1, - 546, -1, 482, -1, 489, 612, 490, -1, -1, 814, - 617, -1, 451, 279, -1, -1, 620, 622, -1, -1, - 50, -1, -1, 50, -1, 279, -1, 167, -1, 121, - 614, 804, -1, 271, 614, 804, -1, 95, -1, 182, - -1, 321, 614, 804, -1, 143, 614, 804, -1, 164, - 321, 590, -1, 164, 321, 482, -1, 164, 266, 271, - 590, -1, 164, 271, 590, -1, 139, 804, -1, 841, - -1, 804, -1, 385, -1, 386, -1, 618, -1, 625, - 493, 618, -1, 628, -1, 627, -1, 489, 628, 490, - -1, 489, 627, 490, -1, 630, -1, 629, 641, -1, - 629, 640, 672, 647, -1, 629, 640, 646, 673, -1, - 631, 629, -1, 631, 629, 641, -1, 631, 629, 640, - 672, 647, -1, 631, 629, 640, 646, 673, -1, 630, - -1, 627, -1, 361, 639, 788, 634, 680, 696, 663, - 671, 741, 651, -1, 361, 638, 789, 634, 680, 696, - 663, 671, 741, 651, -1, 679, -1, 397, 690, -1, - 629, 424, 637, 629, -1, 629, 210, 637, 629, -1, - 629, 145, 637, 629, -1, 451, 632, -1, 475, 632, - -1, 451, 327, 632, -1, 633, -1, 632, 493, 633, - -1, 799, 812, 36, 489, 818, 490, -1, 212, 635, - -1, -1, 403, 636, 797, -1, 401, 636, 797, -1, - 232, 403, 636, 797, -1, 232, 401, 636, 797, -1, - 174, 403, 636, 797, -1, 174, 401, 636, 797, -1, - 428, 636, 797, -1, 397, 797, -1, 797, -1, 397, - -1, -1, 27, -1, 130, -1, -1, 130, -1, 130, - 281, 489, 762, 490, -1, 27, -1, -1, 641, -1, - -1, 287, 54, 642, -1, 643, -1, 642, 493, 643, - -1, 732, 432, 759, 645, -1, 732, 644, 645, -1, - 37, -1, 124, -1, -1, 474, 160, -1, 474, 222, - -1, -1, 648, 649, -1, 649, 648, -1, 648, -1, - 649, -1, 646, -1, -1, 229, 657, -1, 229, 657, - 493, 658, -1, 158, 662, 659, 661, 282, -1, 158, - 662, 661, 282, -1, 278, 658, -1, 278, 659, 661, - -1, 4, 484, -1, 9, 484, -1, 4, 303, -1, - 9, 303, -1, 9, -1, 9, 350, -1, 432, 352, - 653, -1, -1, 805, -1, -1, 652, 489, 650, 490, - 656, -1, 650, -1, 650, 489, 805, 490, -1, 650, - 489, 805, 493, 9, 490, -1, 399, 653, -1, 654, - -1, -1, 336, 489, 9, 490, -1, -1, 732, -1, - 27, -1, 732, -1, 734, -1, 480, 660, -1, 481, - 660, -1, 803, -1, 4, -1, 349, -1, 350, -1, - 160, -1, 263, -1, 177, 54, 664, -1, -1, 665, - -1, 664, 493, 665, -1, 732, -1, 666, -1, 668, - -1, 667, -1, 669, -1, 489, 490, -1, 348, 489, - 762, 490, -1, 96, 489, 762, 490, -1, 178, 370, - 489, 664, 490, -1, 178, -1, 179, -1, 181, 732, - -1, -1, 674, -1, 163, 323, 282, -1, 672, -1, - -1, 675, -1, 674, 675, -1, 676, 677, 678, -1, - 163, 430, -1, 163, 264, 218, 430, -1, 163, 371, - -1, 163, 218, 371, -1, 276, 796, -1, -1, 270, - -1, 375, 237, -1, -1, 438, 489, 762, 490, -1, - 679, 493, 489, 762, 490, -1, 168, 681, -1, -1, - 682, -1, 681, 493, 682, -1, 690, 685, 655, -1, - 691, 686, 655, -1, 223, 691, 686, -1, 627, 685, - 655, -1, 223, 627, 685, -1, 683, -1, 489, 683, - 490, 684, -1, 489, 683, 490, -1, 682, 94, 217, - 682, -1, 682, 687, 217, 682, 689, -1, 682, 217, - 682, 689, -1, 682, 260, 687, 217, 682, -1, 682, - 260, 217, 682, -1, 36, 805, 489, 798, 490, -1, - 36, 806, -1, 805, 489, 798, 490, -1, 805, -1, - 684, -1, -1, 684, -1, 36, 489, 697, 490, -1, - 36, 805, 489, 697, 490, -1, 805, 489, 697, 490, - -1, -1, 169, 688, -1, 226, 688, -1, 345, 688, - -1, 202, -1, 290, -1, -1, 432, 489, 798, 490, - -1, 281, 732, -1, 797, -1, 797, 482, -1, 282, - 797, -1, 282, 489, 797, 490, -1, 737, 695, -1, - 350, 168, 489, 693, 490, 695, -1, 737, 694, -1, - 692, -1, 693, 493, 692, -1, 36, 489, 697, 490, - -1, -1, 475, 288, -1, -1, 448, 732, -1, -1, - 698, -1, 697, 493, 698, -1, 805, 702, 699, -1, - 73, 810, -1, -1, 805, 702, -1, 700, 493, 805, - 702, -1, 349, -1, 390, -1, 704, 703, -1, 369, - 704, 703, -1, 704, 35, 487, 803, 488, -1, 369, - 704, 35, 487, 803, 488, -1, 704, 35, -1, 369, - 704, 35, -1, 701, 489, 700, 490, 703, -1, 240, - 489, 766, 490, 703, -1, 703, 487, 488, -1, 703, - 487, 803, 488, -1, -1, 706, -1, 708, -1, 710, - -1, 714, -1, 720, -1, 721, 731, -1, 721, 489, - 803, 490, -1, 708, -1, 711, -1, 715, -1, 720, - -1, 809, 707, -1, 489, 762, 490, -1, -1, 208, - -1, 209, -1, 376, -1, 49, -1, 324, -1, 161, - 709, -1, 134, 310, -1, 113, 707, -1, 112, 707, - -1, 274, 707, -1, 52, -1, 489, 803, 490, -1, - -1, 712, -1, 713, -1, 712, -1, 713, -1, 51, - 719, 489, 762, 490, -1, 51, 719, -1, 716, -1, - 717, -1, 716, -1, 717, -1, 718, 489, 803, 490, - -1, 718, -1, 65, 719, -1, 64, 719, -1, 439, - -1, 259, 65, 719, -1, 259, 64, 719, -1, 261, - 719, -1, 441, -1, -1, 407, 489, 803, 490, 722, - -1, 407, 722, -1, 406, 489, 803, 490, 722, -1, - 406, 722, -1, 211, -1, 475, 406, 472, -1, 453, - 406, 472, -1, -1, 469, -1, 470, -1, 254, -1, - 255, -1, 109, -1, 110, -1, 184, -1, 185, -1, - 250, -1, 251, -1, 358, -1, 359, -1, 248, -1, - 249, -1, 246, -1, 247, -1, 723, -1, 724, -1, - 725, -1, 726, -1, 727, -1, 728, -1, 729, -1, - 730, -1, 723, 408, 724, -1, 725, 408, 726, -1, - 725, 408, 727, -1, 725, 408, 728, -1, 726, 408, - 727, -1, 726, 408, 728, -1, 727, 408, 728, -1, - -1, 734, -1, 732, 11, 702, -1, 732, 73, 810, - -1, 732, 41, 406, 472, 732, -1, 480, 732, -1, - 481, 732, -1, 732, 480, 732, -1, 732, 481, 732, - -1, 732, 482, 732, -1, 732, 483, 732, -1, 732, - 484, 732, -1, 732, 485, 732, -1, 732, 476, 732, - -1, 732, 477, 732, -1, 732, 478, 732, -1, 732, - 16, 732, -1, 732, 17, 732, -1, 732, 18, 732, - -1, 732, 758, 732, -1, 758, 732, -1, 732, 758, - -1, 732, 33, 732, -1, 732, 286, 732, -1, 266, - 732, -1, 473, 732, -1, 732, 173, 732, -1, 732, - 228, 732, -1, 732, 228, 732, 143, 732, -1, 732, - 473, 228, 732, -1, 732, 473, 228, 732, 143, 732, - -1, 732, 188, 732, -1, 732, 188, 732, 143, 732, - -1, 732, 473, 188, 732, -1, 732, 473, 188, 732, - 143, 732, -1, 732, 373, 408, 732, -1, 732, 373, - 408, 732, 143, 732, -1, 732, 473, 373, 408, 732, - -1, 732, 473, 373, 408, 732, 143, 732, -1, 732, - 214, 271, -1, 732, 215, -1, 732, 214, 266, 271, - -1, 732, 266, 271, -1, 732, 269, -1, 752, -1, - 494, 754, 495, -1, 487, 763, 488, -1, 752, 15, - 732, -1, 782, 15, 732, -1, 752, 292, 752, -1, - 732, 214, 415, -1, 732, 214, 266, 415, -1, 732, - 214, 156, -1, 732, 214, 266, 156, -1, 732, 214, - 426, -1, 732, 214, 266, 426, -1, 732, 214, 130, - 168, 732, -1, 732, 214, 266, 130, 168, 732, -1, - 732, 214, 276, 489, 766, 490, -1, 732, 214, 266, - 276, 489, 766, 490, -1, 732, 48, 787, 733, 33, - 732, -1, 732, 473, 48, 787, 733, 33, 732, -1, - 732, 48, 394, 733, 33, 732, -1, 732, 473, 48, - 394, 733, 33, 732, -1, 732, 193, 776, -1, 732, - 473, 193, 776, -1, 732, 760, 755, 627, -1, 732, - 760, 755, 489, 732, 490, -1, 115, -1, 35, 487, - 763, 488, -1, 734, -1, 733, 11, 702, -1, 480, - 733, -1, 481, 733, -1, 733, 480, 733, -1, 733, - 481, 733, -1, 733, 482, 733, -1, 733, 483, 733, - -1, 733, 484, 733, -1, 733, 485, 733, -1, 733, - 476, 733, -1, 733, 477, 733, -1, 733, 478, 733, - -1, 733, 16, 733, -1, 733, 17, 733, -1, 733, - 18, 733, -1, 733, 758, 733, -1, 758, 733, -1, - 733, 758, -1, 733, 214, 130, 168, 733, -1, 733, - 214, 266, 130, 168, 733, -1, 733, 214, 276, 489, - 766, 490, -1, 733, 214, 266, 276, 489, 766, 490, - -1, 782, -1, 802, -1, 496, 9, -1, 497, 786, - -1, 10, 786, -1, 489, 732, 490, 786, -1, 777, - -1, 736, 786, -1, 627, -1, 627, 785, -1, 150, - 627, -1, 670, 489, 762, 490, -1, 801, 489, 490, - -1, 801, 489, 764, 640, 490, -1, 801, 489, 440, - 765, 640, 490, -1, 801, 489, 764, 493, 440, 765, - 640, 490, -1, 801, 489, 27, 764, 640, 490, -1, - 801, 489, 130, 764, 640, 490, -1, 801, 489, 482, - 490, -1, 735, 739, 740, 744, -1, 738, -1, 735, - -1, 738, -1, 74, 163, 489, 732, 490, -1, 99, - -1, 102, -1, 102, 489, 803, 490, -1, 103, -1, - 103, 489, 803, 490, -1, 233, -1, 233, 489, 803, - 490, -1, 234, -1, 234, 489, 803, 490, -1, 100, - -1, 104, -1, 367, -1, 431, -1, 98, -1, 101, - -1, 61, 489, 732, 36, 702, 490, -1, 418, 489, - 732, 36, 702, 490, -1, 155, 489, 767, 490, -1, - 293, 489, 769, 490, -1, 307, 489, 771, 490, -1, - 392, 489, 772, 490, -1, 412, 489, 732, 36, 702, - 490, -1, 414, 489, 53, 775, 490, -1, 414, 489, - 224, 775, 490, -1, 414, 489, 409, 775, 490, -1, - 414, 489, 775, 490, -1, 272, 489, 732, 493, 732, - 490, -1, 72, 489, 762, 490, -1, 452, 177, 489, - 641, 490, -1, -1, 159, 489, 448, 732, 490, -1, - -1, 450, 742, -1, -1, 743, -1, 742, 493, 743, - -1, 805, 36, 745, -1, 291, 745, -1, 291, 805, - -1, -1, 489, 746, 747, 640, 748, 490, -1, 805, - -1, -1, 300, 54, 762, -1, -1, 322, 749, -1, - 350, 749, -1, -1, 750, -1, 48, 750, 33, 750, - -1, 421, 309, -1, 421, 162, -1, 97, 349, -1, - 732, 309, -1, 732, 162, -1, 349, 489, 762, 490, - -1, 349, 489, 490, -1, 751, -1, 489, 762, 493, - 732, 490, -1, 806, 498, 732, -1, 753, -1, 754, - 493, 753, -1, 34, -1, 378, -1, 27, -1, 8, - -1, 757, -1, 480, -1, 481, -1, 482, -1, 483, - -1, 484, -1, 485, -1, 476, -1, 477, -1, 478, - -1, 16, -1, 17, -1, 18, -1, 8, -1, 283, - 489, 761, 490, -1, 756, -1, 283, 489, 761, 490, - -1, 756, -1, 283, 489, 761, 490, -1, 228, -1, - 473, 228, -1, 173, -1, 473, 173, -1, 188, -1, - 473, 188, -1, 756, -1, 805, 491, 761, -1, 732, - -1, 762, 493, 732, -1, 762, -1, -1, 765, -1, - 764, 493, 765, -1, 732, -1, 813, 13, 732, -1, - 813, 14, 732, -1, 702, -1, 766, 493, 702, -1, - 768, 168, 732, -1, -1, 3, -1, 723, -1, 724, - -1, 725, -1, 726, -1, 727, -1, 728, -1, 729, - -1, 730, -1, 804, -1, 732, 770, 773, 774, -1, - 732, 770, 773, -1, 304, 732, -1, 733, 193, 733, - -1, -1, 732, 773, 774, -1, 732, 774, 773, -1, - 732, 773, -1, 732, 774, -1, 762, -1, -1, 168, - 732, -1, 163, 732, -1, 732, 168, 762, -1, 168, - 762, -1, 762, -1, 627, -1, 489, 762, 490, -1, - 60, 781, 778, 780, 141, -1, 779, -1, 778, 779, - -1, 447, 732, 405, 732, -1, 137, 732, -1, -1, - 732, -1, -1, 805, -1, 805, 785, -1, 491, 800, - -1, 487, 732, 488, -1, 487, 784, 498, 784, 488, - -1, 732, -1, -1, 783, -1, 785, 783, -1, -1, - 786, 783, -1, 40, -1, -1, 789, -1, -1, 790, - -1, 789, 493, 790, -1, 732, 36, 815, -1, 732, - 3, -1, 732, -1, 482, 792, 795, -1, 805, 491, - 482, 792, 795, -1, 146, 489, 798, 490, -1, 146, - 805, -1, 791, -1, -1, 732, 36, 805, -1, 793, - -1, 794, 493, 793, -1, 337, 489, 794, 490, -1, - 337, 793, -1, -1, 797, -1, 796, 493, 797, -1, - 806, -1, 805, 785, -1, 799, -1, 798, 493, 799, - -1, 805, -1, 814, -1, 808, -1, 805, 785, -1, - 803, -1, 4, -1, 804, 786, -1, 6, -1, 7, - -1, 801, 804, -1, 801, 489, 764, 640, 490, 804, - -1, 705, 804, -1, 721, 489, 732, 490, 731, -1, - 721, 803, 731, -1, 721, 804, 731, -1, 415, -1, - 156, -1, 271, -1, 9, -1, 5, -1, 3, -1, - 874, -1, 875, -1, 805, -1, 5, -1, 3, -1, - 874, -1, 879, -1, 3, -1, 874, -1, 876, -1, - 3, -1, 874, -1, 877, -1, 805, -1, 805, 811, - -1, 491, 800, -1, 811, 491, 800, -1, 489, 798, - 490, -1, -1, 807, -1, 3, -1, 878, -1, 874, - -1, 880, -1, 814, -1, 5, -1, 311, 799, 817, - 36, 818, -1, 489, 766, 490, -1, -1, 626, -1, - 520, -1, 608, -1, 857, -1, 93, 354, 805, 820, - -1, 93, 354, 187, 266, 150, 805, 820, -1, 820, - 821, -1, -1, 552, -1, 822, -1, 539, -1, 869, - -1, 93, 828, 196, 825, 826, 281, 797, 824, 489, - 536, 490, 827, 696, -1, 93, 828, 196, 825, 187, - 266, 150, 580, 281, 797, 824, 489, 536, 490, 827, - 696, -1, 805, -1, 432, 823, -1, -1, 82, -1, - -1, 580, -1, -1, 451, 565, -1, -1, 425, -1, - -1, 29, 397, 690, 368, 354, 799, -1, 29, 397, - 187, 150, 690, 368, 354, 799, -1, 29, 362, 797, - 368, 354, 799, -1, 29, 362, 187, 150, 797, 368, - 354, 799, -1, 29, 444, 797, 368, 354, 799, -1, - 29, 444, 187, 150, 797, 368, 354, 799, -1, 164, - 68, -1, 68, -1, 152, 108, 804, 616, -1, 192, - 108, 804, -1, 151, 836, -1, 151, 840, 834, 836, - -1, 151, 442, 836, -1, 151, 489, 839, 490, 836, - -1, 442, -1, -1, 841, -1, 546, -1, -1, 626, - -1, 520, -1, 608, -1, 857, -1, 871, -1, 3, - -1, 874, -1, 878, -1, 837, -1, 804, -1, 842, - -1, 839, 493, 842, -1, 32, -1, 31, -1, 415, - -1, 156, -1, 281, -1, 838, -1, 843, 835, -1, - 837, -1, 840, -1, 368, 845, -1, 368, 232, 845, - -1, 368, 366, 845, -1, 368, 174, 845, -1, 846, - -1, 867, 168, 97, -1, 406, 472, 848, -1, 354, - 804, -1, 867, 408, 849, -1, 867, 478, 849, -1, - 867, 408, 115, -1, 867, 478, 115, -1, 841, -1, - 546, -1, 804, -1, 3, -1, 721, 804, 731, -1, - 721, 489, 803, 490, 804, -1, 546, -1, 115, -1, - 232, -1, 847, -1, 849, 493, 847, -1, 231, 851, - -1, 804, -1, 433, 854, 856, 834, -1, 433, 854, - 856, 834, 797, -1, 433, 854, 856, 834, 861, -1, - 433, 489, 855, 490, -1, 433, 489, 855, 490, 797, - 812, -1, 840, -1, 442, -1, 167, -1, 169, -1, - 3, -1, 169, -1, -1, 853, -1, 855, 493, 853, - -1, 167, -1, -1, 524, 120, 168, 858, 860, 859, - 529, -1, 690, -1, 690, 805, -1, 690, 36, 805, - -1, 448, 732, -1, -1, 432, 681, -1, -1, 840, - 834, -1, 840, 834, 797, 812, -1, 339, 864, -1, - 867, -1, 27, -1, 863, -1, 406, 472, -1, 410, - 216, 227, -1, 866, 626, -1, 393, 626, -1, 393, - 867, -1, 866, 867, -1, 866, 406, 472, -1, 866, - 410, 216, 227, -1, 866, 27, -1, 372, -1, 125, - -1, 805, -1, 867, 491, 805, -1, 56, 735, -1, - 93, 596, 444, 797, 586, 827, 36, 626, 870, -1, - 93, 286, 337, 596, 444, 797, 586, 827, 36, 626, - 870, -1, 93, 596, 327, 444, 797, 489, 590, 490, - 827, 36, 626, 870, -1, 93, 286, 337, 596, 327, - 444, 797, 489, 590, 490, 827, 36, 626, 870, -1, - 451, 67, 284, -1, 451, 59, 67, 284, -1, 451, - 232, 67, 284, -1, -1, 93, 596, 397, 873, 36, - 626, 872, -1, 93, 596, 397, 187, 266, 150, 873, - 36, 626, 872, -1, 451, 107, -1, 451, 264, 107, - -1, -1, 797, 586, 572, 564, -1, 19, -1, 20, - -1, 21, -1, 22, -1, 23, -1, 24, -1, 25, - -1, 26, -1, 28, -1, 29, -1, 30, -1, 38, - -1, 39, -1, 41, -1, 42, -1, 43, -1, 45, - -1, 46, -1, 47, -1, 54, -1, 55, -1, 56, - -1, 57, -1, 58, -1, 59, -1, 62, -1, 63, - -1, 66, -1, 68, -1, 69, -1, 70, -1, 71, - -1, 76, -1, 77, -1, 78, -1, 79, -1, 80, - -1, 81, -1, 83, -1, 84, -1, 85, -1, 87, - -1, 88, -1, 89, -1, 90, -1, 91, -1, 92, - -1, 95, -1, 96, -1, 97, -1, 105, -1, 106, - -1, 107, -1, 108, -1, 109, -1, 110, -1, 111, - -1, 114, -1, 116, -1, 118, -1, 119, -1, 120, - -1, 121, -1, 122, -1, 123, -1, 125, -1, 126, - -1, 127, -1, 128, -1, 129, -1, 132, -1, 133, - -1, 134, -1, 135, -1, 136, -1, 138, -1, 139, - -1, 140, -1, 142, -1, 143, -1, 144, -1, 146, - -1, 147, -1, 148, -1, 149, -1, 151, -1, 152, - -1, 153, -1, 154, -1, 157, -1, 159, -1, 160, - -1, 162, -1, 164, -1, 166, -1, 170, -1, 171, - -1, 172, -1, 174, -1, 176, -1, 180, -1, 182, - -1, 183, -1, 184, -1, 185, -1, 186, -1, 187, - -1, 189, -1, 190, -1, 191, -1, 192, -1, 194, - -1, 195, -1, 196, -1, 197, -1, 198, -1, 199, - -1, 201, -1, 204, -1, 205, -1, 206, -1, 207, - -1, 213, -1, 216, -1, 218, -1, 219, -1, 220, - -1, 221, -1, 222, -1, 225, -1, 227, -1, 230, - -1, 231, -1, 232, -1, 235, -1, 236, -1, 237, - -1, 238, -1, 239, -1, 241, -1, 242, -1, 243, - -1, 244, -1, 245, -1, 246, -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, 262, -1, 263, -1, 264, -1, 267, -1, 268, - -1, 270, -1, 273, -1, 275, -1, 276, -1, 277, - -1, 279, -1, 280, -1, 283, -1, 284, -1, 285, - -1, 288, -1, 291, -1, 294, -1, 295, -1, 296, - -1, 297, -1, 298, -1, 299, -1, 300, -1, 301, - -1, 302, -1, 303, -1, 305, -1, 306, -1, 308, - -1, 309, -1, 311, -1, 312, -1, 313, -1, 315, - -1, 316, -1, 317, -1, 318, -1, 319, -1, 320, - -1, 321, -1, 322, -1, 323, -1, 325, -1, 326, - -1, 327, -1, 328, -1, 330, -1, 331, -1, 332, - -1, 333, -1, 334, -1, 335, -1, 336, -1, 337, - -1, 338, -1, 339, -1, 340, -1, 341, -1, 343, - -1, 344, -1, 346, -1, 347, -1, 348, -1, 350, - -1, 351, -1, 352, -1, 353, -1, 354, -1, 355, - -1, 356, -1, 357, -1, 358, -1, 359, -1, 360, - -1, 362, -1, 363, -1, 364, -1, 365, -1, 366, - -1, 368, -1, 370, -1, 371, -1, 372, -1, 374, - -1, 375, -1, 377, -1, 379, -1, 380, -1, 381, - -1, 382, -1, 383, -1, 384, -1, 385, -1, 386, - -1, 387, -1, 388, -1, 389, -1, 391, -1, 393, - -1, 395, -1, 396, -1, 398, -1, 400, -1, 401, - -1, 402, -1, 403, -1, 404, -1, 410, -1, 411, - -1, 413, -1, 416, -1, 417, -1, 419, -1, 420, - -1, 421, -1, 422, -1, 423, -1, 426, -1, 427, - -1, 428, -1, 429, -1, 430, -1, 433, -1, 434, - -1, 435, -1, 436, -1, 437, -1, 441, -1, 443, - -1, 444, -1, 445, -1, 446, -1, 449, -1, 452, - -1, 453, -1, 454, -1, 455, -1, 456, -1, 457, - -1, 469, -1, 470, -1, 471, -1, 472, -1, 48, - -1, 49, -1, 51, -1, 52, -1, 64, -1, 65, - -1, 72, -1, 112, -1, 113, -1, 150, -1, 155, - -1, 161, -1, 178, -1, 179, -1, 203, -1, 208, - -1, 209, -1, 211, -1, 240, -1, 259, -1, 261, - -1, 265, -1, 272, -1, 274, -1, 289, -1, 293, - -1, 307, -1, 310, -1, 324, -1, 349, -1, 369, - -1, 376, -1, 390, -1, 392, -1, 406, -1, 407, - -1, 412, -1, 414, -1, 418, -1, 438, -1, 439, - -1, 458, -1, 459, -1, 460, -1, 461, -1, 462, - -1, 463, -1, 464, -1, 465, -1, 466, -1, 467, - -1, 468, -1, 44, -1, 50, -1, 74, -1, 82, - -1, 94, -1, 101, -1, 167, -1, 169, -1, 173, - -1, 188, -1, 202, -1, 214, -1, 215, -1, 217, - -1, 226, -1, 228, -1, 240, -1, 260, -1, 269, - -1, 290, -1, 292, -1, 345, -1, 373, -1, 390, - -1, 399, -1, 442, -1, 44, -1, 50, -1, 74, - -1, 82, -1, 94, -1, 101, -1, 167, -1, 169, - -1, 173, -1, 188, -1, 202, -1, 214, -1, 215, - -1, 217, -1, 226, -1, 228, -1, 260, -1, 269, - -1, 290, -1, 292, -1, 345, -1, 373, -1, 399, - -1, 418, -1, 442, -1, 48, -1, 49, -1, 51, - -1, 52, -1, 65, -1, 64, -1, 72, -1, 112, - -1, 113, -1, 150, -1, 155, -1, 161, -1, 178, - -1, 179, -1, 203, -1, 209, -1, 211, -1, 208, - -1, 240, -1, 259, -1, 261, -1, 265, -1, 272, - -1, 274, -1, 289, -1, 293, -1, 307, -1, 310, - -1, 324, -1, 349, -1, 369, -1, 376, -1, 390, - -1, 392, -1, 406, -1, 407, -1, 412, -1, 414, - -1, 418, -1, 438, -1, 439, -1, 458, -1, 459, - -1, 460, -1, 461, -1, 462, -1, 463, -1, 464, - -1, 465, -1, 466, -1, 467, -1, 468, -1, 44, - -1, 50, -1, 74, -1, 82, -1, 94, -1, 101, - -1, 167, -1, 169, -1, 173, -1, 188, -1, 202, - -1, 214, -1, 215, -1, 217, -1, 226, -1, 228, - -1, 240, -1, 260, -1, 269, -1, 290, -1, 292, - -1, 345, -1, 373, -1, 390, -1, 399, -1, 418, - -1, 442, -1, 27, -1, 31, -1, 32, -1, 33, - -1, 34, -1, 35, -1, 36, -1, 37, -1, 40, - -1, 53, -1, 60, -1, 61, -1, 67, -1, 73, - -1, 75, -1, 86, -1, 93, -1, 98, -1, 99, - -1, 100, -1, 102, -1, 103, -1, 104, -1, 115, - -1, 117, -1, 124, -1, 130, -1, 131, -1, 137, - -1, 141, -1, 145, -1, 156, -1, 158, -1, 163, - -1, 165, -1, 168, -1, 175, -1, 177, -1, 181, - -1, 193, -1, 200, -1, 210, -1, 212, -1, 223, - -1, 224, -1, 229, -1, 233, -1, 234, -1, 266, - -1, 271, -1, 278, -1, 281, -1, 282, -1, 286, - -1, 287, -1, 304, -1, 314, -1, 329, -1, 342, - -1, 361, -1, 367, -1, 378, -1, 394, -1, 397, - -1, 405, -1, 408, -1, 409, -1, 415, -1, 424, - -1, 425, -1, 431, -1, 432, -1, 440, -1, 447, - -1, 448, -1, 450, -1, 451, -1 + 504, 0, -1, 505, -1, 505, 496, 506, -1, 506, + -1, 835, -1, 547, -1, 507, -1, 867, -1, 874, + -1, 836, -1, 613, -1, 877, -1, 519, -1, 609, + -1, 825, -1, 543, -1, 556, -1, 518, -1, 863, + -1, 602, -1, 545, -1, 839, -1, 837, -1, 838, + -1, 828, -1, 524, -1, 856, -1, 542, -1, 822, + -1, 522, -1, 630, -1, 554, -1, 612, -1, 858, + -1, 868, -1, 850, -1, 871, -1, 875, -1, -1, + 29, 401, 696, 515, -1, 29, 401, 187, 150, 696, + 515, -1, 29, 197, 803, 515, -1, 29, 197, 187, + 150, 803, 515, -1, 29, 366, 803, 515, -1, 29, + 366, 187, 150, 803, 515, -1, 29, 448, 803, 515, + -1, 29, 448, 187, 150, 803, 515, -1, 510, -1, + 508, 510, -1, 372, 115, 738, -1, 135, 115, -1, + 344, -1, 344, 549, 550, -1, 372, 551, -1, 372, + 172, 601, -1, 514, -1, 511, 497, 514, -1, 23, + 581, -1, 23, 187, 268, 150, 581, -1, 23, 75, + 581, -1, 23, 75, 187, 268, 150, 581, -1, 29, + 523, 811, 509, -1, 29, 523, 811, 135, 268, 273, + -1, 29, 523, 811, 372, 268, 273, -1, 29, 523, + 811, 372, 388, 553, -1, 29, 523, 811, 372, 569, + -1, 29, 523, 811, 342, 569, -1, 29, 523, 811, + 372, 391, 811, -1, 29, 523, 811, 23, 172, 601, + 36, 186, 559, -1, 29, 523, 811, 508, -1, 29, + 523, 811, 135, 186, -1, 29, 523, 811, 135, 186, + 187, 150, -1, 135, 523, 187, 150, 811, 606, -1, + 135, 523, 811, 606, -1, 29, 523, 811, 517, 423, + 708, 705, 513, -1, 29, 523, 811, 516, -1, 23, + 571, -1, 29, 86, 805, 557, -1, 439, 86, 805, + -1, 135, 86, 187, 150, 805, 606, -1, 135, 86, + 805, 606, -1, 372, 240, -1, 372, 432, -1, 372, + 569, -1, 342, 569, -1, 516, -1, 436, 738, -1, + -1, 564, -1, 372, 564, -1, 23, 564, -1, 135, + 579, -1, 512, -1, 515, 497, 512, -1, 287, 493, + 511, 494, -1, 372, 107, -1, 372, -1, -1, 111, + 805, -1, 111, 313, 805, -1, 111, 27, -1, 111, + 313, 27, -1, 93, 423, 816, 36, 142, 493, 520, + 494, -1, 521, -1, -1, 810, -1, 521, 497, 810, + -1, 29, 358, 805, 338, 412, 805, -1, 29, 401, + 696, 338, 412, 805, -1, 29, 401, 187, 150, 696, + 338, 412, 805, -1, 29, 366, 803, 338, 412, 805, + -1, 29, 366, 187, 150, 803, 338, 412, 805, -1, + 29, 448, 803, 338, 412, 805, -1, 29, 448, 187, + 150, 803, 338, 412, 805, -1, 29, 197, 803, 338, + 412, 805, -1, 29, 197, 187, 150, 803, 338, 412, + 805, -1, 29, 401, 696, 338, 523, 805, 412, 805, + -1, 29, 401, 187, 150, 696, 338, 523, 805, 412, + 805, -1, 29, 401, 696, 338, 86, 805, 412, 805, + -1, 29, 401, 187, 150, 696, 338, 86, 805, 412, + 805, -1, 75, -1, -1, 528, 207, 214, 526, 525, + 531, 533, -1, 630, -1, 296, 534, 441, 630, -1, + 493, 538, 494, 630, -1, 493, 538, 494, 296, 534, + 441, 630, -1, 115, 442, -1, 803, -1, 803, 36, + 811, -1, 493, 540, 494, 702, -1, 283, 86, 805, + -1, -1, 635, -1, -1, 811, 792, -1, 541, 482, + 738, -1, 493, 535, 494, 482, 738, -1, 283, 84, + 527, 131, 434, 372, 539, 702, -1, 283, 84, 527, + 131, 269, -1, -1, 811, 536, 537, 649, 650, -1, + 743, 536, 537, 649, 650, -1, 493, 738, 494, 536, + 537, 649, 650, -1, 346, 795, -1, -1, 435, -1, + 400, -1, 541, -1, 535, 497, 541, -1, 73, 816, + -1, -1, 816, -1, -1, 529, -1, 538, 497, 529, + -1, 530, -1, 539, 497, 530, -1, 532, -1, 540, + 497, 532, -1, 811, 792, -1, 310, 811, -1, 310, + 811, 482, 855, -1, 310, 811, 493, 770, 494, -1, + 93, 600, 366, 803, 544, -1, 93, 600, 366, 187, + 268, 150, 803, 544, -1, 548, -1, -1, 149, 805, + 546, -1, 93, 600, 401, 879, 36, 149, 805, 546, + 878, -1, 93, 600, 401, 187, 268, 150, 879, 36, + 149, 805, 546, 878, -1, 493, 768, 494, -1, -1, + 29, 366, 803, 548, -1, 29, 366, 187, 150, 803, + 548, -1, 551, -1, 548, 551, -1, 455, -1, 479, + -1, -1, 4, -1, 484, 4, -1, 485, 4, -1, + 553, -1, 36, 710, -1, 55, 550, -1, 106, -1, + 266, 106, -1, 196, 552, 550, -1, 246, 550, -1, + 254, 550, -1, 266, 246, -1, 266, 254, -1, 297, + 54, 816, -1, 366, 259, 816, -1, 386, 549, 550, + -1, 344, -1, 344, 549, 550, -1, 54, -1, -1, + 809, -1, 484, 809, -1, 485, 809, -1, 19, 555, + -1, 47, 555, -1, 386, 555, -1, 79, 555, -1, + 141, 555, -1, 351, 555, -1, 458, -1, 414, -1, + -1, 93, 600, 401, 803, 493, 588, 494, 576, 568, + -1, 93, 600, 401, 187, 268, 150, 803, 493, 588, + 494, 576, 568, -1, 93, 288, 340, 600, 401, 803, + 493, 588, 494, 576, 568, -1, -1, 557, 580, -1, + 595, -1, 886, -1, 765, -1, 550, -1, 810, -1, + 267, -1, 493, 548, 494, -1, -1, 810, -1, 266, + 22, -1, 345, -1, 58, -1, 372, 273, -1, 372, + 115, -1, 86, 805, 563, -1, 563, -1, 575, -1, + 73, 816, -1, 268, 273, -1, 273, -1, 429, 587, + -1, 316, 220, 587, -1, 67, 493, 738, 494, 570, + -1, 436, 81, 805, -1, 115, 739, -1, 172, 601, + 36, 186, 559, -1, 332, 803, 590, 598, 566, -1, + 579, 560, -1, 283, 434, 561, -1, 565, -1, 592, + -1, 565, 592, -1, 592, 565, -1, -1, 287, 493, + 582, 494, -1, -1, 283, 79, 135, -1, 283, 79, + 120, 354, -1, 283, 79, 315, 354, -1, -1, 493, + 573, 494, -1, 266, 199, -1, -1, 86, 805, 596, + -1, 596, -1, 78, -1, 87, -1, 116, -1, 186, + -1, 198, -1, 388, -1, 391, -1, 27, -1, 593, + -1, 573, 497, 593, -1, 436, 197, 584, -1, 117, + -1, 268, 117, -1, 201, 118, -1, 201, 190, -1, + 455, 569, -1, 455, 281, -1, 457, 281, -1, -1, + 493, 583, 494, -1, 578, 195, 572, -1, 578, 147, + 572, -1, -1, 820, -1, 268, 117, -1, 117, -1, + 201, 190, -1, 201, 118, -1, 268, 438, -1, 266, + 199, -1, 811, 708, 567, 591, -1, 564, -1, 582, + 497, 564, -1, 586, -1, 583, 497, 586, -1, 811, + -1, 581, -1, 599, -1, 571, -1, 820, 482, 558, + -1, 820, -1, 455, 577, -1, -1, 597, -1, -1, + 811, -1, 493, 594, 494, -1, -1, 591, 562, -1, + -1, 283, 120, 561, -1, 820, 482, 558, -1, 820, + -1, 820, 495, 820, 482, 558, -1, 820, 495, 820, + -1, 589, -1, 594, 497, 589, -1, 708, -1, 813, + 817, 488, 423, -1, 373, 813, 817, 488, 423, -1, + 67, 493, 738, 494, 557, -1, 429, 493, 594, 494, + 587, 557, -1, 429, 574, 557, -1, 316, 220, 493, + 594, 494, 587, 557, -1, 316, 220, 574, 557, -1, + 165, 220, 493, 594, 494, 332, 803, 590, 598, 566, + 557, -1, 585, -1, 597, 497, 585, -1, 244, 169, + -1, 244, 301, -1, 244, 378, -1, -1, 230, 803, + 578, -1, 407, -1, 405, -1, 234, 407, -1, 234, + 405, -1, 174, 407, -1, 174, 405, -1, 432, -1, + -1, 30, -1, 54, 115, -1, 135, 603, 187, 150, + 605, 606, -1, 135, 603, 605, 606, -1, 135, 604, + 187, 150, 804, 606, -1, 135, 604, 804, 606, -1, + 135, 607, 805, 283, 816, 606, -1, 135, 607, 187, + 150, 805, 283, 816, 606, -1, 135, 423, 608, 606, + -1, 135, 423, 187, 150, 608, 606, -1, 401, -1, + 366, -1, 170, -1, 241, -1, 448, -1, 245, 448, + -1, 197, -1, 165, 401, -1, 74, -1, 90, -1, + 388, -1, 408, 361, 300, -1, 408, 361, 127, -1, + 408, 361, 406, -1, 408, 361, 83, -1, 21, 247, + -1, 144, 417, -1, 153, -1, 165, 107, 459, -1, + 322, -1, 358, -1, 369, -1, 816, -1, 605, 497, + 816, -1, 58, -1, 345, -1, -1, 308, -1, 355, + -1, 417, -1, 708, -1, 608, 497, 708, -1, 93, + 610, 803, 611, 36, 738, -1, 170, -1, 241, -1, + 493, 494, -1, 493, 770, 494, -1, 528, 434, 864, + 372, 539, 686, 865, 533, -1, 91, 625, 803, 590, + 623, 614, 619, 628, 615, 549, 620, -1, 91, 493, + 824, 494, 412, 619, 628, 549, 620, -1, 168, -1, + 412, -1, 617, 122, 810, -1, -1, 627, -1, 616, + 497, 627, -1, 436, -1, -1, 36, -1, -1, 321, + -1, -1, 624, -1, 493, 629, 494, -1, 847, -1, + 550, -1, 486, -1, 493, 616, 494, -1, -1, 820, + 621, -1, 455, 281, -1, -1, 624, 626, -1, -1, + 50, -1, -1, 50, -1, 281, -1, 167, -1, 121, + 618, 810, -1, 273, 618, 810, -1, 95, -1, 182, + -1, 324, 618, 810, -1, 143, 618, 810, -1, 164, + 324, 594, -1, 164, 324, 486, -1, 164, 268, 273, + 594, -1, 164, 273, 594, -1, 139, 810, -1, 847, + -1, 810, -1, 389, -1, 390, -1, 622, -1, 629, + 497, 622, -1, 632, -1, 631, -1, 493, 632, 494, + -1, 493, 631, 494, -1, 634, -1, 633, 646, -1, + 633, 645, 678, 652, -1, 633, 645, 651, 679, -1, + 635, 633, -1, 635, 633, 646, -1, 635, 633, 645, + 678, 652, -1, 635, 633, 645, 651, 679, -1, 634, + -1, 631, -1, 365, 643, 794, 638, 686, 702, 668, + 676, 747, 677, 656, -1, 365, 642, 795, 638, 686, + 702, 668, 676, 747, 677, 656, -1, 685, -1, 401, + 696, -1, 633, 428, 641, 633, -1, 633, 212, 641, + 633, -1, 633, 145, 641, 633, -1, 455, 636, -1, + 479, 636, -1, 455, 330, 636, -1, 637, -1, 636, + 497, 637, -1, 805, 818, 36, 493, 824, 494, -1, + 214, 639, -1, -1, 407, 640, 803, -1, 405, 640, + 803, -1, 234, 407, 640, 803, -1, 234, 405, 640, + 803, -1, 174, 407, 640, 803, -1, 174, 405, 640, + 803, -1, 432, 640, 803, -1, 401, 803, -1, 803, + -1, 401, -1, -1, 27, -1, 130, -1, -1, 130, + -1, 130, 283, 493, 768, 494, -1, 27, -1, -1, + 188, 275, -1, 343, 275, -1, -1, 646, -1, -1, + 289, 54, 647, -1, 289, 54, 27, 649, 650, -1, + 289, 54, 486, 649, 650, -1, 648, -1, 647, 497, + 648, -1, 738, 436, 765, 650, -1, 738, 649, 650, + -1, 37, -1, 124, -1, -1, 478, 160, -1, 478, + 224, -1, -1, 653, 654, -1, 654, 653, -1, 653, + -1, 654, -1, 651, -1, -1, 231, 662, -1, 231, + 662, 497, 663, -1, 158, 667, 664, 666, 284, -1, + 158, 667, 666, 284, -1, 280, 663, -1, 280, 664, + 666, -1, 4, 488, -1, 9, 488, -1, 4, 305, + -1, 9, 305, -1, 9, -1, 9, 354, -1, 436, + 356, 658, -1, -1, 811, -1, -1, 657, 493, 655, + 494, 661, -1, 655, -1, 655, 493, 811, 494, -1, + 655, 493, 811, 497, 9, 494, -1, 403, 658, -1, + 659, -1, -1, 339, 493, 9, 494, -1, -1, 738, + -1, 27, -1, 738, 488, -1, 4, 305, -1, 9, + 305, -1, 738, -1, 740, -1, 484, 665, -1, 485, + 665, -1, 809, -1, 4, -1, 353, -1, 354, -1, + 160, -1, 265, -1, 177, 54, 669, -1, 177, 54, + 27, -1, 177, 54, 486, -1, -1, 670, -1, 669, + 497, 670, -1, 738, -1, 671, -1, 673, -1, 672, + -1, 674, -1, 493, 494, -1, 352, 493, 768, 494, + -1, 96, 493, 768, 494, -1, 178, 374, 493, 669, + 494, -1, 178, -1, 179, -1, 181, 738, -1, -1, + 323, 738, -1, -1, 680, -1, 163, 326, 284, -1, + 678, -1, -1, 681, -1, 680, 681, -1, 682, 683, + 684, -1, 163, 434, -1, 163, 266, 220, 434, -1, + 163, 375, -1, 163, 220, 375, -1, 278, 802, -1, + -1, 272, -1, 379, 239, -1, -1, 442, 493, 768, + 494, -1, 685, 497, 493, 768, 494, -1, 168, 687, + -1, -1, 688, -1, 687, 497, 688, -1, 696, 691, + 660, -1, 697, 692, 660, -1, 225, 697, 692, -1, + 631, 691, 660, -1, 225, 631, 691, -1, 689, -1, + 493, 689, 494, 690, -1, 493, 689, 494, -1, 688, + 94, 219, 688, -1, 688, 693, 219, 688, 695, -1, + 688, 219, 688, 695, -1, 688, 262, 693, 219, 688, + -1, 688, 262, 219, 688, -1, 36, 811, 493, 804, + 494, -1, 36, 812, -1, 811, 493, 804, 494, -1, + 811, -1, 690, -1, -1, 690, -1, 36, 493, 703, + 494, -1, 36, 811, 493, 703, 494, -1, 811, 493, + 703, 494, -1, -1, 169, 694, -1, 228, 694, -1, + 349, 694, -1, 203, -1, 292, -1, -1, 436, 493, + 804, 494, -1, 283, 738, -1, 803, -1, 803, 486, + -1, 284, 803, -1, 284, 493, 803, 494, -1, 743, + 701, -1, 354, 168, 493, 699, 494, 701, -1, 743, + 700, -1, 698, -1, 699, 497, 698, -1, 36, 493, + 703, 494, -1, -1, 479, 290, -1, -1, 452, 738, + -1, -1, 704, -1, 703, 497, 704, -1, 811, 708, + 705, -1, 73, 816, -1, -1, 811, 708, -1, 706, + 497, 811, 708, -1, 353, -1, 394, -1, 710, 709, + -1, 373, 710, 709, -1, 710, 35, 491, 809, 492, + -1, 373, 710, 35, 491, 809, 492, -1, 710, 35, + -1, 373, 710, 35, -1, 707, 493, 706, 494, 709, + -1, 242, 493, 772, 494, 709, -1, 709, 491, 492, + -1, 709, 491, 809, 492, -1, -1, 712, -1, 714, + -1, 716, -1, 720, -1, 726, -1, 727, 737, -1, + 727, 493, 809, 494, -1, 714, -1, 717, -1, 721, + -1, 726, -1, 815, 713, -1, 493, 768, 494, -1, + -1, 210, -1, 211, -1, 380, -1, 49, -1, 327, + -1, 161, 715, -1, 134, 312, -1, 113, 713, -1, + 112, 713, -1, 276, 713, -1, 52, -1, 493, 809, + 494, -1, -1, 718, -1, 719, -1, 718, -1, 719, + -1, 51, 725, 493, 768, 494, -1, 51, 725, -1, + 722, -1, 723, -1, 722, -1, 723, -1, 724, 493, + 809, 494, -1, 724, -1, 65, 725, -1, 64, 725, + -1, 443, -1, 261, 65, 725, -1, 261, 64, 725, + -1, 263, 725, -1, 445, -1, -1, 411, 493, 809, + 494, 728, -1, 411, 728, -1, 410, 493, 809, 494, + 728, -1, 410, 728, -1, 213, -1, 479, 410, 476, + -1, 457, 410, 476, -1, -1, 473, -1, 474, -1, + 256, -1, 257, -1, 109, -1, 110, -1, 184, -1, + 185, -1, 252, -1, 253, -1, 362, -1, 363, -1, + 250, -1, 251, -1, 248, -1, 249, -1, 729, -1, + 730, -1, 731, -1, 732, -1, 733, -1, 734, -1, + 735, -1, 736, -1, 729, 412, 730, -1, 731, 412, + 732, -1, 731, 412, 733, -1, 731, 412, 734, -1, + 732, 412, 733, -1, 732, 412, 734, -1, 733, 412, + 734, -1, -1, 740, -1, 738, 11, 708, -1, 738, + 73, 816, -1, 738, 41, 410, 476, 738, -1, 484, + 738, -1, 485, 738, -1, 738, 484, 738, -1, 738, + 485, 738, -1, 738, 486, 738, -1, 738, 487, 738, + -1, 738, 488, 738, -1, 738, 489, 738, -1, 738, + 480, 738, -1, 738, 481, 738, -1, 738, 482, 738, + -1, 738, 16, 738, -1, 738, 17, 738, -1, 738, + 18, 738, -1, 738, 764, 738, -1, 764, 738, -1, + 738, 764, -1, 738, 33, 738, -1, 738, 288, 738, + -1, 268, 738, -1, 477, 738, -1, 738, 173, 738, + -1, 738, 230, 738, -1, 738, 230, 738, 143, 738, + -1, 738, 477, 230, 738, -1, 738, 477, 230, 738, + 143, 738, -1, 738, 189, 738, -1, 738, 189, 738, + 143, 738, -1, 738, 477, 189, 738, -1, 738, 477, + 189, 738, 143, 738, -1, 738, 377, 412, 738, -1, + 738, 377, 412, 738, 143, 738, -1, 738, 477, 377, + 412, 738, -1, 738, 477, 377, 412, 738, 143, 738, + -1, 738, 216, 273, -1, 738, 217, -1, 738, 216, + 268, 273, -1, 738, 268, 273, -1, 738, 271, -1, + 758, -1, 498, 760, 499, -1, 491, 769, 492, -1, + 758, 15, 738, -1, 788, 15, 738, -1, 758, 294, + 758, -1, 738, 216, 419, -1, 738, 216, 268, 419, + -1, 738, 216, 156, -1, 738, 216, 268, 156, -1, + 738, 216, 430, -1, 738, 216, 268, 430, -1, 738, + 216, 130, 168, 738, -1, 738, 216, 268, 130, 168, + 738, -1, 738, 216, 278, 493, 772, 494, -1, 738, + 216, 268, 278, 493, 772, 494, -1, 738, 48, 793, + 739, 33, 738, -1, 738, 477, 48, 793, 739, 33, + 738, -1, 738, 48, 398, 739, 33, 738, -1, 738, + 477, 48, 398, 739, 33, 738, -1, 738, 194, 782, + -1, 738, 477, 194, 782, -1, 738, 766, 761, 631, + -1, 738, 766, 761, 493, 738, 494, -1, 115, -1, + 35, 491, 769, 492, -1, 740, -1, 739, 11, 708, + -1, 484, 739, -1, 485, 739, -1, 739, 484, 739, + -1, 739, 485, 739, -1, 739, 486, 739, -1, 739, + 487, 739, -1, 739, 488, 739, -1, 739, 489, 739, + -1, 739, 480, 739, -1, 739, 481, 739, -1, 739, + 482, 739, -1, 739, 16, 739, -1, 739, 17, 739, + -1, 739, 18, 739, -1, 739, 764, 739, -1, 764, + 739, -1, 739, 764, -1, 739, 216, 130, 168, 739, + -1, 739, 216, 268, 130, 168, 739, -1, 739, 216, + 278, 493, 772, 494, -1, 739, 216, 268, 278, 493, + 772, 494, -1, 788, -1, 808, -1, 500, 9, -1, + 501, 792, -1, 10, 792, -1, 493, 738, 494, 792, + -1, 783, -1, 742, 792, -1, 631, -1, 631, 791, + -1, 150, 631, -1, 675, 493, 768, 494, -1, 807, + 493, 494, -1, 807, 493, 770, 645, 644, 494, -1, + 807, 493, 444, 771, 645, 644, 494, -1, 807, 493, + 770, 497, 444, 771, 645, 644, 494, -1, 807, 493, + 27, 770, 645, 644, 494, -1, 807, 493, 130, 770, + 645, 644, 494, -1, 807, 493, 486, 494, -1, 741, + 745, 746, 750, -1, 744, -1, 741, -1, 744, -1, + 74, 163, 493, 738, 494, -1, 99, -1, 102, -1, + 102, 493, 809, 494, -1, 103, -1, 103, 493, 809, + 494, -1, 235, -1, 235, 493, 809, 494, -1, 236, + -1, 236, 493, 809, 494, -1, 100, -1, 104, -1, + 371, -1, 435, -1, 98, -1, 101, -1, 61, 493, + 738, 36, 708, 494, -1, 422, 493, 738, 36, 708, + 494, -1, 155, 493, 773, 494, -1, 295, 493, 775, + 494, -1, 309, 493, 777, 494, -1, 396, 493, 778, + 494, -1, 416, 493, 738, 36, 708, 494, -1, 418, + 493, 53, 781, 494, -1, 418, 493, 226, 781, 494, + -1, 418, 493, 413, 781, 494, -1, 418, 493, 781, + 494, -1, 274, 493, 738, 497, 738, 494, -1, 72, + 493, 768, 494, -1, 456, 177, 493, 646, 494, -1, + -1, 159, 493, 452, 738, 494, -1, -1, 454, 748, + -1, -1, 749, -1, 748, 497, 749, -1, 811, 36, + 751, -1, 293, 751, -1, 293, 811, -1, -1, 493, + 752, 753, 645, 754, 494, -1, 811, -1, -1, 302, + 54, 768, -1, -1, 325, 755, -1, 354, 755, -1, + -1, 756, -1, 48, 756, 33, 756, -1, 425, 311, + -1, 425, 162, -1, 97, 353, -1, 738, 311, -1, + 738, 162, -1, 353, 493, 768, 494, -1, 353, 493, + 494, -1, 757, -1, 493, 768, 497, 738, 494, -1, + 812, 502, 738, -1, 759, -1, 760, 497, 759, -1, + 34, -1, 382, -1, 27, -1, 8, -1, 763, -1, + 484, -1, 485, -1, 486, -1, 487, -1, 488, -1, + 489, -1, 480, -1, 481, -1, 482, -1, 16, -1, + 17, -1, 18, -1, 8, -1, 285, 493, 767, 494, + -1, 762, -1, 285, 493, 767, 494, -1, 762, -1, + 285, 493, 767, 494, -1, 230, -1, 477, 230, -1, + 173, -1, 477, 173, -1, 189, -1, 477, 189, -1, + 762, -1, 811, 495, 767, -1, 738, -1, 768, 497, + 738, -1, 768, -1, -1, 771, -1, 770, 497, 771, + -1, 738, -1, 819, 13, 738, -1, 819, 14, 738, + -1, 708, -1, 772, 497, 708, -1, 774, 168, 738, + -1, -1, 3, -1, 729, -1, 730, -1, 731, -1, + 732, -1, 733, -1, 734, -1, 735, -1, 736, -1, + 810, -1, 738, 776, 779, 780, -1, 738, 776, 779, + -1, 306, 738, -1, 739, 194, 739, -1, -1, 738, + 779, 780, -1, 738, 780, 779, -1, 738, 779, -1, + 738, 780, -1, 768, -1, -1, 168, 738, -1, 163, + 738, -1, 738, 168, 768, -1, 168, 768, -1, 768, + -1, 631, -1, 493, 768, 494, -1, 60, 787, 784, + 786, 141, -1, 785, -1, 784, 785, -1, 451, 738, + 409, 738, -1, 137, 738, -1, -1, 738, -1, -1, + 811, -1, 811, 791, -1, 495, 806, -1, 491, 738, + 492, -1, 491, 790, 502, 790, 492, -1, 738, -1, + -1, 789, -1, 791, 789, -1, -1, 792, 789, -1, + 40, -1, -1, 795, -1, -1, 796, -1, 795, 497, + 796, -1, 738, 36, 821, -1, 738, 3, -1, 738, + -1, 486, 798, 801, -1, 811, 495, 486, 798, 801, + -1, 146, 493, 804, 494, -1, 146, 811, -1, 797, + -1, -1, 738, 36, 811, -1, 799, -1, 800, 497, + 799, -1, 340, 493, 800, 494, -1, 340, 799, -1, + -1, 803, -1, 802, 497, 803, -1, 812, -1, 811, + 791, -1, 805, -1, 804, 497, 805, -1, 811, -1, + 820, -1, 814, -1, 811, 791, -1, 809, -1, 4, + -1, 810, 792, -1, 6, -1, 7, -1, 807, 810, + -1, 807, 493, 770, 645, 644, 494, 810, -1, 711, + 810, -1, 727, 493, 738, 494, 737, -1, 727, 809, + 737, -1, 727, 810, 737, -1, 419, -1, 156, -1, + 273, -1, 9, -1, 5, -1, 3, -1, 880, -1, + 881, -1, 811, -1, 5, -1, 3, -1, 880, -1, + 885, -1, 3, -1, 880, -1, 882, -1, 3, -1, + 880, -1, 883, -1, 811, -1, 811, 817, -1, 495, + 806, -1, 817, 495, 806, -1, 493, 804, 494, -1, + -1, 813, -1, 3, -1, 884, -1, 880, -1, 886, + -1, 820, -1, 5, -1, 313, 805, 823, 36, 824, + -1, 493, 772, 494, -1, -1, 630, -1, 524, -1, + 612, -1, 863, -1, 93, 358, 811, 826, -1, 93, + 358, 187, 268, 150, 811, 826, -1, 826, 827, -1, + -1, 556, -1, 828, -1, 543, -1, 875, -1, 93, + 834, 197, 831, 832, 283, 803, 830, 493, 540, 494, + 833, 702, -1, 93, 834, 197, 831, 187, 268, 150, + 584, 283, 803, 830, 493, 540, 494, 833, 702, -1, + 811, -1, 436, 829, -1, -1, 82, -1, -1, 584, + -1, -1, 455, 569, -1, -1, 429, -1, -1, 29, + 401, 696, 372, 358, 805, -1, 29, 401, 187, 150, + 696, 372, 358, 805, -1, 29, 366, 803, 372, 358, + 805, -1, 29, 366, 187, 150, 803, 372, 358, 805, + -1, 29, 448, 803, 372, 358, 805, -1, 29, 448, + 187, 150, 803, 372, 358, 805, -1, 164, 68, -1, + 68, -1, 152, 108, 810, 620, -1, 193, 108, 810, + -1, 151, 842, -1, 151, 846, 840, 842, -1, 151, + 446, 842, -1, 151, 493, 845, 494, 842, -1, 446, + -1, -1, 847, -1, 550, -1, -1, 630, -1, 524, + -1, 612, -1, 863, -1, 877, -1, 3, -1, 880, + -1, 884, -1, 843, -1, 810, -1, 848, -1, 845, + 497, 848, -1, 32, -1, 31, -1, 419, -1, 156, + -1, 283, -1, 844, -1, 849, 841, -1, 843, -1, + 846, -1, 372, 851, -1, 372, 234, 851, -1, 372, + 370, 851, -1, 372, 174, 851, -1, 852, -1, 873, + 168, 97, -1, 410, 476, 854, -1, 358, 810, -1, + 873, 412, 855, -1, 873, 482, 855, -1, 873, 412, + 115, -1, 873, 482, 115, -1, 847, -1, 550, -1, + 810, -1, 3, -1, 727, 810, 737, -1, 727, 493, + 809, 494, 810, -1, 550, -1, 115, -1, 234, -1, + 853, -1, 855, 497, 853, -1, 233, 857, -1, 208, + 857, -1, 164, 208, 857, -1, 810, -1, 811, -1, + 437, 860, 862, 840, -1, 437, 860, 862, 840, 803, + -1, 437, 860, 862, 840, 867, -1, 437, 493, 861, + 494, -1, 437, 493, 861, 494, 803, 818, -1, 846, + -1, 446, -1, 167, -1, 169, -1, 3, -1, 169, + -1, -1, 859, -1, 861, 497, 859, -1, 167, -1, + -1, 528, 120, 168, 864, 866, 865, 533, -1, 696, + -1, 696, 811, -1, 696, 36, 811, -1, 452, 738, + -1, -1, 436, 687, -1, -1, 846, 840, -1, 846, + 840, 803, 818, -1, 342, 870, -1, 873, -1, 27, + -1, 869, -1, 410, 476, -1, 414, 218, 229, -1, + 872, 630, -1, 397, 630, -1, 397, 873, -1, 872, + 873, -1, 872, 410, 476, -1, 872, 414, 218, 229, + -1, 872, 27, -1, 376, -1, 125, -1, 811, -1, + 873, 495, 811, -1, 56, 741, -1, 93, 600, 448, + 803, 590, 833, 36, 630, 876, -1, 93, 288, 340, + 600, 448, 803, 590, 833, 36, 630, 876, -1, 93, + 600, 330, 448, 803, 493, 594, 494, 833, 36, 630, + 876, -1, 93, 288, 340, 600, 330, 448, 803, 493, + 594, 494, 833, 36, 630, 876, -1, 455, 67, 286, + -1, 455, 59, 67, 286, -1, 455, 234, 67, 286, + -1, -1, 93, 600, 401, 879, 36, 630, 878, -1, + 93, 600, 401, 187, 268, 150, 879, 36, 630, 878, + -1, 455, 107, -1, 455, 266, 107, -1, -1, 803, + 590, 576, 568, -1, 19, -1, 20, -1, 21, -1, + 22, -1, 23, -1, 24, -1, 25, -1, 26, -1, + 28, -1, 29, -1, 30, -1, 38, -1, 39, -1, + 41, -1, 42, -1, 43, -1, 45, -1, 46, -1, + 47, -1, 54, -1, 55, -1, 56, -1, 57, -1, + 58, -1, 59, -1, 62, -1, 63, -1, 66, -1, + 68, -1, 69, -1, 70, -1, 71, -1, 76, -1, + 77, -1, 78, -1, 79, -1, 80, -1, 81, -1, + 83, -1, 84, -1, 85, -1, 87, -1, 88, -1, + 89, -1, 90, -1, 91, -1, 92, -1, 95, -1, + 96, -1, 97, -1, 105, -1, 106, -1, 107, -1, + 108, -1, 109, -1, 110, -1, 111, -1, 114, -1, + 116, -1, 118, -1, 119, -1, 120, -1, 121, -1, + 122, -1, 123, -1, 125, -1, 126, -1, 127, -1, + 128, -1, 129, -1, 132, -1, 133, -1, 134, -1, + 135, -1, 136, -1, 138, -1, 139, -1, 140, -1, + 142, -1, 143, -1, 144, -1, 146, -1, 147, -1, + 148, -1, 149, -1, 151, -1, 152, -1, 153, -1, + 154, -1, 157, -1, 159, -1, 160, -1, 162, -1, + 164, -1, 166, -1, 170, -1, 171, -1, 172, -1, + 174, -1, 176, -1, 180, -1, 182, -1, 183, -1, + 184, -1, 185, -1, 186, -1, 187, -1, 188, -1, + 190, -1, 191, -1, 192, -1, 193, -1, 195, -1, + 196, -1, 197, -1, 198, -1, 199, -1, 200, -1, + 202, -1, 205, -1, 206, -1, 207, -1, 208, -1, + 209, -1, 215, -1, 218, -1, 220, -1, 221, -1, + 222, -1, 223, -1, 224, -1, 227, -1, 229, -1, + 232, -1, 233, -1, 234, -1, 237, -1, 238, -1, + 239, -1, 240, -1, 241, -1, 243, -1, 244, -1, + 245, -1, 246, -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, 264, -1, 265, -1, 266, -1, 269, -1, + 270, -1, 272, -1, 275, -1, 277, -1, 278, -1, + 279, -1, 281, -1, 282, -1, 285, -1, 286, -1, + 287, -1, 290, -1, 293, -1, 296, -1, 297, -1, + 298, -1, 299, -1, 300, -1, 301, -1, 302, -1, + 303, -1, 304, -1, 305, -1, 307, -1, 308, -1, + 310, -1, 311, -1, 313, -1, 314, -1, 315, -1, + 317, -1, 318, -1, 319, -1, 320, -1, 321, -1, + 322, -1, 324, -1, 325, -1, 326, -1, 328, -1, + 329, -1, 330, -1, 331, -1, 333, -1, 334, -1, + 335, -1, 336, -1, 337, -1, 338, -1, 339, -1, + 340, -1, 341, -1, 342, -1, 343, -1, 344, -1, + 345, -1, 347, -1, 348, -1, 350, -1, 351, -1, + 352, -1, 354, -1, 355, -1, 356, -1, 357, -1, + 358, -1, 359, -1, 360, -1, 361, -1, 362, -1, + 363, -1, 364, -1, 366, -1, 367, -1, 368, -1, + 369, -1, 370, -1, 372, -1, 374, -1, 375, -1, + 376, -1, 378, -1, 379, -1, 381, -1, 383, -1, + 384, -1, 385, -1, 386, -1, 387, -1, 388, -1, + 389, -1, 390, -1, 391, -1, 392, -1, 393, -1, + 395, -1, 397, -1, 399, -1, 400, -1, 402, -1, + 404, -1, 405, -1, 406, -1, 407, -1, 408, -1, + 414, -1, 415, -1, 417, -1, 420, -1, 421, -1, + 423, -1, 424, -1, 425, -1, 426, -1, 427, -1, + 430, -1, 431, -1, 432, -1, 433, -1, 434, -1, + 437, -1, 438, -1, 439, -1, 440, -1, 441, -1, + 445, -1, 447, -1, 448, -1, 449, -1, 450, -1, + 453, -1, 456, -1, 457, -1, 458, -1, 459, -1, + 460, -1, 461, -1, 473, -1, 474, -1, 475, -1, + 476, -1, 48, -1, 49, -1, 51, -1, 52, -1, + 64, -1, 65, -1, 72, -1, 112, -1, 113, -1, + 150, -1, 155, -1, 161, -1, 178, -1, 179, -1, + 204, -1, 210, -1, 211, -1, 213, -1, 242, -1, + 261, -1, 263, -1, 267, -1, 274, -1, 276, -1, + 291, -1, 295, -1, 309, -1, 312, -1, 327, -1, + 353, -1, 373, -1, 380, -1, 394, -1, 396, -1, + 410, -1, 411, -1, 416, -1, 418, -1, 422, -1, + 442, -1, 443, -1, 462, -1, 463, -1, 464, -1, + 465, -1, 466, -1, 467, -1, 468, -1, 469, -1, + 470, -1, 471, -1, 472, -1, 44, -1, 50, -1, + 74, -1, 82, -1, 94, -1, 101, -1, 167, -1, + 169, -1, 173, -1, 189, -1, 203, -1, 216, -1, + 217, -1, 219, -1, 228, -1, 230, -1, 242, -1, + 262, -1, 271, -1, 292, -1, 294, -1, 349, -1, + 377, -1, 394, -1, 403, -1, 446, -1, 44, -1, + 50, -1, 74, -1, 82, -1, 94, -1, 101, -1, + 167, -1, 169, -1, 173, -1, 189, -1, 203, -1, + 216, -1, 217, -1, 219, -1, 228, -1, 230, -1, + 262, -1, 271, -1, 292, -1, 294, -1, 349, -1, + 377, -1, 403, -1, 422, -1, 446, -1, 48, -1, + 49, -1, 51, -1, 52, -1, 65, -1, 64, -1, + 72, -1, 112, -1, 113, -1, 150, -1, 155, -1, + 161, -1, 178, -1, 179, -1, 204, -1, 211, -1, + 213, -1, 210, -1, 242, -1, 261, -1, 263, -1, + 267, -1, 274, -1, 276, -1, 291, -1, 295, -1, + 309, -1, 312, -1, 327, -1, 353, -1, 373, -1, + 380, -1, 394, -1, 396, -1, 410, -1, 411, -1, + 416, -1, 418, -1, 422, -1, 442, -1, 443, -1, + 462, -1, 463, -1, 464, -1, 465, -1, 466, -1, + 467, -1, 468, -1, 469, -1, 470, -1, 471, -1, + 472, -1, 44, -1, 50, -1, 74, -1, 82, -1, + 94, -1, 101, -1, 167, -1, 169, -1, 173, -1, + 189, -1, 203, -1, 216, -1, 217, -1, 219, -1, + 228, -1, 230, -1, 242, -1, 262, -1, 271, -1, + 292, -1, 294, -1, 349, -1, 377, -1, 394, -1, + 403, -1, 422, -1, 446, -1, 27, -1, 31, -1, + 32, -1, 33, -1, 34, -1, 35, -1, 36, -1, + 37, -1, 40, -1, 53, -1, 60, -1, 61, -1, + 67, -1, 73, -1, 75, -1, 86, -1, 93, -1, + 98, -1, 99, -1, 100, -1, 102, -1, 103, -1, + 104, -1, 115, -1, 117, -1, 124, -1, 130, -1, + 131, -1, 137, -1, 141, -1, 145, -1, 156, -1, + 158, -1, 163, -1, 165, -1, 168, -1, 175, -1, + 177, -1, 181, -1, 194, -1, 201, -1, 212, -1, + 214, -1, 225, -1, 226, -1, 231, -1, 235, -1, + 236, -1, 268, -1, 273, -1, 280, -1, 283, -1, + 284, -1, 288, -1, 289, -1, 306, -1, 316, -1, + 323, -1, 332, -1, 346, -1, 365, -1, 371, -1, + 382, -1, 398, -1, 401, -1, 409, -1, 412, -1, + 413, -1, 419, -1, 428, -1, 429, -1, 435, -1, + 436, -1, 444, -1, 451, -1, 452, -1, 454, -1, + 455, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 464, 464, 480, 492, 501, 502, 503, 504, 505, - 506, 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, 536, + 0, 465, 465, 481, 493, 502, 503, 504, 505, 506, + 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, 537, 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, @@ -217485,84 +232885,86 @@ static const yytype_uint16 yyrline[] = 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, 170, 186, 187, 206, 210, - 214, 231, 238, 245, 255, 256, 259, 271, 282, 290, - 295, 300, 305, 310, 318, 326, 331, 336, 343, 344, - 348, 349, 350, 357, 358, 362, 363, 367, 368, 372, - 376, 377, 380, 389, 400, 401, 402, 405, 406, 407, - 411, 412, 413, 414, 418, 419, 423, 425, 441, 443, - 448, 451, 459, 463, 467, 471, 475, 479, 486, 491, - 498, 499, 503, 507, 511, 515, 522, 529, 530, 535, - 536, 540, 541, 549, 569, 570, 572, 577, 578, 582, - 583, 586, 587, 612, 613, 617, 618, 622, 623, 624, - 625, 626, 630, 643, 650, 657, 664, 665, 669, 670, - 674, 675, 679, 680, 684, 685, 689, 700, 701, 702, - 703, 707, 708, 713, 714, 715, 724, 730, 748, 749, - 753, 754, 760, 766, 774, 782, 791, 800, 804, 830, - 834, 847, 861, 876, 888, 904, 910, 915, 921, 928, - 929, 937, 941, 945, 951, 958, 963, 964, 965, 966, - 970, 971, 983, 984, 989, 996, 1003, 1010, 1042, 1053, - 1066, 1071, 1072, 1075, 1076, 1079, 1080, 1085, 1086, 1091, - 1095, 1101, 1122, 1130, 1143, 1146, 1150, 1150, 1152, 1157, - 1164, 1169, 1175, 1180, 1186, 1192, 1201, 1203, 1206, 1210, - 1211, 1212, 1213, 1214, 1215, 1220, 1240, 1241, 1242, 1243, - 1254, 1268, 1269, 1275, 1280, 1285, 1290, 1295, 1300, 1305, - 1310, 1316, 1322, 1328, 1335, 1357, 1366, 1370, 1378, 1382, - 1390, 1402, 1423, 1427, 1433, 1437, 1450, 1458, 1468, 1470, - 1472, 1474, 1476, 1478, 1483, 1484, 1491, 1500, 1508, 1517, - 1528, 1536, 1537, 1538, 1542, 1542, 1545, 1545, 1548, 1548, - 1551, 1551, 1554, 1554, 1557, 1557, 1560, 1560, 1563, 1563, - 1566, 1568, 1570, 1572, 1574, 1576, 1578, 1580, 1582, 1587, - 1592, 1598, 1605, 1610, 1616, 1622, 1653, 1655, 1657, 1665, - 1680, 1682, 1684, 1686, 1688, 1690, 1692, 1694, 1696, 1698, - 1700, 1702, 1704, 1706, 1709, 1711, 1713, 1716, 1718, 1720, - 1722, 1725, 1730, 1735, 1742, 1747, 1754, 1759, 1767, 1772, - 1781, 1789, 1797, 1805, 1823, 1831, 1839, 1847, 1855, 1863, - 1867, 1871, 1875, 1883, 1891, 1907, 1915, 1923, 1931, 1939, - 1947, 1955, 1959, 1963, 1967, 1971, 1979, 1987, 1995, 2003, - 2023, 2045, 2056, 2063, 2077, 2093, 2095, 2097, 2099, 2101, - 2103, 2105, 2107, 2109, 2111, 2113, 2115, 2117, 2119, 2121, - 2123, 2125, 2127, 2129, 2131, 2135, 2139, 2143, 2157, 2158, - 2159, 2166, 2178, 2193, 2205, 2207, 2219, 2230, 2254, 2265, - 2274, 2278, 2284, 2291, 2298, 2308, 2315, 2343, 2378, 2389, - 2390, 2397, 2403, 2407, 2411, 2415, 2419, 2423, 2427, 2431, - 2435, 2439, 2443, 2447, 2451, 2455, 2459, 2463, 2465, 2467, - 2471, 2480, 2485, 2492, 2507, 2514, 2518, 2522, 2526, 2530, - 2544, 2545, 2549, 2550, 2558, 2559, 2563, 2564, 2569, 2577, - 2579, 2593, 2596, 2623, 2624, 2627, 2628, 2639, 2645, 2652, - 2661, 2678, 2723, 2731, 2739, 2747, 2755, 2776, 2777, 2780, - 2781, 2785, 2795, 2796, 2798, 2799, 2800, 2803, 2804, 2807, - 2808, 2809, 2810, 2811, 2812, 2813, 2814, 2815, 2816, 2817, - 2818, 2821, 2823, 2828, 2830, 2835, 2837, 2839, 2841, 2843, - 2845, 2847, 2849, 2863, 2865, 2869, 2873, 2880, 2885, 2892, - 2896, 2902, 2906, 2915, 2926, 2927, 2931, 2935, 2942, 2943, - 2944, 2945, 2946, 2947, 2948, 2949, 2950, 2951, 2961, 2965, - 2972, 2979, 2980, 2996, 3000, 3005, 3009, 3024, 3029, 3033, - 3036, 3039, 3040, 3041, 3044, 3051, 3061, 3075, 3076, 3080, - 3091, 3092, 3095, 3096, 3099, 3103, 3110, 3114, 3122, 3133, - 3134, 3138, 3139, 3143, 3144, 3147, 3148, 3158, 3159, 3163, - 3164, 3167, 3183, 3191, 3199, 3214, 3232, 3233, 3236, 3237, - 3240, 3244, 3245, 3248, 3249, 3250, 3260, 3261, 3272, 3276, - 3303, 3305, 3310, 3312, 3322, 3325, 3336, 3340, 3344, 3356, - 3360, 3369, 3376, 3408, 3412, 3416, 3420, 3424, 3428, 3432, - 3438, 3439, 3455, 3456, 3457, 3460, 3461, 3467, 3468, 3469, - 3472, 3473, 3474, 3477, 3478, 3479, 3482, 3483, 3486, 3488, - 3493, 3494, 3497, 3505, 3506, 3507, 3508, 3511, 3512, 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, 65, 66, 67, 72, 73, 78, 82, 90, 91, - 96, 97, 98, 104, 109, 117, 118, 10, 16, 22, - 28, 38, 39, 47, 58, 70, 78, 86, 93, 103, - 105, 111, 115, 119, 134, 141, 142, 143, 147, 148, - 7, 16, 8, 22, 36, 48, 56, 70, 71, 72, - 73, 74, 87, 88, 93, 94, 98, 99, 7, 21, - 25, 32, 43, 44, 50, 51, 9, 19, 2, 7, - 14, 24, 25, 32, 3, 10, 17, 24, 31, 38, - 45, 55, 55, 57, 58, 6, 8, 21, 34, 52, - 74, 75, 76, 77, 11, 24, 41, 42, 43, 48, + 108, 116, 127, 128, 155, 171, 188, 189, 208, 212, + 216, 233, 240, 247, 257, 258, 261, 273, 284, 292, + 297, 302, 307, 312, 320, 328, 333, 338, 345, 346, + 350, 351, 352, 359, 360, 364, 365, 369, 370, 371, + 375, 376, 380, 381, 391, 404, 405, 408, 417, 428, + 429, 430, 433, 434, 435, 439, 440, 441, 442, 446, + 447, 451, 453, 469, 471, 476, 479, 487, 491, 495, + 499, 503, 507, 514, 519, 526, 527, 531, 535, 539, + 543, 550, 557, 558, 563, 564, 568, 569, 574, 576, + 578, 583, 603, 604, 606, 611, 612, 616, 617, 620, + 621, 646, 647, 652, 657, 661, 662, 666, 667, 668, + 669, 670, 674, 687, 694, 701, 708, 709, 713, 714, + 718, 719, 723, 724, 728, 729, 733, 734, 738, 749, + 750, 751, 752, 756, 757, 762, 763, 764, 773, 779, + 797, 798, 802, 803, 809, 815, 823, 831, 840, 849, + 853, 879, 883, 896, 910, 925, 937, 953, 959, 964, + 970, 977, 978, 986, 990, 994, 1000, 1007, 1012, 1013, + 1014, 1015, 1019, 1020, 1032, 1033, 1038, 1045, 1052, 1059, + 1091, 1102, 1115, 1120, 1121, 1124, 1125, 1128, 1129, 1134, + 1135, 1140, 1144, 1150, 1171, 1179, 1192, 1195, 1199, 1199, + 1201, 1206, 1213, 1218, 1224, 1229, 1235, 1241, 1250, 1252, + 1255, 1259, 1260, 1261, 1262, 1263, 1264, 1269, 1289, 1290, + 1291, 1292, 1303, 1317, 1318, 1324, 1329, 1334, 1339, 1344, + 1349, 1354, 1359, 1365, 1371, 1377, 1384, 1406, 1415, 1419, + 1427, 1431, 1439, 1451, 1472, 1476, 1482, 1486, 1499, 1507, + 1517, 1519, 1521, 1523, 1525, 1527, 1532, 1533, 1540, 1549, + 1557, 1566, 1577, 1585, 1586, 1587, 1591, 1591, 1594, 1594, + 1597, 1597, 1600, 1600, 1603, 1603, 1606, 1606, 1609, 1609, + 1612, 1612, 1615, 1617, 1619, 1621, 1623, 1625, 1627, 1629, + 1631, 1636, 1641, 1647, 1654, 1659, 1665, 1671, 1702, 1704, + 1706, 1714, 1729, 1731, 1733, 1735, 1737, 1739, 1741, 1743, + 1745, 1747, 1749, 1751, 1753, 1755, 1758, 1760, 1762, 1765, + 1767, 1769, 1771, 1774, 1779, 1784, 1791, 1796, 1803, 1808, + 1816, 1821, 1830, 1838, 1846, 1854, 1872, 1880, 1888, 1896, + 1904, 1912, 1916, 1920, 1924, 1932, 1940, 1956, 1964, 1972, + 1980, 1988, 1996, 2004, 2008, 2012, 2016, 2020, 2028, 2036, + 2044, 2052, 2072, 2094, 2105, 2112, 2126, 2142, 2144, 2146, + 2148, 2150, 2152, 2154, 2156, 2158, 2160, 2162, 2164, 2166, + 2168, 2170, 2172, 2174, 2176, 2178, 2180, 2184, 2188, 2192, + 2206, 2207, 2208, 2215, 2227, 2242, 2254, 2256, 2268, 2279, + 2303, 2314, 2323, 2327, 2334, 2342, 2350, 2361, 2369, 2397, + 2432, 2443, 2444, 2451, 2457, 2461, 2465, 2469, 2473, 2477, + 2481, 2485, 2489, 2493, 2497, 2501, 2505, 2509, 2513, 2517, + 2519, 2521, 2525, 2534, 2539, 2546, 2561, 2568, 2572, 2576, + 2580, 2584, 2598, 2599, 2603, 2604, 2612, 2613, 2617, 2618, + 2623, 2631, 2633, 2647, 2650, 2677, 2678, 2681, 2682, 2693, + 2699, 2706, 2715, 2732, 2777, 2785, 2793, 2801, 2809, 2830, + 2831, 2834, 2835, 2839, 2849, 2850, 2852, 2853, 2854, 2857, + 2858, 2861, 2862, 2863, 2864, 2865, 2866, 2867, 2868, 2869, + 2870, 2871, 2872, 2875, 2877, 2882, 2884, 2889, 2891, 2893, + 2895, 2897, 2899, 2901, 2903, 2917, 2919, 2923, 2927, 2934, + 2939, 2946, 2950, 2956, 2960, 2969, 2980, 2981, 2985, 2989, + 2996, 2997, 2998, 2999, 3000, 3001, 3002, 3003, 3004, 3005, + 3015, 3019, 3026, 3033, 3034, 3050, 3054, 3059, 3063, 3078, + 3083, 3087, 3090, 3093, 3094, 3095, 3098, 3105, 3115, 3129, + 3130, 3134, 3145, 3146, 3149, 3150, 3153, 3157, 3164, 3168, + 3176, 3187, 3188, 3192, 3193, 3197, 3198, 3201, 3202, 3212, + 3213, 3217, 3218, 3221, 3237, 3245, 3253, 3268, 3286, 3287, + 3290, 3291, 3294, 3298, 3299, 3302, 3303, 3304, 3314, 3315, + 3326, 3330, 3357, 3359, 3364, 3366, 3376, 3379, 3390, 3394, + 3398, 3410, 3414, 3423, 3430, 3468, 3472, 3476, 3480, 3484, + 3488, 3492, 3498, 3499, 3515, 3516, 3517, 3520, 3521, 3527, + 3528, 3529, 3532, 3533, 3534, 3537, 3538, 3539, 3542, 3543, + 3546, 3548, 3553, 3554, 3557, 3565, 3566, 3567, 3568, 3571, + 3572, 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, 65, 66, 67, 72, 73, 78, 82, + 90, 91, 96, 97, 98, 104, 109, 117, 118, 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, 21, 25, 32, 43, 44, 50, + 51, 9, 19, 2, 7, 14, 24, 25, 32, 3, + 10, 17, 24, 31, 38, 45, 55, 55, 57, 58, + 6, 8, 21, 34, 52, 74, 75, 76, 77, 11, + 24, 41, 42, 43, 48, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, @@ -217592,33 +232994,33 @@ static const yytype_uint16 yyrline[] = 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, - 61, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, + 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 63, 64, + 63, 63, 63, 63, 63, 63, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, + 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 66, 66, 66, 66, + 65, 65, 65, 65, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 67, 67, 67, 67, 67, 67, 67, + 66, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67 + 67, 67, 67, 67, 67, 67, 67, 67, 67 }; #endif @@ -217657,122 +233059,123 @@ static const char *const yytname[] = "FROM", "FULL", "FUNCTION", "FUNCTIONS", "GENERATED", "GLOB", "GLOBAL", "GRANT", "GRANTED", "GROUP_P", "GROUPING", "GROUPING_ID", "HANDLER", "HAVING", "HEADER_P", "HOLD", "HOUR_P", "HOURS_P", "IDENTITY_P", "IF_P", - "ILIKE", "IMMEDIATE", "IMMUTABLE", "IMPLICIT_P", "IMPORT_P", "IN_P", - "INCLUDING", "INCREMENT", "INDEX", "INDEXES", "INHERIT", "INHERITS", - "INITIALLY", "INLINE_P", "INNER_P", "INOUT", "INPUT_P", "INSENSITIVE", - "INSERT", "INSTEAD", "INT_P", "INTEGER", "INTERSECT", "INTERVAL", "INTO", - "INVOKER", "IS", "ISNULL", "ISOLATION", "JOIN", "KEY", "LABEL", - "LANGUAGE", "LARGE_P", "LAST_P", "LATERAL_P", "LEADING", "LEAKPROOF", - "LEFT", "LEVEL", "LIKE", "LIMIT", "LISTEN", "LOAD", "LOCAL", "LOCALTIME", - "LOCALTIMESTAMP", "LOCATION", "LOCK_P", "LOCKED", "LOGGED", "MACRO", - "MAP", "MAPPING", "MATCH", "MATERIALIZED", "MAXVALUE", "METHOD", - "MICROSECOND_P", "MICROSECONDS_P", "MILLISECOND_P", "MILLISECONDS_P", - "MINUTE_P", "MINUTES_P", "MINVALUE", "MODE", "MONTH_P", "MONTHS_P", - "MOVE", "NAME_P", "NAMES", "NATIONAL", "NATURAL", "NCHAR", "NEW", "NEXT", - "NO", "NONE", "NOT", "NOTHING", "NOTIFY", "NOTNULL", "NOWAIT", "NULL_P", - "NULLIF", "NULLS_P", "NUMERIC", "OBJECT_P", "OF", "OFF", "OFFSET", - "OIDS", "OLD", "ON", "ONLY", "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", "PUBLICATION", "QUOTE", "RANGE", "READ_P", - "REAL", "REASSIGN", "RECHECK", "RECURSIVE", "REF", "REFERENCES", - "REFERENCING", "REFRESH", "REINDEX", "RELATIVE_P", "RELEASE", "RENAME", - "REPEATABLE", "REPLACE", "REPLICA", "RESET", "RESTART", "RESTRICT", - "RETURNING", "RETURNS", "REVOKE", "RIGHT", "ROLE", "ROLLBACK", "ROLLUP", - "ROW", "ROWS", "RULE", "SAMPLE", "SAVEPOINT", "SCHEMA", "SCHEMAS", - "SCROLL", "SEARCH", "SECOND_P", "SECONDS_P", "SECURITY", "SELECT", - "SEQUENCE", "SEQUENCES", "SERIALIZABLE", "SERVER", "SESSION", - "SESSION_USER", "SET", "SETOF", "SETS", "SHARE", "SHOW", "SIMILAR", - "SIMPLE", "SKIP", "SMALLINT", "SNAPSHOT", "SOME", "SQL_P", "STABLE", - "STANDALONE_P", "START", "STATEMENT", "STATISTICS", "STDIN", "STDOUT", - "STORAGE", "STRICT_P", "STRIP_P", "STRUCT", "SUBSCRIPTION", "SUBSTRING", - "SUMMARIZE", "SYMMETRIC", "SYSID", "SYSTEM_P", "TABLE", "TABLES", - "TABLESAMPLE", "TABLESPACE", "TEMP", "TEMPLATE", "TEMPORARY", "TEXT_P", - "THEN", "TIME", "TIMESTAMP", "TO", "TRAILING", "TRANSACTION", - "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", "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", "CreateEnumStmt", "opt_enum_val_list", "enum_val_list", - "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", "index_params", "set_target", "PragmaStmt", - "CreateSeqStmt", "OptSeqOptList", "ExecuteStmt", "execute_param_clause", - "AlterSeqStmt", "SeqOptList", "opt_with", "NumericOnly", "SeqOptElem", - "opt_by", "SignedIconst", "TransactionStmt", "opt_transaction", - "CreateStmt", "ConstraintAttributeSpec", "def_arg", - "OptParenthesizedSeqOptList", "generic_option_arg", "key_action", - "ColConstraint", "ColConstraintElem", "generic_option_elem", - "key_update", "key_actions", "create_generic_options", "OnCommitOption", - "reloptions", "opt_no_inherit", "TableConstraint", "TableLikeOption", - "reloption_list", "ExistingIndex", "ConstraintAttr", "OptWith", - "definition", "TableLikeOptionList", "generic_option_name", - "ConstraintAttributeElem", "columnDef", "generic_option_list", - "def_list", "index_name", "TableElement", "def_elem", "opt_definition", - "OptTableElementList", "columnElem", "opt_column_list", "ColQualList", - "key_delete", "reloption_elem", "columnList", "func_type", - "ConstraintElem", "TableElementList", "key_match", "TableLikeClause", - "OptTemp", "generated_when", "DropStmt", "drop_type_any_name", - "drop_type_name", "any_name_list", "opt_drop_behavior", - "drop_type_name_on_any_name", "type_name_list", "CreateFunctionStmt", - "macro_alias", "param_list", "UpdateStmt", "CopyStmt", "copy_from", - "copy_delimiter", "copy_generic_opt_arg_list", "opt_using", "opt_as", - "opt_program", "copy_options", "copy_generic_opt_arg", - "copy_generic_opt_elem", "opt_oids", "copy_opt_list", "opt_binary", - "copy_opt_item", "copy_generic_opt_arg_list_item", "copy_file_name", + "IGNORE_P", "ILIKE", "IMMEDIATE", "IMMUTABLE", "IMPLICIT_P", "IMPORT_P", + "IN_P", "INCLUDING", "INCREMENT", "INDEX", "INDEXES", "INHERIT", + "INHERITS", "INITIALLY", "INLINE_P", "INNER_P", "INOUT", "INPUT_P", + "INSENSITIVE", "INSERT", "INSTALL", "INSTEAD", "INT_P", "INTEGER", + "INTERSECT", "INTERVAL", "INTO", "INVOKER", "IS", "ISNULL", "ISOLATION", + "JOIN", "KEY", "LABEL", "LANGUAGE", "LARGE_P", "LAST_P", "LATERAL_P", + "LEADING", "LEAKPROOF", "LEFT", "LEVEL", "LIKE", "LIMIT", "LISTEN", + "LOAD", "LOCAL", "LOCALTIME", "LOCALTIMESTAMP", "LOCATION", "LOCK_P", + "LOCKED", "LOGGED", "MACRO", "MAP", "MAPPING", "MATCH", "MATERIALIZED", + "MAXVALUE", "METHOD", "MICROSECOND_P", "MICROSECONDS_P", "MILLISECOND_P", + "MILLISECONDS_P", "MINUTE_P", "MINUTES_P", "MINVALUE", "MODE", "MONTH_P", + "MONTHS_P", "MOVE", "NAME_P", "NAMES", "NATIONAL", "NATURAL", "NCHAR", + "NEW", "NEXT", "NO", "NONE", "NOT", "NOTHING", "NOTIFY", "NOTNULL", + "NOWAIT", "NULL_P", "NULLIF", "NULLS_P", "NUMERIC", "OBJECT_P", "OF", + "OFF", "OFFSET", "OIDS", "OLD", "ON", "ONLY", "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", "PUBLICATION", + "QUALIFY", "QUOTE", "RANGE", "READ_P", "REAL", "REASSIGN", "RECHECK", + "RECURSIVE", "REF", "REFERENCES", "REFERENCING", "REFRESH", "REINDEX", + "RELATIVE_P", "RELEASE", "RENAME", "REPEATABLE", "REPLACE", "REPLICA", + "RESET", "RESPECT_P", "RESTART", "RESTRICT", "RETURNING", "RETURNS", + "REVOKE", "RIGHT", "ROLE", "ROLLBACK", "ROLLUP", "ROW", "ROWS", "RULE", + "SAMPLE", "SAVEPOINT", "SCHEMA", "SCHEMAS", "SCROLL", "SEARCH", + "SECOND_P", "SECONDS_P", "SECURITY", "SELECT", "SEQUENCE", "SEQUENCES", + "SERIALIZABLE", "SERVER", "SESSION", "SESSION_USER", "SET", "SETOF", + "SETS", "SHARE", "SHOW", "SIMILAR", "SIMPLE", "SKIP", "SMALLINT", + "SNAPSHOT", "SOME", "SQL_P", "STABLE", "STANDALONE_P", "START", + "STATEMENT", "STATISTICS", "STDIN", "STDOUT", "STORAGE", "STRICT_P", + "STRIP_P", "STRUCT", "SUBSCRIPTION", "SUBSTRING", "SUMMARIZE", + "SYMMETRIC", "SYSID", "SYSTEM_P", "TABLE", "TABLES", "TABLESAMPLE", + "TABLESPACE", "TEMP", "TEMPLATE", "TEMPORARY", "TEXT_P", "THEN", "TIME", + "TIMESTAMP", "TO", "TRAILING", "TRANSACTION", "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", "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", "CreateEnumStmt", "opt_enum_val_list", + "enum_val_list", "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", "index_params", + "set_target", "PragmaStmt", "CreateSeqStmt", "OptSeqOptList", + "ExecuteStmt", "execute_param_clause", "AlterSeqStmt", "SeqOptList", + "opt_with", "NumericOnly", "SeqOptElem", "opt_by", "SignedIconst", + "TransactionStmt", "opt_transaction", "CreateStmt", + "ConstraintAttributeSpec", "def_arg", "OptParenthesizedSeqOptList", + "generic_option_arg", "key_action", "ColConstraint", "ColConstraintElem", + "generic_option_elem", "key_update", "key_actions", + "create_generic_options", "OnCommitOption", "reloptions", + "opt_no_inherit", "TableConstraint", "TableLikeOption", "reloption_list", + "ExistingIndex", "ConstraintAttr", "OptWith", "definition", + "TableLikeOptionList", "generic_option_name", "ConstraintAttributeElem", + "columnDef", "generic_option_list", "def_list", "index_name", + "TableElement", "def_elem", "opt_definition", "OptTableElementList", + "columnElem", "opt_column_list", "ColQualList", "key_delete", + "reloption_elem", "columnList", "func_type", "ConstraintElem", + "TableElementList", "key_match", "TableLikeClause", "OptTemp", + "generated_when", "DropStmt", "drop_type_any_name", "drop_type_name", + "any_name_list", "opt_drop_behavior", "drop_type_name_on_any_name", + "type_name_list", "CreateFunctionStmt", "macro_alias", "param_list", + "UpdateStmt", "CopyStmt", "copy_from", "copy_delimiter", + "copy_generic_opt_arg_list", "opt_using", "opt_as", "opt_program", + "copy_options", "copy_generic_opt_arg", "copy_generic_opt_elem", + "opt_oids", "copy_opt_list", "opt_binary", "copy_opt_item", + "copy_generic_opt_arg_list_item", "copy_file_name", "copy_generic_opt_list", "SelectStmt", "select_with_parens", "select_no_parens", "select_clause", "simple_select", "with_clause", "cte_list", "common_table_expr", "into_clause", "OptTempTableName", "opt_table", "all_or_distinct", "distinct_clause", "opt_all_clause", - "opt_sort_clause", "sort_clause", "sortby_list", "sortby", - "opt_asc_desc", "opt_nulls_order", "select_limit", "opt_select_limit", - "limit_clause", "offset_clause", "sample_count", "sample_clause", - "opt_sample_func", "tablesample_entry", "tablesample_clause", - "opt_tablesample_clause", "opt_repeatable_clause", "select_limit_value", - "select_offset_value", "select_fetch_first_value", "I_or_F_const", - "row_or_rows", "first_or_next", "group_clause", "group_by_list", - "group_by_item", "empty_grouping_set", "rollup_clause", "cube_clause", - "grouping_sets_clause", "grouping_or_grouping_id", "having_clause", - "for_locking_clause", "opt_for_locking_clause", "for_locking_items", - "for_locking_item", "for_locking_strength", "locked_rels_list", - "opt_nowait_or_skip", "values_clause", "from_clause", "from_list", - "table_ref", "joined_table", "alias_clause", "opt_alias_clause", - "func_alias_clause", "join_type", "join_outer", "join_qual", - "relation_expr", "func_table", "rowsfrom_item", "rowsfrom_list", - "opt_col_def_list", "opt_ordinality", "where_clause", - "TableFuncElementList", "TableFuncElement", "opt_collate_clause", - "colid_type_list", "RowOrStruct", "Typename", "opt_array_bounds", - "SimpleTypename", "ConstTypename", "GenericType", "opt_type_modifiers", - "Numeric", "opt_float", "Bit", "ConstBit", "BitWithLength", - "BitWithoutLength", "Character", "ConstCharacter", "CharacterWithLength", - "CharacterWithoutLength", "character", "opt_varying", "ConstDatetime", - "ConstInterval", "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", - "func_expr_windowless", "func_expr_common_subexpr", - "within_group_clause", "filter_clause", "window_clause", - "window_definition_list", "window_definition", "over_clause", - "window_specification", "opt_existing_window_name", + "opt_ignore_nulls", "opt_sort_clause", "sort_clause", "sortby_list", + "sortby", "opt_asc_desc", "opt_nulls_order", "select_limit", + "opt_select_limit", "limit_clause", "offset_clause", "sample_count", + "sample_clause", "opt_sample_func", "tablesample_entry", + "tablesample_clause", "opt_tablesample_clause", "opt_repeatable_clause", + "select_limit_value", "select_offset_value", "select_fetch_first_value", + "I_or_F_const", "row_or_rows", "first_or_next", "group_clause", + "group_by_list", "group_by_item", "empty_grouping_set", "rollup_clause", + "cube_clause", "grouping_sets_clause", "grouping_or_grouping_id", + "having_clause", "qualify_clause", "for_locking_clause", + "opt_for_locking_clause", "for_locking_items", "for_locking_item", + "for_locking_strength", "locked_rels_list", "opt_nowait_or_skip", + "values_clause", "from_clause", "from_list", "table_ref", "joined_table", + "alias_clause", "opt_alias_clause", "func_alias_clause", "join_type", + "join_outer", "join_qual", "relation_expr", "func_table", + "rowsfrom_item", "rowsfrom_list", "opt_col_def_list", "opt_ordinality", + "where_clause", "TableFuncElementList", "TableFuncElement", + "opt_collate_clause", "colid_type_list", "RowOrStruct", "Typename", + "opt_array_bounds", "SimpleTypename", "ConstTypename", "GenericType", + "opt_type_modifiers", "Numeric", "opt_float", "Bit", "ConstBit", + "BitWithLength", "BitWithoutLength", "Character", "ConstCharacter", + "CharacterWithLength", "CharacterWithoutLength", "character", + "opt_varying", "ConstDatetime", "ConstInterval", "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", "func_expr_windowless", + "func_expr_common_subexpr", "within_group_clause", "filter_clause", + "window_clause", "window_definition_list", "window_definition", + "over_clause", "window_specification", "opt_existing_window_name", "opt_partition_clause", "opt_frame_clause", "frame_extent", "frame_bound", "qualified_row", "row", "dict_arg", "dict_arguments", "sub_type", "all_Op", "MathOp", "qual_Op", "qual_all_Op", "subquery_Op", @@ -217863,194 +233266,197 @@ static const yytype_uint16 yytoknum[] = 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 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, 60, 62, 61, 731, - 43, 45, 42, 47, 37, 94, 732, 91, 93, 40, - 41, 46, 59, 44, 123, 125, 35, 63, 58 + 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, + 60, 62, 61, 735, 43, 45, 42, 47, 37, 94, + 736, 91, 93, 40, 41, 46, 59, 44, 123, 125, + 35, 63, 58 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint16 yyr1[] = { - 0, 499, 500, 501, 501, 502, 502, 502, 502, 502, - 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, - 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, - 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, - 503, 503, 503, 503, 503, 503, 503, 503, 504, 504, - 505, 505, 506, 506, 506, 506, 507, 507, 508, 508, - 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, - 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, - 508, 508, 508, 508, 508, 508, 508, 509, 509, 510, - 510, 510, 510, 511, 511, 512, 513, 513, 513, 514, - 514, 514, 514, 515, 516, 516, 517, 517, 518, 518, - 518, 518, 518, 518, 518, 518, 518, 518, 518, 518, - 518, 519, 519, 520, 521, 521, 521, 521, 521, 522, - 522, 523, 523, 523, 524, 524, 525, 526, 526, 527, - 527, 527, 528, 528, 528, 529, 529, 530, 530, 531, - 531, 532, 532, 533, 533, 534, 534, 535, 535, 536, - 536, 537, 538, 538, 538, 539, 539, 540, 540, 541, - 541, 541, 542, 542, 543, 543, 544, 544, 545, 545, - 545, 546, 546, 546, 546, 547, 547, 547, 547, 547, - 547, 547, 547, 547, 547, 547, 547, 547, 547, 548, - 548, 549, 549, 549, 550, 550, 550, 550, 550, 550, - 551, 551, 551, 552, 552, 552, 553, 553, 554, 554, - 554, 554, 554, 554, 555, 555, 556, 557, 557, 557, - 557, 557, 558, 558, 558, 558, 559, 559, 559, 559, - 559, 559, 559, 559, 559, 560, 561, 562, 562, 562, - 562, 562, 563, 563, 564, 564, 564, 564, 565, 566, - 566, 567, 567, 568, 568, 568, 568, 568, 568, 568, - 568, 569, 569, 570, 571, 571, 571, 571, 572, 572, - 572, 572, 573, 574, 574, 574, 575, 576, 576, 576, - 576, 576, 576, 577, 578, 578, 579, 579, 580, 581, - 581, 581, 582, 582, 583, 583, 584, 584, 585, 586, - 586, 587, 587, 588, 589, 589, 589, 589, 590, 590, - 591, 591, 591, 592, 592, 592, 592, 592, 592, 593, - 593, 594, 594, 594, 594, 595, 596, 596, 596, 596, - 596, 596, 596, 596, 597, 597, 598, 598, 598, 598, - 598, 598, 598, 598, 599, 599, 599, 599, 599, 599, - 599, 599, 599, 599, 599, 599, 599, 599, 599, 600, - 600, 600, 600, 600, 600, 600, 601, 601, 602, 602, - 602, 603, 603, 603, 604, 604, 605, 606, 606, 607, - 607, 608, 609, 609, 610, 610, 611, 611, 612, 612, - 613, 613, 614, 614, 615, 615, 616, 616, 617, 617, - 617, 617, 617, 618, 619, 619, 620, 620, 621, 621, - 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, - 622, 622, 622, 622, 623, 624, 624, 624, 625, 625, - 626, 626, 627, 627, 628, 628, 628, 628, 628, 628, - 628, 628, 629, 629, 630, 630, 630, 630, 630, 630, - 630, 631, 631, 631, 632, 632, 633, 634, 634, 635, - 635, 635, 635, 635, 635, 635, 635, 635, 636, 636, - 637, 637, 637, 638, 638, 639, 639, 640, 640, 641, - 642, 642, 643, 643, 644, 644, 644, 645, 645, 645, - 646, 646, 646, 646, 647, 647, 648, 648, 648, 648, - 649, 649, 650, 650, 650, 650, 650, 650, 651, 651, - 652, 652, 653, 653, 653, 653, 654, 655, 655, 656, - 656, 657, 657, 658, 659, 659, 659, 660, 660, 661, - 661, 662, 662, 663, 663, 664, 664, 665, 665, 665, - 665, 665, 666, 667, 668, 669, 670, 670, 671, 671, - 672, 672, 673, 673, 674, 674, 675, 676, 676, 676, - 676, 677, 677, 678, 678, 678, 679, 679, 680, 680, - 681, 681, 682, 682, 682, 682, 682, 682, 682, 683, - 683, 683, 683, 683, 683, 684, 684, 684, 684, 685, - 685, 686, 686, 686, 686, 686, 687, 687, 687, 687, - 688, 688, 689, 689, 690, 690, 690, 690, 691, 691, - 692, 693, 693, 694, 694, 695, 695, 696, 696, 697, - 697, 698, 699, 699, 700, 700, 701, 701, 702, 702, - 702, 702, 702, 702, 702, 702, 703, 703, 703, 704, - 704, 704, 704, 704, 704, 704, 705, 705, 705, 705, - 706, 707, 707, 708, 708, 708, 708, 708, 708, 708, - 708, 708, 708, 708, 709, 709, 710, 710, 711, 711, - 712, 713, 714, 714, 715, 715, 716, 717, 718, 718, - 718, 718, 718, 718, 719, 719, 720, 720, 720, 720, - 721, 722, 722, 722, 723, 723, 724, 724, 725, 725, - 726, 726, 727, 727, 728, 728, 729, 729, 730, 730, - 731, 731, 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 731, 731, 732, 732, 732, 732, - 732, 732, 732, 732, 732, 732, 732, 732, 732, 732, - 732, 732, 732, 732, 732, 732, 732, 732, 732, 732, - 732, 732, 732, 732, 732, 732, 732, 732, 732, 732, - 732, 732, 732, 732, 732, 732, 732, 732, 732, 732, - 732, 732, 732, 732, 732, 732, 732, 732, 732, 732, - 732, 732, 732, 732, 732, 732, 732, 732, 732, 732, - 732, 732, 732, 732, 732, 733, 733, 733, 733, 733, - 733, 733, 733, 733, 733, 733, 733, 733, 733, 733, - 733, 733, 733, 733, 733, 733, 733, 733, 734, 734, - 734, 734, 734, 734, 734, 734, 734, 734, 734, 734, - 735, 735, 735, 735, 735, 735, 735, 736, 736, 737, - 737, 738, 738, 738, 738, 738, 738, 738, 738, 738, + 0, 503, 504, 505, 505, 506, 506, 506, 506, 506, + 506, 506, 506, 506, 506, 506, 506, 506, 506, 506, + 506, 506, 506, 506, 506, 506, 506, 506, 506, 506, + 506, 506, 506, 506, 506, 506, 506, 506, 506, 506, + 507, 507, 507, 507, 507, 507, 507, 507, 508, 508, + 509, 509, 510, 510, 510, 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, 513, 513, 514, + 514, 514, 514, 515, 515, 516, 517, 517, 517, 518, + 518, 518, 518, 519, 520, 520, 521, 521, 522, 522, + 522, 522, 522, 522, 522, 522, 522, 522, 522, 522, + 522, 523, 523, 524, 525, 525, 525, 525, 525, 526, + 526, 527, 527, 527, 528, 528, 529, 530, 530, 531, + 531, 531, 532, 532, 532, 533, 533, 534, 534, 535, + 535, 536, 536, 537, 537, 538, 538, 539, 539, 540, + 540, 541, 542, 542, 542, 543, 543, 544, 544, 545, + 545, 545, 546, 546, 547, 547, 548, 548, 549, 549, + 549, 550, 550, 550, 550, 551, 551, 551, 551, 551, + 551, 551, 551, 551, 551, 551, 551, 551, 551, 552, + 552, 553, 553, 553, 554, 554, 554, 554, 554, 554, + 555, 555, 555, 556, 556, 556, 557, 557, 558, 558, + 558, 558, 558, 558, 559, 559, 560, 561, 561, 561, + 561, 561, 562, 562, 562, 562, 563, 563, 563, 563, + 563, 563, 563, 563, 563, 564, 565, 566, 566, 566, + 566, 566, 567, 567, 568, 568, 568, 568, 569, 570, + 570, 571, 571, 572, 572, 572, 572, 572, 572, 572, + 572, 573, 573, 574, 575, 575, 575, 575, 576, 576, + 576, 576, 577, 578, 578, 578, 579, 580, 580, 580, + 580, 580, 580, 581, 582, 582, 583, 583, 584, 585, + 585, 585, 586, 586, 587, 587, 588, 588, 589, 590, + 590, 591, 591, 592, 593, 593, 593, 593, 594, 594, + 595, 595, 595, 596, 596, 596, 596, 596, 596, 597, + 597, 598, 598, 598, 598, 599, 600, 600, 600, 600, + 600, 600, 600, 600, 601, 601, 602, 602, 602, 602, + 602, 602, 602, 602, 603, 603, 603, 603, 603, 603, + 603, 603, 603, 603, 603, 603, 603, 603, 603, 604, + 604, 604, 604, 604, 604, 604, 605, 605, 606, 606, + 606, 607, 607, 607, 608, 608, 609, 610, 610, 611, + 611, 612, 613, 613, 614, 614, 615, 615, 616, 616, + 617, 617, 618, 618, 619, 619, 620, 620, 621, 621, + 621, 621, 621, 622, 623, 623, 624, 624, 625, 625, + 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, + 626, 626, 626, 626, 627, 628, 628, 628, 629, 629, + 630, 630, 631, 631, 632, 632, 632, 632, 632, 632, + 632, 632, 633, 633, 634, 634, 634, 634, 634, 634, + 634, 635, 635, 635, 636, 636, 637, 638, 638, 639, + 639, 639, 639, 639, 639, 639, 639, 639, 640, 640, + 641, 641, 641, 642, 642, 643, 643, 644, 644, 644, + 645, 645, 646, 646, 646, 647, 647, 648, 648, 649, + 649, 649, 650, 650, 650, 651, 651, 651, 651, 652, + 652, 653, 653, 653, 653, 654, 654, 655, 655, 655, + 655, 655, 655, 656, 656, 657, 657, 658, 658, 658, + 658, 659, 660, 660, 661, 661, 662, 662, 662, 662, + 662, 663, 664, 664, 664, 665, 665, 666, 666, 667, + 667, 668, 668, 668, 668, 669, 669, 670, 670, 670, + 670, 670, 671, 672, 673, 674, 675, 675, 676, 676, + 677, 677, 678, 678, 679, 679, 680, 680, 681, 682, + 682, 682, 682, 683, 683, 684, 684, 684, 685, 685, + 686, 686, 687, 687, 688, 688, 688, 688, 688, 688, + 688, 689, 689, 689, 689, 689, 689, 690, 690, 690, + 690, 691, 691, 692, 692, 692, 692, 692, 693, 693, + 693, 693, 694, 694, 695, 695, 696, 696, 696, 696, + 697, 697, 698, 699, 699, 700, 700, 701, 701, 702, + 702, 703, 703, 704, 705, 705, 706, 706, 707, 707, + 708, 708, 708, 708, 708, 708, 708, 708, 709, 709, + 709, 710, 710, 710, 710, 710, 710, 710, 711, 711, + 711, 711, 712, 713, 713, 714, 714, 714, 714, 714, + 714, 714, 714, 714, 714, 714, 715, 715, 716, 716, + 717, 717, 718, 719, 720, 720, 721, 721, 722, 723, + 724, 724, 724, 724, 724, 724, 725, 725, 726, 726, + 726, 726, 727, 728, 728, 728, 729, 729, 730, 730, + 731, 731, 732, 732, 733, 733, 734, 734, 735, 735, + 736, 736, 737, 737, 737, 737, 737, 737, 737, 737, + 737, 737, 737, 737, 737, 737, 737, 737, 738, 738, + 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, - 739, 739, 740, 740, 741, 741, 742, 742, 743, 744, - 744, 744, 745, 746, 746, 747, 747, 748, 748, 748, - 749, 749, 750, 750, 750, 750, 750, 751, 751, 752, - 752, 753, 754, 754, 755, 755, 755, 756, 756, 757, - 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, - 757, 758, 758, 759, 759, 760, 760, 760, 760, 760, - 760, 760, 760, 761, 761, 762, 762, 763, 763, 764, - 764, 765, 765, 765, 766, 766, 767, 767, 768, 768, - 768, 768, 768, 768, 768, 768, 768, 768, 769, 769, - 770, 771, 771, 772, 772, 772, 772, 772, 772, 773, - 774, 775, 775, 775, 776, 776, 777, 778, 778, 779, - 780, 780, 781, 781, 782, 782, 783, 783, 783, 784, - 784, 785, 785, 786, 786, 787, 787, 788, 788, 789, - 789, 790, 790, 790, 790, 790, 791, 791, 792, 792, - 793, 794, 794, 795, 795, 795, 796, 796, 797, 797, - 798, 798, 799, 800, 801, 801, 802, 802, 802, 802, - 802, 802, 802, 802, 802, 802, 802, 802, 802, 802, - 803, 804, 805, 805, 805, 806, 806, 807, 807, 807, - 808, 808, 808, 809, 809, 809, 810, 810, 811, 811, - 812, 812, 813, 814, 814, 814, 814, 815, 815, 816, - 817, 817, 818, 818, 818, 818, 819, 819, 820, 820, - 821, 821, 821, 821, 822, 822, 823, 824, 824, 825, - 825, 826, 826, 827, 827, 828, 828, 829, 829, 829, - 829, 829, 829, 830, 830, 831, 832, 833, 833, 833, - 833, 834, 834, 835, 835, 835, 836, 836, 836, 836, - 836, 837, 837, 837, 838, 838, 839, 839, 840, 840, - 841, 841, 841, 841, 842, 843, 843, 844, 844, 844, - 844, 845, 845, 845, 845, 846, 846, 846, 846, 847, - 847, 848, 848, 848, 848, 848, 848, 848, 849, 849, - 850, 851, 852, 852, 852, 852, 852, 853, 853, 853, - 853, 853, 854, 854, 855, 855, 856, 856, 857, 858, - 858, 858, 859, 859, 860, 860, 861, 861, 862, 863, - 863, 864, 864, 864, 865, 865, 865, 865, 865, 865, - 865, 866, 866, 867, 867, 868, 869, 869, 869, 869, - 870, 870, 870, 870, 871, 871, 872, 872, 872, 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 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, - 874, 875, 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 876, 876, 876, 876, 876, 876, 876, - 876, 876, 876, 876, 876, 876, 876, 876, 876, 876, - 876, 876, 876, 876, 876, 876, 876, 876, 876, 877, - 877, 877, 877, 877, 877, 877, 877, 877, 877, 877, - 877, 877, 877, 877, 877, 877, 877, 877, 877, 877, - 877, 877, 877, 877, 878, 878, 878, 878, 878, 878, - 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, - 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, - 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, - 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, - 878, 878, 878, 878, 878, 878, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 880, 880, 880, 880, 880, 880, 880, + 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, + 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, + 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, + 738, 738, 738, 738, 738, 738, 738, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 739, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 739, 739, 739, 739, + 740, 740, 740, 740, 740, 740, 740, 740, 740, 740, + 740, 740, 741, 741, 741, 741, 741, 741, 741, 742, + 742, 743, 743, 744, 744, 744, 744, 744, 744, 744, + 744, 744, 744, 744, 744, 744, 744, 744, 744, 744, + 744, 744, 744, 744, 744, 744, 744, 744, 744, 744, + 744, 744, 745, 745, 746, 746, 747, 747, 748, 748, + 749, 750, 750, 750, 751, 752, 752, 753, 753, 754, + 754, 754, 755, 755, 756, 756, 756, 756, 756, 757, + 757, 758, 758, 759, 760, 760, 761, 761, 761, 762, + 762, 763, 763, 763, 763, 763, 763, 763, 763, 763, + 763, 763, 763, 764, 764, 765, 765, 766, 766, 766, + 766, 766, 766, 766, 766, 767, 767, 768, 768, 769, + 769, 770, 770, 771, 771, 771, 772, 772, 773, 773, + 774, 774, 774, 774, 774, 774, 774, 774, 774, 774, + 775, 775, 776, 777, 777, 778, 778, 778, 778, 778, + 778, 779, 780, 781, 781, 781, 782, 782, 783, 784, + 784, 785, 786, 786, 787, 787, 788, 788, 789, 789, + 789, 790, 790, 791, 791, 792, 792, 793, 793, 794, + 794, 795, 795, 796, 796, 796, 796, 796, 797, 797, + 798, 798, 799, 800, 800, 801, 801, 801, 802, 802, + 803, 803, 804, 804, 805, 806, 807, 807, 808, 808, + 808, 808, 808, 808, 808, 808, 808, 808, 808, 808, + 808, 808, 809, 810, 811, 811, 811, 812, 812, 813, + 813, 813, 814, 814, 814, 815, 815, 815, 816, 816, + 817, 817, 818, 818, 819, 820, 820, 820, 820, 821, + 821, 822, 823, 823, 824, 824, 824, 824, 825, 825, + 826, 826, 827, 827, 827, 827, 828, 828, 829, 830, + 830, 831, 831, 832, 832, 833, 833, 834, 834, 835, + 835, 835, 835, 835, 835, 836, 836, 837, 838, 839, + 839, 839, 839, 840, 840, 841, 841, 841, 842, 842, + 842, 842, 842, 843, 843, 843, 844, 844, 845, 845, + 846, 846, 847, 847, 847, 847, 848, 849, 849, 850, + 850, 850, 850, 851, 851, 851, 851, 852, 852, 852, + 852, 853, 853, 854, 854, 854, 854, 854, 854, 854, + 855, 855, 856, 856, 856, 857, 857, 858, 858, 858, + 858, 858, 859, 859, 859, 859, 859, 860, 860, 861, + 861, 862, 862, 863, 864, 864, 864, 865, 865, 866, + 866, 867, 867, 868, 869, 869, 870, 870, 870, 871, + 871, 871, 871, 871, 871, 871, 872, 872, 873, 873, + 874, 875, 875, 875, 875, 876, 876, 876, 876, 877, + 877, 878, 878, 878, 879, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, 880, 880 + 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, 880, 881, + 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, + 881, 882, 882, 882, 882, 882, 882, 882, 882, 882, + 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, + 882, 882, 882, 882, 882, 882, 882, 883, 883, 883, + 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, + 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, + 883, 883, 884, 884, 884, 884, 884, 884, 884, 884, + 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, + 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, + 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, + 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, + 884, 884, 884, 884, 885, 885, 885, 885, 885, 885, + 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, + 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, + 885, 886, 886, 886, 886, 886, 886, 886, 886, 886, + 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, + 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, + 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, + 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, + 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, + 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, + 886, 886, 886, 886, 886, 886, 886, 886, 886 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -218101,86 +233507,86 @@ static const yytype_uint8 yyr2[] = 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, 10, 10, 1, 2, 4, 4, + 5, 5, 1, 1, 11, 11, 1, 2, 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, 1, 5, 1, 0, 1, 0, 3, - 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, 1, 1, 2, 2, 1, 1, 1, - 1, 1, 1, 3, 0, 1, 3, 1, 1, 1, + 1, 1, 0, 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, 1, 1, 1, 1, 2, 4, 4, 5, 1, 1, 2, 0, - 1, 3, 1, 0, 1, 2, 3, 2, 4, 2, - 3, 2, 0, 1, 2, 0, 4, 5, 2, 0, - 1, 3, 3, 3, 3, 3, 3, 1, 4, 3, - 4, 5, 4, 5, 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, 1, - 3, 3, 2, 0, 2, 4, 1, 1, 2, 3, - 5, 6, 2, 3, 5, 5, 3, 4, 0, 1, - 1, 1, 1, 1, 2, 4, 1, 1, 1, 1, - 2, 3, 0, 1, 1, 1, 1, 1, 2, 2, - 2, 2, 2, 1, 3, 0, 1, 1, 1, 1, - 5, 2, 1, 1, 1, 1, 4, 1, 2, 2, - 1, 3, 3, 2, 1, 0, 5, 2, 5, 2, - 1, 3, 3, 0, 1, 1, 1, 1, 1, 1, + 2, 0, 1, 3, 1, 0, 1, 2, 3, 2, + 4, 2, 3, 2, 0, 1, 2, 0, 4, 5, + 2, 0, 1, 3, 3, 3, 3, 3, 3, 1, + 4, 3, 4, 5, 4, 5, 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, 1, 3, 3, 2, 0, 2, 4, 1, 1, + 2, 3, 5, 6, 2, 3, 5, 5, 3, 4, + 0, 1, 1, 1, 1, 1, 2, 4, 1, 1, + 1, 1, 2, 3, 0, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 1, 3, 0, 1, 1, + 1, 1, 5, 2, 1, 1, 1, 1, 4, 1, + 2, 2, 1, 3, 3, 2, 1, 0, 5, 2, + 5, 2, 1, 3, 3, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, - 3, 3, 3, 3, 3, 0, 1, 3, 3, 5, - 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 2, 2, 3, 3, 2, - 2, 3, 3, 5, 4, 6, 3, 5, 4, 6, - 4, 6, 5, 7, 3, 2, 4, 3, 2, 1, - 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, - 4, 5, 6, 6, 7, 6, 7, 6, 7, 3, - 4, 4, 6, 1, 4, 1, 3, 2, 2, 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, 2, 1, 2, 2, 4, - 3, 5, 6, 8, 6, 6, 4, 4, 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, - 5, 0, 5, 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, 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, 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, 3, 2, 1, 3, 5, 4, 2, 1, 0, - 3, 1, 3, 4, 2, 0, 1, 3, 1, 2, - 1, 3, 1, 1, 1, 2, 1, 1, 2, 1, - 1, 2, 6, 2, 5, 3, 3, 1, 1, 1, + 3, 3, 3, 3, 3, 3, 3, 0, 1, 3, + 3, 5, 2, 2, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, + 3, 2, 2, 3, 3, 5, 4, 6, 3, 5, + 4, 6, 4, 6, 5, 7, 3, 2, 4, 3, + 2, 1, 3, 3, 3, 3, 3, 3, 4, 3, + 4, 3, 4, 5, 6, 6, 7, 6, 7, 6, + 7, 3, 4, 4, 6, 1, 4, 1, 3, 2, + 2, 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, 2, 1, 2, + 2, 4, 3, 6, 7, 9, 7, 7, 4, 4, + 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, 5, 0, 5, 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, 1, 1, 1, 1, 1, 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, 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, 1, 4, 5, 5, 4, 6, 1, 1, 1, - 1, 1, 1, 0, 1, 3, 1, 0, 7, 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, 3, 2, 9, 11, 12, 14, - 3, 4, 4, 0, 7, 10, 2, 3, 0, 4, + 1, 1, 1, 1, 4, 1, 4, 1, 4, 1, + 2, 1, 2, 1, 2, 1, 3, 1, 3, 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, 3, 2, 1, 3, 5, 4, 2, + 1, 0, 3, 1, 3, 4, 2, 0, 1, 3, + 1, 2, 1, 3, 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, 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, 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, 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, 3, + 2, 9, 11, 12, 14, 3, 4, 4, 0, 7, + 10, 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, 1, 1, @@ -218234,7 +233640,9 @@ 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, 1, 1, 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 @@ -218242,7154 +233650,6859 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint16 yydefact[] = { - 135, 212, 0, 1139, 1138, 212, 0, 1114, 212, 419, - 343, 0, 1212, 0, 212, 0, 135, 0, 0, 0, - 0, 0, 0, 0, 212, 486, 0, 1211, 212, 0, - 0, 1183, 0, 0, 0, 0, 0, 2, 4, 7, - 18, 13, 30, 26, 0, 28, 16, 21, 6, 32, - 17, 20, 14, 33, 11, 31, 453, 440, 488, 452, - 134, 456, 29, 15, 25, 5, 10, 23, 24, 22, - 1122, 36, 27, 34, 19, 8, 35, 37, 0, 9, - 38, 12, 211, 210, 204, 0, 0, 0, 0, 0, - 205, 1052, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, - 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1583, 1246, - 1247, 1248, 1531, 1532, 1584, 1533, 1534, 1249, 1250, 1251, - 1252, 1253, 1254, 1255, 1256, 1535, 1536, 1257, 1258, 1259, - 1260, 1261, 1537, 1585, 1262, 1263, 1264, 1265, 1266, 1267, - 1586, 1268, 1269, 1270, 1271, 1272, 1273, 1274, 1275, 1276, - 1587, 1277, 1278, 1279, 1588, 1280, 1281, 1282, 1283, 1284, - 1285, 1286, 1538, 1539, 1287, 1288, 1289, 1290, 1291, 1292, - 1293, 1294, 1295, 1296, 1297, 1298, 1299, 1300, 1301, 1302, - 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, 1311, 1312, - 1313, 1314, 1540, 1315, 1316, 1317, 1318, 1541, 1319, 1320, - 1321, 1542, 1322, 1323, 1324, 1589, 1590, 1325, 1326, 1327, - 1591, 1328, 1329, 1543, 1544, 1330, 1331, 1332, 1333, 1334, - 1335, 1336, 1592, 1337, 1338, 1339, 1340, 1341, 1342, 1343, - 1344, 1345, 1346, 1347, 1593, 1545, 1348, 1349, 1350, 1351, - 1546, 1547, 1548, 1352, 1594, 1595, 1353, 1596, 1354, 1355, - 1356, 1357, 1358, 1359, 1597, 1360, 1598, 1361, 1362, 1363, - 1364, 1365, 1366, 1367, 1368, 1549, 1369, 1370, 1371, 1372, - 1373, 1374, 1375, 1376, 1377, 1378, 1379, 1380, 1381, 1382, - 1383, 1384, 1385, 1386, 1550, 1600, 1551, 1387, 1388, 1389, - 1552, 1390, 1391, 1601, 1392, 1553, 1393, 1554, 1394, 1395, - 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1555, 1602, 1403, - 1603, 1556, 1404, 1405, 1406, 1407, 1408, 1409, 1410, 1411, - 1412, 1413, 1414, 1415, 1557, 1416, 1417, 1558, 1418, 1419, - 1420, 1421, 1422, 1423, 1424, 1425, 1426, 1427, 1428, 1429, - 1559, 1430, 1431, 1432, 1433, 1434, 1435, 1436, 1437, 1438, - 1439, 1440, 1441, 1442, 1443, 1444, 1445, 1446, 1447, 1604, - 1448, 1449, 1450, 1560, 1451, 1452, 1453, 1454, 1455, 1456, - 1457, 1458, 1459, 1460, 1461, 1462, 1463, 1464, 1465, 1466, - 1467, 1561, 1468, 1469, 1470, 1605, 1471, 1472, 1562, 1473, - 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1481, 1482, 1483, - 1484, 1563, 1485, 1564, 1486, 1487, 1488, 1489, 1607, 1490, - 1491, 1492, 1493, 1494, 1565, 1566, 1495, 1496, 1567, 1497, - 1568, 1498, 1499, 1569, 1500, 1501, 1502, 1503, 1504, 1505, - 1506, 1507, 1508, 1509, 1510, 1511, 1512, 1513, 1514, 1570, - 1571, 1515, 1608, 1516, 1517, 1518, 1519, 1520, 1521, 1522, - 1523, 1524, 1525, 1526, 1572, 1573, 1574, 1575, 1576, 1577, - 1578, 1579, 1580, 1581, 1582, 1527, 1528, 1529, 1530, 1215, - 0, 0, 1034, 1053, 1054, 1062, 207, 418, 135, 0, - 387, 0, 0, 388, 0, 0, 337, 336, 0, 1105, - 342, 0, 0, 0, 1052, 101, 1549, 1418, 1563, 99, - 1032, 1053, 0, 362, 363, 0, 371, 0, 356, 360, - 357, 0, 381, 373, 382, 374, 355, 375, 364, 354, - 0, 383, 0, 358, 0, 0, 0, 208, 173, 343, - 135, 0, 1127, 1128, 1126, 1117, 1122, 1129, 1130, 0, - 1113, 0, 1051, 1171, 1170, 162, 1081, 1200, 1565, 1495, - 1213, 1201, 1198, 1199, 209, 485, 483, 0, 1008, 1328, - 1363, 1455, 1466, 1565, 1147, 1151, 0, 206, 1570, 1205, - 0, 1206, 1056, 0, 457, 614, 1055, 1028, 1182, 0, - 1187, 0, 1432, 461, 464, 1071, 462, 453, 0, 1, - 135, 0, 0, 0, 482, 482, 0, 482, 0, 445, - 453, 448, 452, 0, 1121, 1196, 1210, 1565, 1495, 1204, - 1207, 1336, 0, 0, 1336, 0, 1336, 0, 1336, 0, - 0, 1000, 0, 1001, 1035, 1083, 1084, 1082, 0, 1085, - 310, 341, 340, 339, 338, 343, 1336, 1089, 1066, 0, - 0, 0, 0, 0, 0, 1100, 102, 100, 369, 370, - 0, 361, 359, 0, 1063, 1609, 666, 1610, 695, 673, - 695, 695, 1611, 1612, 1613, 1614, 662, 662, 1302, 675, - 1615, 1616, 1617, 1336, 1618, 1619, 663, 664, 700, 1620, - 1621, 1622, 1623, 1624, 0, 0, 1625, 695, 1626, 662, - 1627, 1628, 667, 1629, 636, 0, 1630, 665, 637, 1631, - 703, 703, 1632, 690, 1633, 380, 0, 384, 648, 649, - 650, 651, 676, 677, 652, 682, 683, 687, 653, 735, - 662, 1064, 1065, 1336, 380, 376, 1336, 380, 1030, 1336, - 0, 0, 169, 0, 1119, 1131, 1634, 1635, 1636, 1637, - 1639, 1638, 1640, 1641, 1642, 1643, 1644, 1645, 1646, 1647, - 1648, 1651, 1649, 1650, 1652, 1653, 1654, 1655, 1656, 1657, - 1658, 1659, 1660, 1661, 1662, 1663, 1664, 1665, 1666, 1667, - 1668, 1669, 1670, 1671, 1672, 1673, 1674, 1675, 1676, 1677, - 1678, 1679, 1680, 1681, 1682, 1683, 1684, 1685, 1145, 0, - 1146, 1136, 1125, 1132, 1133, 135, 417, 1116, 0, 0, - 0, 0, 1202, 0, 0, 0, 1037, 1039, 1040, 931, - 1050, 1003, 0, 1532, 1533, 1534, 993, 0, 1535, 1536, - 1537, 1585, 865, 852, 861, 866, 853, 855, 862, 1538, - 1539, 803, 1540, 1541, 1048, 1542, 1543, 1544, 1546, 1547, - 1548, 857, 859, 1550, 1551, 0, 1049, 1553, 1554, 1399, - 1556, 1557, 1559, 1560, 863, 1562, 1564, 1565, 1566, 1567, - 1568, 1047, 1569, 864, 1571, 0, 0, 0, 1019, 948, - 0, 0, 0, 1003, 836, 0, 0, 656, 657, 678, - 679, 658, 684, 685, 659, 0, 1013, 736, 881, 1003, - 848, 909, 779, 0, 834, 828, 468, 1009, 0, 829, - 1036, 1003, 994, 468, 1007, 1150, 1148, 1154, 1149, 0, - 0, 0, 0, 0, 616, 615, 1029, 1181, 1179, 1180, - 1178, 1177, 1184, 0, 1186, 1122, 945, 0, 994, 463, - 0, 0, 0, 443, 442, 3, 0, 0, 1189, 0, - 480, 481, 0, 0, 0, 0, 0, 0, 0, 0, - 563, 502, 503, 505, 560, 564, 572, 0, 449, 0, - 1071, 1208, 0, 0, 0, 122, 122, 0, 0, 0, - 0, 0, 93, 42, 86, 0, 0, 0, 0, 187, - 200, 0, 0, 0, 0, 0, 197, 0, 0, 180, - 44, 174, 176, 0, 122, 0, 40, 0, 0, 0, - 46, 1052, 0, 1583, 1584, 1585, 1586, 1587, 866, 0, - 1589, 1590, 1591, 1592, 1593, 1594, 1595, 1596, 1597, 1598, - 1549, 1600, 1601, 1602, 1603, 1604, 1605, 1563, 1607, 1569, - 0, 1608, 0, 840, 951, 488, 949, 1072, 0, 1053, - 1059, 999, 0, 1073, 1713, 1714, 1715, 1716, 1717, 1718, - 1719, 1720, 1721, 1722, 1723, 1724, 1725, 1726, 1727, 1728, - 1729, 1730, 1731, 1732, 1733, 1734, 1735, 1736, 1737, 1738, + 135, 212, 0, 1151, 1150, 212, 0, 1126, 212, 419, + 343, 0, 1227, 0, 212, 0, 135, 0, 0, 0, + 0, 0, 0, 0, 0, 212, 486, 0, 1226, 212, + 0, 0, 1198, 0, 0, 0, 0, 0, 2, 4, + 7, 18, 13, 30, 26, 0, 28, 16, 21, 6, + 32, 17, 20, 14, 33, 11, 31, 453, 440, 491, + 452, 134, 456, 29, 15, 25, 5, 10, 23, 24, + 22, 1134, 36, 27, 34, 19, 8, 35, 37, 0, + 9, 38, 12, 211, 210, 204, 0, 0, 0, 0, + 0, 205, 1064, 1245, 1246, 1247, 1248, 1249, 1250, 1251, + 1252, 1253, 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1601, + 1261, 1262, 1263, 1549, 1550, 1602, 1551, 1552, 1264, 1265, + 1266, 1267, 1268, 1269, 1270, 1271, 1553, 1554, 1272, 1273, + 1274, 1275, 1276, 1555, 1603, 1277, 1278, 1279, 1280, 1281, + 1282, 1604, 1283, 1284, 1285, 1286, 1287, 1288, 1289, 1290, + 1291, 1605, 1292, 1293, 1294, 1606, 1295, 1296, 1297, 1298, + 1299, 1300, 1301, 1556, 1557, 1302, 1303, 1304, 1305, 1306, + 1307, 1308, 1309, 1310, 1311, 1312, 1313, 1314, 1315, 1316, + 1317, 1318, 1319, 1320, 1321, 1322, 1323, 1324, 1325, 1326, + 1327, 1328, 1329, 1558, 1330, 1331, 1332, 1333, 1559, 1334, + 1335, 1336, 1560, 1337, 1338, 1339, 1607, 1608, 1340, 1341, + 1342, 1609, 1343, 1344, 1561, 1562, 1345, 1346, 1347, 1348, + 1349, 1350, 1351, 1352, 1610, 1353, 1354, 1355, 1356, 1357, + 1358, 1359, 1360, 1361, 1362, 1363, 1611, 1563, 1364, 1365, + 1366, 1367, 1368, 1564, 1565, 1566, 1369, 1612, 1613, 1370, + 1614, 1371, 1372, 1373, 1374, 1375, 1376, 1615, 1377, 1616, + 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1567, 1386, + 1387, 1388, 1389, 1390, 1391, 1392, 1393, 1394, 1395, 1396, + 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1568, 1618, 1569, + 1404, 1405, 1406, 1570, 1407, 1408, 1619, 1409, 1571, 1410, + 1572, 1411, 1412, 1413, 1414, 1415, 1416, 1417, 1418, 1419, + 1573, 1620, 1420, 1621, 1574, 1421, 1422, 1423, 1424, 1425, + 1426, 1427, 1428, 1429, 1430, 1431, 1432, 1575, 1433, 1434, + 1576, 1435, 1436, 1437, 1438, 1439, 1440, 1441, 1442, 1443, + 1444, 1445, 1446, 1577, 1447, 1448, 1449, 1450, 1451, 1452, + 1453, 1454, 1455, 1456, 1457, 1458, 1459, 1460, 1461, 1462, + 1463, 1464, 1465, 1622, 1466, 1467, 1468, 1578, 1469, 1470, + 1471, 1472, 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1480, + 1481, 1482, 1483, 1484, 1485, 1579, 1486, 1487, 1488, 1623, + 1489, 1490, 1580, 1491, 1492, 1493, 1494, 1495, 1496, 1497, + 1498, 1499, 1500, 1501, 1502, 1581, 1503, 1582, 1504, 1505, + 1506, 1507, 1625, 1508, 1509, 1510, 1511, 1512, 1583, 1584, + 1513, 1514, 1585, 1515, 1586, 1516, 1517, 1587, 1518, 1519, + 1520, 1521, 1522, 1523, 1524, 1525, 1526, 1527, 1528, 1529, + 1530, 1531, 1532, 1588, 1589, 1533, 1626, 1534, 1535, 1536, + 1537, 1538, 1539, 1540, 1541, 1542, 1543, 1544, 1590, 1591, + 1592, 1593, 1594, 1595, 1596, 1597, 1598, 1599, 1600, 1545, + 1546, 1547, 1548, 1230, 0, 0, 1046, 1065, 1066, 1074, + 207, 418, 135, 0, 387, 0, 0, 388, 0, 0, + 337, 336, 0, 1117, 342, 0, 0, 0, 1064, 101, + 1567, 1435, 1581, 99, 1044, 1065, 0, 362, 363, 0, + 371, 0, 356, 360, 357, 0, 381, 373, 382, 374, + 355, 375, 364, 354, 0, 383, 0, 358, 0, 0, + 0, 208, 173, 343, 135, 0, 1139, 1140, 1138, 1129, + 1134, 1141, 1142, 0, 1125, 0, 0, 1063, 1185, 1186, + 1183, 1182, 162, 1093, 1215, 1583, 1513, 1228, 1216, 1213, + 1214, 209, 485, 483, 0, 1020, 1343, 1380, 1473, 1484, + 1583, 1159, 1163, 0, 206, 1588, 1220, 0, 1221, 1068, + 0, 457, 626, 1067, 1040, 1197, 0, 1202, 0, 1449, + 461, 464, 1083, 462, 453, 0, 1, 135, 0, 0, + 0, 482, 482, 0, 482, 0, 445, 453, 448, 452, + 0, 1133, 1211, 1225, 1583, 1513, 1219, 1222, 1351, 0, + 0, 1351, 0, 1351, 0, 1351, 0, 0, 1012, 0, + 1013, 1047, 1095, 1096, 1094, 0, 1097, 310, 341, 340, + 339, 338, 343, 1351, 1101, 1078, 0, 0, 0, 0, + 0, 0, 1112, 102, 100, 369, 370, 0, 361, 359, + 0, 1075, 1627, 678, 1628, 707, 685, 707, 707, 1629, + 1630, 1631, 1632, 674, 674, 1317, 687, 1633, 1634, 1635, + 1351, 1636, 1637, 675, 676, 712, 1638, 1639, 1640, 1641, + 1642, 0, 0, 1643, 707, 1644, 674, 1645, 1646, 679, + 1647, 648, 0, 1648, 677, 649, 1649, 715, 715, 1650, + 702, 1651, 380, 0, 384, 660, 661, 662, 663, 688, + 689, 664, 694, 695, 699, 665, 747, 674, 1076, 1077, + 1351, 380, 376, 1351, 380, 1042, 1351, 0, 0, 169, + 0, 1131, 1143, 1652, 1653, 1654, 1655, 1657, 1656, 1658, + 1659, 1660, 1661, 1662, 1663, 1664, 1665, 1666, 1669, 1667, + 1668, 1670, 1671, 1672, 1673, 1674, 1675, 1676, 1677, 1678, + 1679, 1680, 1681, 1682, 1683, 1684, 1685, 1686, 1687, 1688, + 1689, 1690, 1691, 1692, 1693, 1694, 1695, 1696, 1697, 1698, + 1699, 1700, 1701, 1702, 1703, 1157, 0, 1158, 1148, 1137, + 1144, 1145, 135, 417, 1184, 1128, 0, 0, 0, 0, + 1217, 0, 0, 0, 1049, 1051, 1052, 943, 1062, 1015, + 0, 1550, 1551, 1552, 1005, 0, 1553, 1554, 1555, 1603, + 877, 864, 873, 878, 865, 867, 874, 1556, 1557, 815, + 1558, 1559, 1060, 1560, 1561, 1562, 1564, 1565, 1566, 869, + 871, 1568, 1569, 0, 1061, 1571, 1572, 1416, 1574, 1575, + 1577, 1578, 875, 1580, 1582, 1583, 1584, 1585, 1586, 1059, + 1587, 876, 1589, 0, 0, 0, 1031, 960, 0, 0, + 0, 1015, 848, 0, 0, 668, 669, 690, 691, 670, + 696, 697, 671, 0, 1025, 748, 893, 1015, 860, 921, + 791, 0, 846, 840, 468, 1021, 0, 841, 1048, 1015, + 1006, 468, 1019, 1162, 1160, 1166, 1161, 0, 0, 0, + 0, 0, 628, 627, 1041, 1196, 1194, 1195, 1193, 1192, + 1199, 0, 1201, 1134, 957, 0, 1006, 463, 0, 0, + 0, 443, 442, 3, 0, 0, 1204, 0, 480, 481, + 0, 0, 0, 0, 0, 0, 0, 0, 575, 507, + 508, 510, 572, 576, 584, 0, 449, 0, 1083, 1223, + 0, 0, 0, 122, 122, 0, 0, 0, 0, 0, + 93, 42, 86, 0, 0, 0, 0, 187, 200, 0, + 0, 0, 0, 0, 197, 0, 0, 180, 44, 174, + 176, 0, 122, 0, 40, 0, 0, 0, 46, 1064, + 0, 1601, 1602, 1603, 1604, 1605, 878, 0, 1607, 1608, + 1609, 1610, 1611, 1612, 1613, 1614, 1615, 1616, 1567, 1618, + 1619, 1620, 1621, 1622, 1623, 1581, 1625, 1587, 0, 1626, + 0, 852, 963, 491, 961, 1084, 0, 1065, 1071, 1011, + 0, 1085, 1731, 1732, 1733, 1734, 1735, 1736, 1737, 1738, 1739, 1740, 1741, 1742, 1743, 1744, 1745, 1746, 1747, 1748, 1749, 1750, 1751, 1752, 1753, 1754, 1755, 1756, 1757, 1758, 1759, 1760, 1761, 1762, 1763, 1764, 1765, 1766, 1767, 1768, 1769, 1770, 1771, 1772, 1773, 1774, 1775, 1776, 1777, 1778, - 1779, 1780, 1781, 1782, 1783, 1784, 1673, 1785, 1786, 1787, - 1788, 1789, 996, 1033, 1075, 1074, 1076, 1002, 0, 0, - 415, 0, 0, 1086, 0, 1067, 0, 0, 1336, 168, - 1336, 310, 0, 310, 0, 0, 1099, 1102, 372, 368, - 366, 365, 367, 694, 681, 689, 688, 0, 671, 670, - 669, 0, 668, 0, 0, 695, 695, 693, 672, 648, - 0, 0, 0, 699, 0, 697, 378, 379, 0, 352, - 0, 642, 638, 0, 708, 709, 710, 711, 718, 719, - 716, 717, 712, 713, 706, 707, 714, 715, 704, 705, - 0, 720, 721, 722, 723, 724, 725, 726, 727, 654, - 660, 0, 0, 347, 0, 0, 349, 0, 0, 0, - 0, 135, 0, 181, 1141, 1142, 1140, 0, 0, 1124, - 184, 201, 1135, 1144, 1134, 1143, 1123, 1118, 0, 1115, - 406, 1160, 1159, 1168, 163, 0, 954, 0, 135, 1203, - 1214, 0, 832, 948, 992, 0, 0, 0, 0, 0, - 0, 838, 957, 0, 0, 759, 0, 0, 0, 972, - 0, 978, 0, 0, 0, 760, 740, 741, 0, 1018, - 1025, 947, 0, 836, 945, 0, 912, 0, 1055, 0, - 830, 831, 837, 0, 1043, 0, 735, 735, 1012, 931, - 0, 928, 929, 930, 0, 0, 0, 1006, 0, 939, - 941, 0, 0, 775, 937, 0, 778, 0, 0, 0, - 0, 925, 926, 927, 919, 920, 921, 922, 923, 924, - 935, 918, 756, 0, 0, 883, 835, 0, 0, 755, - 0, 0, 0, 579, 0, 1041, 1038, 0, 995, 579, - 1162, 1166, 1167, 1165, 0, 1161, 1153, 1152, 1157, 1155, - 1158, 1156, 0, 1175, 0, 1172, 576, 0, 465, 0, - 0, 1195, 0, 129, 0, 1190, 0, 460, 459, 489, - 490, 496, 458, 541, 542, 0, 0, 0, 0, 569, - 567, 532, 506, 531, 0, 0, 510, 0, 533, 736, - 562, 447, 500, 501, 504, 446, 0, 565, 0, 575, - 563, 505, 0, 1197, 1209, 0, 0, 0, 0, 0, - 1336, 0, 0, 77, 58, 262, 0, 121, 0, 0, - 0, 0, 0, 0, 0, 85, 82, 83, 84, 0, - 0, 0, 0, 185, 186, 199, 0, 190, 191, 188, - 192, 193, 0, 0, 178, 179, 0, 0, 0, 0, - 177, 0, 0, 0, 0, 0, 0, 0, 0, 488, - 488, 488, 846, 0, 0, 487, 0, 0, 997, 1000, - 405, 318, 0, 308, 0, 0, 0, 0, 0, 0, - 343, 1092, 1090, 1088, 1091, 1093, 1068, 0, 0, 0, - 0, 165, 167, 0, 307, 281, 0, 1104, 389, 0, - 0, 1336, 1101, 298, 0, 0, 0, 0, 380, 0, - 692, 691, 643, 639, 0, 0, 0, 0, 385, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 380, - 377, 380, 1031, 0, 380, 172, 1336, 310, 0, 1120, - 1137, 182, 202, 183, 203, 438, 0, 412, 420, 425, - 403, 0, 403, 0, 422, 426, 403, 421, 403, 416, - 0, 164, 0, 1080, 0, 1079, 0, 1004, 0, 0, - 991, 987, 0, 0, 0, 0, 0, 958, 959, 960, - 961, 962, 963, 964, 965, 966, 0, 0, 967, 0, - 0, 0, 917, 928, 929, 930, 925, 926, 927, 919, - 920, 921, 922, 923, 924, 943, 0, 0, 0, 0, - 0, 0, 0, 0, 805, 0, 0, 828, 908, 0, - 945, 977, 0, 0, 0, 0, 0, 0, 945, 983, - 0, 0, 0, 1017, 0, 1014, 781, 1003, 0, 0, - 780, 0, 0, 0, 1045, 1046, 737, 751, 752, 753, - 757, 1078, 1077, 1011, 0, 1005, 0, 0, 738, 761, - 766, 0, 984, 799, 0, 787, 0, 774, 0, 785, - 789, 762, 777, 0, 758, 0, 1006, 940, 942, 0, - 938, 0, 748, 749, 750, 742, 743, 744, 745, 746, - 747, 754, 916, 914, 915, 0, 0, 0, 891, 782, - 0, 0, 784, 783, 1328, 1363, 0, 479, 479, 479, - 467, 477, 1010, 0, 628, 488, 1019, 628, 0, 735, - 617, 1071, 1185, 1173, 1174, 946, 1070, 135, 0, 1193, - 0, 0, 0, 141, 124, 0, 1191, 0, 157, 579, - 0, 1003, 0, 494, 495, 0, 499, 1560, 1451, 0, - 0, 0, 0, 534, 570, 0, 561, 0, 1037, 535, - 1036, 536, 539, 540, 511, 571, 1026, 573, 0, 566, - 451, 450, 577, 0, 43, 0, 1336, 60, 0, 0, - 0, 0, 0, 0, 216, 253, 216, 98, 1336, 380, - 1336, 380, 1234, 1303, 1467, 0, 56, 89, 0, 286, - 115, 0, 271, 315, 79, 94, 108, 0, 0, 45, - 175, 189, 194, 111, 198, 195, 1109, 196, 122, 0, - 41, 0, 109, 0, 1107, 0, 0, 47, 113, 1111, - 0, 0, 0, 0, 950, 841, 952, 953, 999, 0, + 1779, 1780, 1781, 1782, 1783, 1784, 1785, 1786, 1787, 1788, + 1789, 1790, 1791, 1792, 1793, 1794, 1795, 1796, 1797, 1798, + 1799, 1800, 1801, 1802, 1803, 1691, 1804, 1805, 1806, 1807, + 1808, 1008, 1045, 1087, 1086, 1088, 1014, 0, 0, 415, + 0, 0, 1098, 0, 1079, 0, 0, 1351, 168, 1351, + 310, 0, 310, 0, 0, 1111, 1114, 372, 368, 366, + 365, 367, 706, 693, 701, 700, 0, 683, 682, 681, + 0, 680, 0, 0, 707, 707, 705, 684, 660, 0, + 0, 0, 711, 0, 709, 378, 379, 0, 352, 0, + 654, 650, 0, 720, 721, 722, 723, 730, 731, 728, + 729, 724, 725, 718, 719, 726, 727, 716, 717, 0, + 732, 733, 734, 735, 736, 737, 738, 739, 666, 672, + 0, 0, 347, 0, 0, 349, 0, 0, 0, 0, + 135, 0, 181, 1153, 1154, 1152, 0, 0, 1136, 184, + 201, 1147, 1156, 1146, 1155, 1135, 1130, 0, 1127, 406, + 1172, 1171, 1180, 163, 0, 966, 0, 135, 1218, 1229, + 0, 844, 960, 1004, 0, 0, 0, 0, 0, 0, + 850, 969, 0, 0, 771, 0, 0, 0, 984, 0, + 990, 0, 0, 0, 772, 752, 753, 0, 1030, 1037, + 959, 0, 848, 957, 0, 924, 0, 1067, 0, 842, + 843, 849, 0, 1055, 0, 747, 747, 1024, 943, 0, + 940, 941, 942, 0, 0, 0, 1018, 0, 951, 953, + 0, 0, 787, 949, 0, 790, 0, 0, 0, 0, + 937, 938, 939, 931, 932, 933, 934, 935, 936, 947, + 930, 768, 0, 0, 895, 847, 0, 0, 767, 0, + 0, 0, 591, 0, 1053, 1050, 0, 1007, 591, 1174, + 1178, 1179, 1177, 0, 1173, 1165, 1164, 1169, 1167, 1170, + 1168, 0, 1190, 0, 1187, 588, 0, 465, 0, 0, + 1210, 0, 129, 0, 1205, 0, 460, 459, 501, 501, + 492, 495, 501, 458, 549, 550, 0, 0, 0, 0, + 581, 579, 1049, 1062, 537, 511, 536, 0, 0, 515, + 0, 541, 748, 574, 447, 505, 506, 509, 446, 0, + 577, 0, 587, 575, 510, 0, 1212, 1224, 0, 0, + 0, 0, 0, 1351, 0, 0, 77, 58, 262, 0, + 121, 0, 0, 0, 0, 0, 0, 0, 85, 82, + 83, 84, 0, 0, 0, 0, 185, 186, 199, 0, + 190, 191, 188, 192, 193, 0, 0, 178, 179, 0, + 0, 0, 0, 177, 0, 0, 0, 0, 0, 0, + 0, 0, 491, 491, 491, 858, 0, 489, 490, 0, + 0, 1009, 1012, 405, 318, 0, 308, 0, 0, 0, + 0, 0, 0, 343, 1104, 1102, 1100, 1103, 1105, 1080, + 0, 0, 0, 0, 165, 167, 0, 307, 281, 0, + 1116, 389, 0, 0, 1351, 1113, 298, 0, 0, 0, + 0, 380, 0, 704, 703, 655, 651, 0, 0, 0, + 0, 385, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 380, 377, 380, 1043, 0, 380, 172, 1351, + 310, 0, 1132, 1149, 182, 202, 183, 203, 438, 0, + 412, 420, 425, 403, 0, 403, 0, 422, 426, 403, + 421, 403, 416, 0, 164, 0, 1092, 0, 1091, 0, + 1016, 0, 0, 1003, 999, 0, 0, 0, 0, 0, + 970, 971, 972, 973, 974, 975, 976, 977, 978, 0, + 0, 979, 0, 0, 0, 929, 940, 941, 942, 937, + 938, 939, 931, 932, 933, 934, 935, 936, 955, 0, + 0, 0, 0, 0, 0, 0, 0, 817, 0, 0, + 840, 920, 0, 957, 989, 0, 0, 0, 0, 0, + 0, 957, 995, 0, 0, 0, 1029, 0, 1026, 793, + 1015, 0, 0, 792, 0, 0, 0, 1057, 1058, 749, + 763, 764, 765, 769, 1090, 1089, 1023, 0, 1017, 0, + 0, 750, 773, 778, 0, 996, 811, 0, 799, 0, + 786, 0, 797, 801, 774, 789, 0, 770, 0, 1018, + 952, 954, 0, 950, 0, 760, 761, 762, 754, 755, + 756, 757, 758, 759, 766, 928, 926, 927, 0, 0, + 0, 903, 794, 0, 0, 796, 795, 1343, 1380, 0, + 479, 479, 479, 467, 477, 1022, 0, 640, 491, 1031, + 640, 0, 747, 629, 1083, 1200, 1188, 1189, 958, 1082, + 135, 0, 1208, 0, 0, 0, 141, 124, 0, 1206, + 0, 157, 591, 0, 1015, 499, 500, 504, 504, 0, + 0, 504, 1578, 1469, 0, 0, 0, 0, 542, 582, + 0, 573, 539, 540, 0, 538, 1049, 543, 1048, 544, + 547, 548, 516, 583, 1038, 585, 0, 578, 451, 450, + 589, 0, 43, 0, 1351, 60, 0, 0, 0, 0, + 0, 0, 216, 253, 216, 98, 1351, 380, 1351, 380, + 1249, 1318, 1485, 0, 56, 89, 0, 286, 115, 0, + 271, 315, 79, 94, 108, 0, 0, 45, 175, 189, + 194, 111, 198, 195, 1121, 196, 122, 0, 41, 0, + 109, 0, 1119, 0, 0, 47, 113, 1123, 489, 489, + 489, 0, 962, 0, 0, 0, 964, 965, 1011, 0, 404, 0, 309, 0, 414, 394, 395, 405, 0, 0, - 310, 1089, 0, 1069, 105, 0, 0, 0, 0, 301, + 310, 1101, 0, 1081, 105, 0, 0, 0, 0, 301, 299, 329, 0, 306, 300, 308, 0, 0, 257, 0, - 1228, 0, 0, 390, 386, 0, 0, 0, 661, 674, - 353, 648, 0, 702, 701, 703, 703, 648, 0, 634, - 0, 646, 0, 686, 655, 728, 729, 730, 731, 732, - 733, 734, 346, 348, 0, 350, 0, 0, 407, 0, + 1243, 0, 0, 390, 386, 0, 0, 0, 673, 686, + 353, 660, 0, 714, 713, 715, 715, 660, 0, 646, + 0, 658, 0, 698, 667, 740, 741, 742, 743, 744, + 745, 746, 346, 348, 0, 350, 0, 0, 407, 0, 410, 0, 409, 413, 408, 402, 0, 433, 0, 0, - 0, 0, 0, 0, 1169, 955, 484, 804, 0, 0, - 988, 0, 0, 879, 0, 854, 856, 869, 0, 858, - 860, 0, 932, 0, 0, 0, 870, 807, 808, 0, + 0, 0, 0, 0, 1181, 967, 484, 816, 0, 0, + 1000, 0, 0, 891, 0, 866, 868, 881, 0, 870, + 872, 0, 944, 0, 0, 0, 882, 819, 820, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 823, 822, 871, 907, - 0, 0, 975, 976, 872, 0, 0, 982, 0, 0, - 0, 877, 0, 0, 0, 0, 1024, 833, 946, 913, - 911, 839, 735, 0, 0, 0, 0, 0, 0, 0, - 788, 776, 0, 786, 790, 0, 0, 0, 770, 0, - 0, 768, 800, 764, 0, 0, 801, 0, 0, 0, - 847, 479, 479, 479, 479, 476, 478, 0, 0, 0, - 0, 1451, 0, 600, 578, 580, 587, 600, 605, 849, - 626, 850, 1055, 0, 544, 0, 1025, 544, 0, 1163, - 1176, 0, 1194, 0, 146, 128, 148, 147, 0, 155, - 0, 1003, 0, 146, 130, 0, 149, 0, 1193, 0, - 161, 491, 0, 933, 499, 0, 493, 538, 537, 0, - 509, 568, 507, 0, 574, 0, 0, 0, 261, 0, - 0, 0, 216, 0, 0, 325, 0, 312, 78, 0, - 0, 0, 52, 97, 70, 62, 48, 76, 0, 0, - 81, 0, 74, 91, 92, 90, 95, 0, 245, 226, - 258, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 844, 845, 842, 488, 998, 436, - 437, 180, 435, 319, 0, 0, 307, 1104, 1087, 0, - 0, 104, 106, 0, 168, 310, 0, 285, 281, 0, - 279, 278, 280, 0, 1229, 173, 0, 1224, 1103, 0, - 0, 1098, 680, 645, 0, 698, 696, 644, 0, 640, - 647, 380, 0, 439, 0, 398, 434, 423, 428, 0, - 432, 430, 429, 424, 427, 0, 990, 986, 0, 851, - 956, 0, 944, 970, 969, 806, 818, 819, 820, 971, - 0, 0, 0, 815, 816, 817, 809, 810, 811, 812, - 813, 814, 821, 980, 979, 973, 974, 0, 874, 875, - 876, 981, 0, 1016, 945, 1021, 0, 0, 910, 1044, - 739, 0, 0, 767, 985, 791, 0, 0, 0, 763, - 932, 0, 0, 0, 0, 0, 772, 0, 0, 0, - 894, 889, 890, 0, 0, 0, 0, 470, 469, 475, - 600, 605, 0, 453, 0, 587, 0, 599, 528, 598, - 0, 0, 611, 609, 0, 611, 0, 611, 0, 528, - 0, 601, 528, 598, 0, 618, 1029, 627, 0, 559, - 841, 1015, 559, 0, 466, 1192, 0, 1188, 0, 0, - 0, 136, 133, 123, 0, 0, 158, 146, 137, 0, - 492, 497, 498, 508, 1027, 116, 216, 0, 0, 59, - 0, 327, 273, 305, 288, 0, 0, 0, 217, 0, - 293, 0, 51, 71, 0, 67, 0, 96, 0, 0, - 0, 0, 0, 54, 66, 0, 49, 0, 380, 380, - 57, 272, 1063, 1609, 1610, 1611, 1612, 1613, 1614, 1615, - 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, 1624, 1702, - 1625, 223, 1626, 1399, 1627, 1628, 1629, 0, 1630, 637, - 1631, 1632, 1633, 919, 920, 221, 314, 218, 320, 220, - 222, 0, 1064, 219, 317, 112, 1110, 0, 110, 0, - 1108, 119, 117, 114, 1112, 0, 417, 397, 0, 0, - 0, 1336, 0, 103, 0, 1104, 166, 307, 0, 335, - 257, 330, 0, 1228, 1226, 0, 1223, 0, 0, 0, - 641, 635, 351, 0, 411, 0, 431, 989, 867, 878, - 968, 0, 0, 0, 0, 873, 868, 1023, 0, 1020, - 797, 795, 792, 0, 793, 771, 0, 0, 769, 765, - 0, 802, 880, 0, 896, 893, 474, 473, 472, 471, - 586, 584, 0, 589, 1055, 596, 521, 527, 585, 0, - 581, 0, 610, 606, 0, 607, 0, 0, 608, 0, - 582, 0, 1055, 583, 0, 625, 0, 0, 885, 1042, - 885, 1164, 145, 125, 0, 126, 156, 0, 0, 0, - 0, 150, 391, 0, 323, 61, 0, 305, 0, 216, - 290, 289, 292, 287, 291, 294, 0, 0, 0, 0, - 0, 274, 0, 0, 0, 237, 0, 0, 305, 0, - 311, 233, 234, 344, 0, 0, 0, 63, 53, 50, - 55, 64, 0, 0, 65, 68, 633, 80, 73, 1702, - 1709, 0, 0, 0, 0, 0, 843, 393, 400, 180, - 0, 0, 281, 0, 0, 307, 107, 0, 0, 0, - 1228, 0, 0, 213, 0, 254, 0, 170, 1227, 0, - 1216, 0, 1096, 1097, 0, 0, 399, 824, 0, 0, - 0, 1022, 794, 798, 796, 773, 882, 0, 488, 621, - 0, 624, 588, 0, 0, 516, 523, 0, 526, 520, - 0, 590, 0, 0, 592, 594, 0, 0, 0, 629, - 0, 0, 0, 1032, 1278, 1543, 1450, 0, 543, 545, - 548, 550, 549, 551, 547, 558, 0, 519, 519, 0, - 0, 0, 159, 0, 152, 152, 0, 138, 934, 0, - 216, 0, 304, 324, 252, 0, 0, 235, 0, 242, - 0, 276, 277, 275, 236, 305, 310, 238, 0, 345, - 0, 72, 0, 88, 0, 0, 316, 120, 118, 417, - 0, 1104, 257, 1223, 0, 0, 281, 173, 1225, 270, - 263, 264, 265, 266, 267, 268, 269, 284, 283, 255, - 256, 0, 0, 0, 1098, 0, 825, 0, 826, 0, - 899, 626, 0, 0, 620, 0, 514, 512, 515, 517, - 513, 0, 0, 597, 613, 0, 593, 591, 602, 0, - 633, 0, 604, 0, 0, 0, 552, 0, 884, 886, - 0, 0, 455, 454, 0, 132, 0, 628, 0, 0, - 154, 154, 140, 0, 310, 326, 0, 296, 303, 295, - 0, 0, 232, 0, 239, 334, 241, 225, 632, 0, - 75, 0, 321, 392, 396, 0, 215, 1217, 0, 1223, - 257, 1228, 0, 1220, 0, 0, 1104, 827, 895, 0, - 0, 0, 619, 622, 0, 595, 0, 0, 0, 630, - 631, 603, 0, 0, 0, 546, 0, 0, 521, 127, - 152, 131, 160, 151, 496, 153, 496, 0, 334, 282, - 0, 0, 260, 225, 0, 251, 0, 69, 87, 322, - 0, 307, 1218, 214, 171, 1221, 1222, 0, 628, 1531, - 1279, 1502, 0, 897, 900, 898, 892, 0, 524, 0, - 530, 612, 554, 0, 553, 887, 888, 518, 154, 499, - 499, 628, 251, 297, 302, 0, 240, 243, 331, 332, - 333, 0, 247, 244, 248, 0, 1223, 0, 1094, 0, - 904, 903, 902, 906, 905, 623, 0, 0, 522, 555, - 496, 143, 142, 139, 216, 259, 0, 0, 0, 249, - 0, 250, 224, 1219, 1104, 0, 525, 0, 499, 328, - 229, 0, 228, 0, 313, 246, 628, 901, 0, 144, - 227, 231, 230, 1095, 529 + 0, 0, 0, 0, 0, 0, 835, 834, 883, 919, + 0, 0, 987, 988, 884, 0, 0, 994, 0, 0, + 0, 889, 0, 0, 0, 0, 1036, 845, 958, 925, + 923, 851, 747, 0, 0, 0, 0, 0, 0, 0, + 800, 788, 0, 798, 802, 0, 0, 0, 782, 0, + 0, 780, 812, 776, 0, 0, 813, 0, 0, 0, + 859, 479, 479, 479, 479, 476, 478, 0, 0, 0, + 0, 1469, 0, 612, 590, 592, 599, 612, 617, 861, + 638, 862, 1067, 0, 554, 489, 1037, 554, 0, 1175, + 1191, 0, 1209, 0, 146, 128, 148, 147, 0, 155, + 0, 1015, 0, 146, 130, 0, 149, 0, 1208, 0, + 161, 0, 493, 494, 496, 0, 945, 504, 498, 546, + 545, 0, 514, 580, 512, 0, 586, 0, 0, 0, + 261, 0, 0, 0, 216, 0, 0, 325, 0, 312, + 78, 0, 0, 0, 52, 97, 70, 62, 48, 76, + 0, 0, 81, 0, 74, 91, 92, 90, 95, 0, + 245, 226, 258, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 491, + 487, 488, 853, 1010, 436, 437, 180, 435, 319, 0, + 0, 307, 1116, 1099, 0, 0, 104, 106, 0, 168, + 310, 0, 285, 281, 0, 279, 278, 280, 0, 1244, + 173, 0, 1239, 1115, 0, 0, 1110, 692, 657, 0, + 710, 708, 656, 0, 652, 659, 380, 0, 439, 0, + 398, 434, 423, 428, 0, 432, 430, 429, 424, 427, + 0, 1002, 998, 0, 863, 968, 0, 956, 982, 981, + 818, 830, 831, 832, 983, 0, 0, 0, 827, 828, + 829, 821, 822, 823, 824, 825, 826, 833, 992, 991, + 985, 986, 0, 886, 887, 888, 993, 0, 1028, 957, + 1033, 0, 0, 922, 1056, 751, 0, 0, 779, 997, + 803, 0, 0, 0, 775, 944, 0, 0, 0, 0, + 0, 784, 0, 0, 0, 906, 901, 902, 0, 0, + 0, 0, 470, 469, 475, 612, 617, 0, 453, 0, + 599, 0, 611, 533, 610, 0, 0, 623, 621, 0, + 623, 0, 623, 0, 533, 0, 613, 533, 610, 0, + 630, 1041, 639, 0, 569, 0, 1027, 569, 0, 466, + 1207, 0, 1203, 0, 0, 0, 136, 133, 123, 0, + 0, 158, 146, 137, 502, 503, 0, 497, 513, 1039, + 116, 216, 0, 0, 59, 0, 327, 273, 305, 288, + 0, 0, 0, 217, 0, 293, 0, 51, 71, 0, + 67, 0, 96, 0, 0, 0, 0, 0, 54, 66, + 0, 49, 0, 380, 380, 57, 272, 1075, 1627, 1628, + 1629, 1630, 1631, 1632, 1633, 1634, 1635, 1636, 1637, 1638, + 1639, 1640, 1641, 1642, 1720, 1643, 223, 1644, 1416, 1645, + 1646, 1647, 0, 1648, 649, 1649, 1650, 1651, 931, 932, + 221, 314, 218, 320, 220, 222, 0, 1076, 219, 317, + 112, 1122, 0, 110, 0, 1120, 119, 117, 114, 1124, + 856, 857, 854, 489, 417, 397, 0, 0, 0, 1351, + 0, 103, 0, 1116, 166, 307, 0, 335, 257, 330, + 0, 1243, 1241, 0, 1238, 0, 0, 0, 653, 647, + 351, 0, 411, 0, 431, 1001, 879, 890, 980, 0, + 0, 0, 0, 885, 880, 1035, 0, 1032, 809, 807, + 804, 0, 805, 783, 0, 0, 781, 777, 0, 814, + 892, 0, 908, 905, 474, 473, 472, 471, 598, 596, + 0, 601, 1067, 608, 526, 532, 597, 0, 593, 0, + 622, 618, 0, 619, 0, 0, 620, 0, 594, 0, + 1067, 595, 0, 637, 0, 0, 897, 853, 897, 1176, + 145, 125, 0, 126, 156, 0, 0, 0, 0, 150, + 391, 0, 323, 61, 0, 305, 0, 216, 290, 289, + 292, 287, 291, 294, 0, 0, 0, 0, 0, 274, + 0, 0, 0, 237, 0, 0, 305, 0, 311, 233, + 234, 344, 0, 0, 0, 63, 53, 50, 55, 64, + 0, 0, 65, 68, 645, 80, 73, 1720, 1727, 0, + 0, 0, 0, 0, 0, 393, 400, 180, 0, 0, + 281, 0, 0, 307, 107, 0, 0, 0, 1243, 0, + 0, 213, 0, 254, 0, 170, 1242, 0, 1231, 0, + 1108, 1109, 0, 0, 399, 836, 0, 0, 0, 1034, + 806, 810, 808, 785, 894, 0, 491, 633, 0, 636, + 600, 0, 0, 521, 528, 0, 531, 525, 0, 602, + 0, 0, 604, 606, 0, 0, 0, 641, 0, 0, + 0, 1044, 552, 1293, 1561, 1468, 553, 0, 551, 555, + 558, 560, 559, 561, 557, 568, 0, 571, 1054, 571, + 0, 0, 0, 159, 0, 152, 152, 0, 138, 946, + 0, 216, 0, 304, 324, 252, 0, 0, 235, 0, + 242, 0, 276, 277, 275, 236, 305, 310, 238, 0, + 345, 0, 72, 0, 88, 0, 0, 316, 120, 118, + 855, 417, 0, 1116, 257, 1238, 0, 0, 281, 173, + 1240, 270, 263, 264, 265, 266, 267, 268, 269, 284, + 283, 255, 256, 0, 0, 0, 1110, 0, 837, 0, + 838, 0, 911, 638, 0, 0, 632, 0, 519, 517, + 520, 522, 518, 0, 0, 609, 625, 0, 605, 603, + 614, 0, 645, 0, 616, 0, 0, 0, 562, 0, + 896, 898, 0, 0, 524, 524, 0, 132, 0, 640, + 0, 0, 154, 154, 140, 0, 310, 326, 0, 296, + 303, 295, 0, 0, 232, 0, 239, 334, 241, 225, + 644, 0, 75, 0, 321, 392, 396, 0, 215, 1232, + 0, 1238, 257, 1243, 0, 1235, 0, 0, 1116, 839, + 907, 0, 0, 0, 631, 634, 0, 607, 0, 0, + 0, 642, 643, 615, 0, 0, 0, 556, 0, 0, + 570, 0, 455, 454, 127, 152, 131, 160, 151, 501, + 153, 501, 0, 334, 282, 0, 0, 260, 225, 0, + 251, 0, 69, 87, 322, 0, 307, 1233, 214, 171, + 1236, 1237, 0, 640, 1549, 1294, 1520, 0, 909, 912, + 910, 904, 0, 529, 0, 535, 624, 564, 0, 563, + 899, 900, 526, 154, 504, 504, 640, 251, 297, 302, + 0, 240, 243, 331, 332, 333, 0, 247, 244, 248, + 0, 1238, 0, 1106, 0, 916, 915, 914, 918, 917, + 635, 0, 0, 527, 565, 523, 501, 143, 142, 139, + 216, 259, 0, 0, 0, 249, 0, 250, 224, 1234, + 1116, 0, 530, 0, 504, 328, 229, 0, 228, 0, + 313, 246, 640, 913, 0, 144, 227, 231, 230, 1107, + 534 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 36, 37, 38, 39, 2114, 2115, 2116, 1805, 972, - 2800, 1806, 973, 974, 2118, 40, 41, 2160, 2161, 42, - 1429, 532, 1743, 1372, 2529, 44, 2069, 1748, 2073, 2672, - 2317, 2068, 2075, 2780, 2844, 2070, 1749, 2673, 1750, 45, - 46, 1501, 47, 732, 48, 1502, 1456, 1241, 992, 1446, - 1230, 49, 84, 50, 2105, 2406, 2857, 2128, 2944, 2560, - 2561, 1807, 2902, 2903, 2107, 2174, 1438, 2896, 1869, 2727, - 1811, 1794, 2562, 1878, 2682, 2439, 1808, 2348, 1870, 2546, - 2786, 1512, 1871, 2787, 2539, 1872, 1481, 1505, 2350, 2904, - 1812, 1482, 2407, 1425, 1873, 2855, 1874, 491, 2565, 51, - 524, 525, 724, 1179, 526, 705, 52, 492, 1145, 533, - 54, 1857, 2589, 2194, 2590, 1926, 1851, 1239, 1923, 1555, - 1485, 1240, 479, 1569, 2195, 2151, 1556, 534, 874, 57, - 58, 59, 570, 583, 584, 1343, 1720, 2037, 942, 557, - 558, 598, 1475, 1379, 1380, 1756, 2086, 1404, 1405, 951, - 952, 2636, 2772, 2637, 2638, 2497, 2498, 2918, 1392, 1396, - 1397, 1769, 1762, 1385, 2309, 2658, 2659, 2660, 2661, 2662, - 2663, 875, 2518, 1400, 1401, 954, 955, 956, 1409, 1779, - 61, 1724, 2044, 2045, 2046, 2287, 2288, 2302, 2298, 2503, - 2644, 2047, 2048, 2629, 2630, 2744, 2305, 2054, 2648, 2649, - 2703, 1529, 706, 1246, 1182, 708, 876, 709, 1158, 877, - 1162, 711, 878, 879, 880, 714, 881, 882, 883, 717, - 1154, 884, 885, 1173, 1201, 1202, 1203, 1204, 1205, 1206, - 1207, 1208, 1209, 926, 1623, 887, 888, 889, 2050, 890, - 1335, 1708, 2667, 2768, 2769, 2030, 2271, 2484, 2628, 2821, - 2873, 2874, 891, 892, 1286, 1287, 1705, 1330, 1331, 893, - 2409, 1333, 1616, 1285, 1282, 1035, 1036, 1247, 1596, 1597, - 1619, 1955, 1626, 1632, 1982, 1983, 1640, 1673, 894, 1580, - 1581, 1941, 1255, 895, 623, 1042, 624, 1252, 1667, 903, - 896, 897, 1279, 1280, 1996, 2246, 1645, 1775, 575, 2640, - 728, 1122, 898, 899, 900, 901, 928, 577, 1037, 472, - 720, 2845, 1135, 932, 1038, 1809, 1663, 62, 801, 628, - 63, 1133, 1493, 64, 2613, 2449, 1147, 1514, 1882, 493, - 65, 66, 67, 68, 69, 605, 1233, 535, 1234, 1235, - 789, 70, 1242, 791, 792, 71, 564, 565, 1243, 1356, - 1244, 72, 544, 73, 922, 580, 923, 925, 537, 939, - 2064, 1739, 75, 76, 551, 552, 77, 78, 566, 79, - 80, 2610, 538, 2177, 1142, 501, 474, 475, 722, 1125, - 1040, 1126 + -1, 37, 38, 39, 40, 2136, 2137, 2138, 1823, 980, + 2832, 1824, 981, 982, 2140, 41, 42, 2185, 2186, 43, + 1442, 536, 1756, 1381, 2557, 45, 2089, 1761, 2093, 2703, + 2342, 2088, 2095, 2812, 2879, 2090, 1762, 2704, 1763, 46, + 47, 1514, 48, 739, 49, 1515, 1469, 1250, 1000, 1459, + 1239, 50, 85, 51, 2127, 2431, 2892, 2150, 2980, 2588, + 2589, 1825, 2937, 2938, 2129, 2199, 1451, 2931, 1889, 2759, + 1829, 1812, 2590, 1898, 2713, 2467, 1826, 2373, 1890, 2574, + 2818, 1525, 1891, 2819, 2567, 1892, 1494, 1518, 2375, 2939, + 1830, 1495, 2432, 1438, 1893, 2890, 1894, 495, 2593, 52, + 528, 529, 731, 1188, 530, 712, 53, 496, 1154, 537, + 55, 1877, 2617, 2219, 2618, 1946, 1871, 1248, 1943, 1568, + 1498, 1249, 483, 1582, 2220, 2176, 1569, 538, 882, 58, + 59, 60, 577, 590, 591, 1352, 1733, 2057, 950, 564, + 565, 1865, 605, 1488, 1390, 1391, 1767, 2102, 1417, 1418, + 959, 960, 2664, 2872, 2665, 2666, 2525, 2526, 2953, 1405, + 1409, 1410, 1787, 1777, 1396, 2334, 2688, 2689, 2690, 2691, + 2692, 2693, 883, 2546, 2804, 1413, 1414, 962, 963, 964, + 1422, 1797, 62, 1737, 2064, 2065, 2066, 2312, 2313, 2327, + 2323, 2531, 2672, 2067, 2068, 2657, 2658, 2776, 2330, 2074, + 2676, 2677, 2734, 1542, 713, 1255, 1191, 715, 884, 716, + 1167, 885, 1171, 718, 886, 887, 888, 721, 889, 890, + 891, 724, 1163, 892, 893, 1182, 1210, 1211, 1212, 1213, + 1214, 1215, 1216, 1217, 1218, 934, 1636, 895, 896, 897, + 2070, 898, 1344, 1721, 2697, 2800, 2801, 2050, 2296, 2512, + 2656, 2853, 2908, 2909, 899, 900, 1295, 1296, 1718, 1339, + 1340, 901, 2434, 1342, 1629, 1294, 1291, 1043, 1044, 1256, + 1609, 1610, 1632, 1975, 1639, 1645, 2002, 2003, 1653, 1686, + 902, 1593, 1594, 1961, 1264, 903, 630, 1050, 631, 1261, + 1680, 911, 904, 905, 1288, 1289, 2016, 2271, 1658, 1793, + 582, 2668, 735, 1131, 906, 907, 908, 909, 936, 584, + 1045, 476, 727, 2880, 1144, 940, 1046, 1827, 1676, 63, + 809, 635, 64, 1142, 1506, 65, 2641, 2477, 1156, 1527, + 1902, 497, 66, 67, 68, 69, 70, 612, 1242, 539, + 1243, 1244, 796, 71, 1251, 798, 799, 72, 571, 572, + 1252, 1365, 1253, 73, 550, 74, 930, 587, 931, 933, + 541, 947, 2084, 1752, 76, 77, 558, 559, 78, 79, + 573, 80, 81, 2638, 542, 2202, 1151, 505, 478, 479, + 729, 1134, 1048, 1135 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -2529 +#define YYPACT_NINF -2632 static const int yypact[] = { - 4084, -86, 38, -2529, -2529, -86, 31849, -2529, -86, 57, - 2391, 36549, -2529, 25800, -86, 42659, 968, 265, 282, 411, - 429, 42659, 42659, 37019, -86, 219, 43129, -2529, -86, 22081, - 34199, -8, 74, 43599, 42659, 568, 639, 178, -2529, -2529, - -2529, -2529, -2529, -2529, 64, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, 88, -2529, 53, 102, - 439, 226, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - 286, -2529, -2529, -2529, -2529, -2529, -2529, -2529, 21610, -2529, - -2529, -2529, -2529, -2529, -2529, 37489, 42659, 37959, 34669, 38429, - -2529, 106, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, 131, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, 132, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - 249, 274, -2529, 135, -2529, -2529, -2529, -2529, 568, 38899, - -2529, -93, 567, -2529, 445, 44069, -2529, -2529, 42659, -2529, - -2529, 649, 38899, 592, -2529, -2529, -2529, 39369, -2529, -2529, - -2529, -2529, 566, -2529, -2529, 437, -2529, 41, -2529, -2529, - -2529, 380, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - 516, -2529, 49239, -2529, 44539, 45009, 45479, -2529, 399, 594, - 394, 21139, -2529, -2529, -2529, -2529, 286, -2529, -2529, 429, - -2529, 429, -2529, -2529, -2529, 193, 420, -2529, 453, 767, - -2529, -2529, -2529, 519, -2529, -2529, 736, 8937, 8937, 45949, - 45949, 429, 45949, 558, -2529, -2529, 285, -2529, 74, -2529, - 439, 519, -2529, 22552, -2529, 613, 274, -2529, -2529, 188, - 891, 11907, 42659, 571, -2529, 620, 571, 635, 700, -2529, - 4084, 1042, 988, 34199, 241, 241, 1158, 241, 691, 735, - -2529, 1411, -2529, 738, -2529, 38899, -2529, 757, 1009, -2529, - 519, 1081, 467, 903, 1094, 2224, 1096, 681, 1098, 839, - 6957, 11907, 30439, -2529, 274, -2529, -2529, -2529, 769, -2529, - 768, -2529, -2529, -2529, -2529, 594, 989, -2529, 770, 1240, - 846, 39839, 40309, 38899, 799, 1250, -2529, -2529, -2529, -2529, - 884, -2529, -2529, 110, -2529, -2529, -2529, -2529, 905, -2529, - 905, 905, -2529, -2529, -2529, -2529, 875, 875, 1045, 882, - -2529, -2529, -2529, 1212, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, 902, 1012, -2529, 905, -2529, 875, - -2529, -2529, -2529, -2529, -2529, 50604, -2529, -2529, -2529, -2529, - 197, 486, -2529, -2529, -2529, 45, 911, -2529, 1345, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, 920, -2529, 4601, - 875, -2529, -2529, 1248, 47, -2529, 1265, 100, -2529, 1295, - 1172, 11907, -2529, 1071, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, 74, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, 308, - -2529, -2529, 28246, -2529, -2529, 394, 994, -2529, 28246, 12402, - 49694, 1439, -2529, 1270, 42659, 998, -2529, -2529, -2529, -2529, - -2529, -2529, 1015, 1501, 129, 1506, 11907, 1033, 129, 129, - 1037, 1383, -2529, -2529, -2529, 136, 1064, 1074, -2529, 140, - 140, -2529, 1076, 1087, -2529, 145, 1090, 1103, 1596, 1608, - 82, 1129, 1138, 1012, 129, 11907, -2529, 1150, 140, 1154, - 1159, 1161, 1646, 1163, -2529, 1648, 1166, 90, 114, 1167, - 1168, -2529, 1169, -2529, 146, 11907, 11907, 11907, 1513, 11907, - 7947, 38899, 1653, -2529, 274, 1174, 429, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, 121, 4575, -2529, 1214, -2529, - -2529, -2529, 181, 11907, -2529, 1649, -32, -2529, 147, -2529, - -2529, -2529, 551, 1456, 1176, -2529, -2529, -2529, -2529, 165, - 1575, 27306, 27776, 38899, -2529, -2529, 274, -2529, -2529, -2529, - -2529, -2529, -2529, 601, -2529, 286, 29463, 614, 274, 571, - 42659, 42659, 1637, -2529, -2529, -2529, 34199, 38899, 46419, 1306, - -2529, -2529, 439, 439, 11907, 439, 473, 33, 9432, 12897, - 1512, 1398, 141, 608, 1515, -2529, 1404, 691, 735, 11907, - 620, -2529, 1454, 38899, 32319, 765, 844, 1194, 1278, 1198, - 403, 1602, -2529, 1199, -2529, 1288, 38899, 50604, 163, -2529, - 1643, 163, 163, 278, 1650, 1294, 200, 1443, -39, 260, - 1199, 2023, -2529, 34199, 87, 518, 1199, 38899, 1299, 577, - 1199, 84, 12402, 1100, 1185, 325, 1206, 1287, 101, 12402, - 1292, 1372, 1410, 1417, 1423, 1448, 1507, 1547, 1558, 1568, - 108, 1570, 1572, 1574, 1577, 1581, 1583, 111, 1585, 79, - 12402, 1590, 1218, -2529, 29463, -38, -2529, -2529, 1593, 118, - -2529, 25895, 1213, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, 1307, 42659, - 1268, 363, 1566, 1628, 30439, 1231, 1582, 38899, 1457, 2023, - 1459, 1239, 1694, 768, 9927, 1698, -2529, 46889, -2529, -2529, - -2529, -2529, -2529, -2529, 1264, -2529, -2529, 11907, -2529, -2529, - -2529, 1743, -2529, 49694, 49694, 905, 905, -2529, -2529, 1704, - 1349, 1350, 1743, -2529, 1743, -2529, -2529, -2529, 49694, -2529, - 42659, 1275, 1277, 1743, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - 1743, 1358, -2529, 1359, 1360, 1362, -2529, -2529, -2529, -2529, - -2529, 42659, 42659, -2529, 42659, 42659, -2529, 42659, 42659, 630, - 40779, 394, 35139, -2529, -2529, -2529, -2529, 326, 953, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, 30439, -2529, - 2048, -2529, -2529, -2529, 1280, 660, -2529, 673, 568, -2529, - -2529, 11907, 274, 11907, 29463, 1310, 11907, 11907, 1282, 1743, - 1743, -2529, 1744, 1743, 1743, 29502, 11907, 25381, 11907, 16362, - 10422, 11907, 11907, 8442, 11907, 29502, 1763, 1763, 23494, -2529, - 1438, 1284, 1290, 2546, 4881, 1289, -2529, 536, -2529, 1285, - -2529, 274, 274, 11907, -2529, 11907, 5263, 5263, -2529, 155, - 49694, 11907, 11907, 11907, 11907, 29969, 1370, 119, 42659, 11907, - 11907, 1296, 826, -2529, 11907, 1510, -2529, 1298, 11907, 1378, - 138, 11907, 11907, 11907, 11907, 11907, 11907, 11907, 11907, 11907, - -2529, -2529, 17833, 221, 1611, 1630, 274, 11907, -96, 172, - 11907, 35609, 8937, 1622, 6957, -2529, 274, 26366, 85, 1622, - -2529, -2529, -2529, -2529, 151, -2529, -2529, -2529, -2529, 1280, - -2529, 1280, 1301, 38899, 188, 33729, -2529, 11907, -2529, 715, - 1312, 1371, 576, 1766, 42659, -2529, 23965, 1595, -2529, 1313, - -2529, 28712, 1595, -2529, -2529, 16843, 1436, 1598, 1526, -2529, - -2529, -2529, 1320, 29463, 13392, 13392, -2529, 1260, 29463, 1262, - -2529, -2529, -2529, -2529, -2529, -2529, 485, -2529, 38899, -14, - 1512, 608, 728, -2529, -2529, 867, 1325, 47359, 42659, 1603, - 1554, 1606, -147, -2529, -2529, -2529, 49694, -2529, 42659, 42659, - 47829, 48299, 30909, 42659, 30439, -2529, -2529, -2529, -2529, 42659, - 749, 42659, 5279, -2529, -2529, -2529, 163, -2529, -2529, -2529, - -2529, -2529, 42659, 42659, -2529, -2529, 163, 42659, 42659, 163, - -2529, 874, 42659, 42659, 42659, 42659, 1082, 42659, 42659, -37, - -37, 1538, -2529, 10917, 1336, -2529, 11907, 11907, -2529, 11907, - 1508, -2529, 743, -2529, 1549, 40, 1386, 38899, 38899, 42659, - 1041, -2529, -2529, -2529, -2529, -2529, -2529, 30439, 1342, 1343, - 1684, -2529, 2023, 1688, 32789, 634, 722, 1390, -2529, 782, - 11907, 1576, -2529, -2529, 1559, 11907, 817, 1353, 45, 821, - -2529, -2529, 1361, 1277, 1373, 1374, 1357, 1365, -2529, 835, - 49694, 1743, 103, 1366, 1367, 1369, 1190, 563, 1267, 47, - -2529, 100, -2529, 1569, 113, -2529, 1586, 768, 1813, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, 840, 20668, -2529, -2529, - 1822, 429, 1822, 586, -2529, -2529, 1822, -2529, 1822, -2529, - 28246, -2529, 12402, -2529, 49694, -2529, 847, -2529, 1376, 11907, - 89, -2529, 28776, 854, 11907, 1392, 1393, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, 1394, 1691, -2529, 1395, - 1397, 3329, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, 1400, 1377, 28836, 1401, - 16362, 16362, 7947, 3295, -2529, 16362, 1402, -2529, -2529, 855, - 28730, 1284, 1403, 29075, 11412, 11907, 11412, 11412, 29109, 1284, - 1407, 29258, 42659, -2529, 13887, -2529, -2529, -2529, 11907, 38899, - -2529, 11907, 860, 5112, -2529, -2529, -2529, 5484, 5484, 5484, - 29502, -2529, -2529, -2529, 1408, -2529, 16362, 16362, -2529, 4401, - 3016, 7947, -2529, -2529, 1705, -2529, 624, -2529, 1399, -2529, - -2529, 4013, -2529, 25381, 3521, 11907, 120, -2529, 11907, 1296, - 11907, 1471, 5484, 5484, 5484, 194, 194, 124, 124, 124, - 305, 172, -2529, -2529, -2529, 1405, 1409, 1416, 1609, 29463, - 1163, 11907, -2529, 29463, 753, 761, 38899, 94, 1412, 2834, - -2529, -2529, -2529, 19255, 1453, -38, 1513, 1453, 1743, 5263, - -2529, 620, -2529, -2529, -2529, 29463, -2529, 568, 19255, 1458, - 1469, -98, 22081, 1627, -2529, 42659, -2529, 42659, -2529, -35, - 1431, -2529, 11907, -2529, -2529, 184, 1440, 1634, 1635, 954, - 954, 1260, 1636, -2529, -2529, 1482, -2529, 11907, 1283, -2529, - 1297, -2529, -2529, -2529, -2529, 1426, -2529, -2529, 1683, -2529, - -2529, -2529, -2529, 1514, 1199, 11907, 1655, -2529, 60, 1435, - 1775, -145, 1731, 42659, -2529, 1641, -2529, 750, 1780, 113, - 1781, 113, 30439, 30439, 30439, 861, -2529, -2529, 429, -2529, - -2529, 866, -2529, -186, -2529, -2529, -2529, 1524, 640, 1199, - 2023, -2529, -2529, -2529, -2529, -2529, -2529, -2529, 156, 672, - 1199, 1527, -2529, 1529, -2529, 1530, 678, 1199, -2529, -2529, - 1444, 1451, 1460, 12402, -2529, -2529, 29463, 29463, 29463, 1455, - -2529, 173, -2529, 42659, -2529, -2529, -2529, 1508, 38899, 1462, - 768, -2529, 748, -2529, 429, 42659, 38899, 38899, 38899, -2529, - -2529, -2529, 1463, 1466, -2529, 49694, -47, 1665, 1666, 42659, - 1495, 1198, 1916, -2529, 29463, 1810, 38899, 873, -2529, -2529, - -2529, -2529, 1743, -2529, -2529, 355, 355, -2529, 42659, -2529, - 1483, -2529, 1488, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, -2529, -2529, 42659, -2529, 1827, 568, -2529, 30439, - -2529, 33259, -2529, -2529, -2529, -2529, 429, -2529, 429, 1707, - 42659, 26836, 429, 429, -2529, -2529, -2529, -2529, 29349, 11907, - -2529, 1839, 49694, -2529, 5211, -2529, -2529, -2529, 11907, -2529, - -2529, 11907, -2529, 25381, 11907, 1814, -2529, 1970, 1970, 4881, - 49694, 16362, 16362, 16362, 16362, 675, 1154, 16362, 16362, 16362, - 16362, 16362, 16362, 16362, 16362, 16362, 17338, 262, -2529, -2529, - 11907, 11907, 1820, 1814, -2529, 49694, 1497, 1284, 1511, 1516, - 11907, -2529, 49694, 879, 7947, 29388, -2529, 274, 5455, -2529, - 29463, -2529, 5263, 11907, 2965, 3395, 11907, 880, 11907, 1817, - -2529, -2529, 1518, -2529, -2529, 49694, 11907, 1521, 4634, 16362, - 16362, 4751, -2529, 6273, 11907, 7947, -2529, 1538, 1548, 24436, - -2529, 1607, 1607, 1607, 1607, -2529, -2529, 38899, 38899, 38899, - 19726, 1837, 18784, 41249, 1519, 1032, -2529, 41249, 41719, -2529, - 1540, -2529, 274, 11907, 1840, 1531, 1438, 1840, 1532, -2529, - -2529, 1533, 1519, 11907, 1674, -2529, -2529, -2529, 1587, -2529, - 894, -2529, 1941, 1674, -2529, 900, -2529, 23965, 1458, 11907, - 274, -2529, 1537, -2529, 1440, 130, -2529, -2529, -2529, 1745, - -2529, -2529, -2529, 38899, -2529, 42659, 5530, 1878, -2529, 42659, - 42659, 42659, -2529, 42659, 909, 185, 1541, -2529, 185, 1857, - 179, 1198, 200, 5799, -59, -2529, -2529, -2529, 1619, 42659, - -2529, 42659, -2529, -2529, -2529, -2529, -2529, 30909, -2529, -2529, - -2529, 30439, 24910, 30439, 42659, 42659, 42659, 42659, 42659, 42659, - 42659, 42659, 42659, 42659, -2529, -2529, -2529, 1538, -2529, -2529, - -2529, 260, -2529, -2529, 173, 1550, 32789, 1390, 1628, 42189, - 1551, 1556, -2529, 914, 2023, 1553, 2004, -2529, 634, 32789, - -2529, -2529, -2529, 1964, -2529, 399, 123, -2529, -2529, 568, - 42659, 1612, -2529, 1277, 1562, -2529, -2529, 1277, 49694, -2529, - -2529, 113, 38899, -2529, 918, -2529, -2529, -2529, -2529, 42659, - 1560, -2529, 1560, -2529, -2529, 11907, 29463, -2529, 1561, -2529, - 29463, 6014, -2529, 29463, 1820, -2529, 801, 801, 801, 3550, - 1884, 202, 1565, 801, 801, 801, 247, 247, 143, 143, - 143, 1970, 262, 29463, 29463, -2529, -2529, 1571, -2529, -2529, - -2529, 1284, 1579, -2529, 4797, -2529, 923, 42659, -2529, -2529, - 685, 11907, 11907, 4401, -2529, 3150, 11907, 49694, 932, 4401, - 227, 11907, 3568, 4521, 11907, 11907, 6441, 6058, 1580, 11907, - 48769, -2529, -2529, 38899, 38899, 38899, 38899, -2529, -2529, -2529, - 41249, 41719, 1567, 18312, 1032, 1589, 38899, -2529, 1656, 1578, - 19255, 1841, 1770, -2529, 19255, 1770, 134, 1770, 1847, 1656, - 23023, -2529, 1656, 1588, 1777, -2529, 696, 29463, 2012, 1890, - 429, -2529, 1890, 429, -2529, 29463, 8937, -2529, 568, 997, - 42659, 274, 77, -2529, 1594, 42659, -2529, 1674, 29463, 25381, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, 42659, 956, -2529, - 961, 185, -2529, 1629, -2529, 201, 1885, 49, -2529, 30439, - 1995, 720, -2529, 1895, 1815, -2529, 163, -2529, 11907, 720, - 1818, 168, 42659, -2529, -2529, 2059, -2529, 49694, 113, 113, - -2529, -2529, 1597, 1599, 1600, 1601, 1605, 1610, 1613, 1615, - 1616, 1617, 1618, 1620, 1624, 1625, 1626, 1632, 1639, 902, - 1642, -2529, 1654, 1537, 1657, 1663, 1668, 50149, 1670, 1671, - 1672, 1675, 1680, 326, 953, -2529, -2529, -2529, -2529, -2529, - -2529, 770, 1682, -2529, 1621, -2529, -2529, 1677, -2529, 1686, - -2529, -2529, -2529, -2529, -2529, 1638, 994, 99, 42659, 1647, - 2064, 1852, 1631, -2529, 429, 1390, -2529, 32789, 963, 327, - 1666, -2529, 242, 1495, -2529, 2025, 1690, 1838, 42659, 1658, - -2529, -2529, -2529, 2103, -2529, 33259, 1560, 29463, -2529, -2529, - -2529, 16362, 1978, 1685, 49694, -2529, -2529, -2529, 11907, -2529, - 4401, 4401, 3150, 965, -2529, 4401, 11907, 11907, 4401, 4401, - 11907, -2529, -2529, 6392, 1876, -2529, -2529, -2529, -2529, -2529, - -2529, -2529, 31379, 41249, 1692, -2529, 36079, -2529, -2529, 42659, - 1032, 19255, -2529, -2529, 1263, -2529, 19255, 1940, -2529, 19255, - -2529, 42659, 1695, -2529, 42659, -2529, 14382, 11907, 1727, -2529, - 1727, -2529, 1176, -2529, -98, -2529, -2529, 2093, 20197, 2049, - 11907, -2529, -2529, 1696, 185, -2529, 1856, 1629, 1699, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, 966, 1701, 42659, 42659, - 16362, -2529, 720, 216, 161, -2529, 1974, 38899, 1629, 2112, - -2529, -2529, -2529, -2529, 2079, 2160, 2047, -2529, -2529, 29463, - -2529, -2529, 1743, 1743, -2529, -2529, 2125, -2529, -2529, -2529, - -2529, 770, 398, 24910, 42659, 42659, -2529, -2529, -2529, 260, - 2078, 970, 634, 568, 2051, 32789, -2529, 2168, 1715, 42659, - 1495, 661, 661, -2529, 1858, -2529, 1861, -2529, -2529, 261, - -2529, 38899, -2529, -2529, 20197, 568, -2529, 3885, 16362, 49694, - 984, -2529, -2529, 4401, 4401, 4401, -2529, 2152, 1538, -2529, - 986, 2180, -2529, 42659, -85, -67, 1732, 1733, -2529, -2529, - 991, -2529, 11907, 1734, -2529, -2529, 19255, 1263, 1002, -2529, - 49694, 42659, 1006, 49694, 1735, -126, 1736, 7452, 1726, -2529, - -2529, -2529, -2529, -2529, 29463, 29463, 42659, 1788, 1788, 1790, - 42659, 11907, -2529, 1020, 2153, 69, -29, 29463, -2529, 38899, - -2529, 30439, -2529, 185, -2529, 30439, 11907, -2529, 910, 3550, - 2192, -2529, -2529, -2529, -2529, 1629, 768, -2529, 42659, -2529, - 2043, -2529, 42659, 1800, 433, 1821, -2529, -2529, -2529, 994, - 429, 1390, 1666, 1690, 38899, 568, 634, 399, -2529, -2529, - -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, -2529, - -2529, 2167, 1952, 2170, 1612, 1022, 3885, 1026, -2529, 11907, - 401, 1540, 31379, 1750, -2529, 1038, -2529, -2529, -2529, -2529, - -2529, 42659, 1019, -2529, 29463, 42659, -2529, -2529, -2529, 42659, - 2125, 1040, -2529, 11907, 1752, 11907, -2529, 14382, 1749, -2529, - 2212, 1897, -2529, -2529, 568, -2529, 25859, 1453, 20197, 42659, - 42659, 42659, -2529, 1888, 768, 185, 1044, -2529, 1779, -2529, - 25877, 1993, -2529, 2083, -2529, 2028, -2529, 1776, -2529, 11907, - -2529, 1854, -2529, -2529, -2529, 2235, -2529, -2529, 1787, 1690, - 1666, 1495, 1994, -2529, 1996, 1794, 1390, -2529, 1284, 14877, - 14877, 1801, -2529, -2529, 42659, -2529, 1046, 1802, 1048, -2529, - -2529, -2529, 1050, 14382, 1052, -2529, 42659, 1804, 36079, -2529, - 2153, -2529, -2529, -2529, 240, -2529, 240, 23965, 2028, -2529, - 30439, 24910, 2026, 1776, 95, 2014, 2023, -2529, 29463, -2529, - 568, 32789, -2529, -2529, -2529, -2529, -2529, 20197, 1453, 15867, - 1948, 97, 28748, -2529, -2529, -2529, -2529, 1057, -2529, 2289, - 1963, -2529, -2529, 1065, -2529, -2529, -2529, -2529, 42659, 1440, - 1440, -176, 2014, -2529, -2529, 2104, -2529, -2529, -2529, -2529, - -2529, 127, 2020, -2529, 2024, 1499, 1690, 1069, -2529, 2271, - -2529, -2529, -2529, -2529, -2529, -2529, 1826, 1819, -2529, -2529, - 240, -2529, -2529, -2529, -2529, -2529, 164, 164, 2197, -2529, - 1882, -2529, -2529, -2529, 1390, 15372, -2529, 2311, 1440, 185, - -2529, 2299, -2529, 176, -2529, -2529, 1453, -2529, 1832, -2529, - -2529, -2529, -2529, -2529, -2529 + 4820, -127, 708, -2632, -2632, -127, 34140, -2632, -127, 56, + 2404, 38880, -2632, 4957, -127, 45516, 900, 161, 185, 195, + 39354, 39354, 45516, 45516, 39828, -127, 230, 45990, -2632, -127, + 23678, 36510, 14, -138, 46464, 45516, 1311, 343, 110, -2632, + -2632, -2632, -2632, -2632, -2632, 77, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, 91, -2632, 144, + 101, -32, 67, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, 170, -2632, -2632, -2632, -2632, -2632, -2632, -2632, 23203, + -2632, -2632, -2632, -2632, -2632, -2632, 40302, 45516, 40776, 36984, + 41250, -2632, 103, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, 116, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, 120, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, 238, 316, -2632, 126, -2632, -2632, + -2632, -2632, 1311, 41724, -2632, -13, 602, -2632, 304, 46938, + -2632, -2632, 45516, -2632, -2632, -16, 41724, 550, -2632, -2632, + -2632, 42198, -2632, -2632, -2632, -2632, 513, -2632, -2632, 359, + -2632, 51, -2632, -2632, -2632, 383, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, 482, -2632, 52152, -2632, 47412, 47886, + 48360, -2632, 357, 493, 932, 22728, -2632, -2632, -2632, -2632, + 170, -2632, -2632, 877, -2632, 39354, 877, -2632, -2632, -2632, + -2632, -2632, -152, 380, -2632, 425, 691, -2632, -2632, -2632, + 431, -2632, -2632, 651, 10426, 10426, 48834, 48834, 877, 48834, + 481, -2632, -2632, 7, -2632, -138, -2632, -32, 431, -2632, + 24153, -2632, 484, 316, -2632, -2632, 199, 814, 13420, 45516, + 489, -2632, 509, 489, 514, 521, -2632, 4820, 852, 825, + 36510, 614, 614, 997, 614, 696, 749, -2632, 1543, -2632, + 562, -2632, 41724, -2632, 583, 865, -2632, 431, 920, 847, + 758, 952, 2317, 957, 977, 1004, 1066, 6933, 13420, 32718, + -2632, 316, -2632, -2632, -2632, 633, -2632, 687, -2632, -2632, + -2632, -2632, 493, 918, -2632, 689, 1154, 754, 42672, 43146, + 41724, 712, 1125, -2632, -2632, -2632, -2632, 750, -2632, -2632, + 121, -2632, -2632, -2632, -2632, 777, -2632, 777, 777, -2632, + -2632, -2632, -2632, 722, 722, 912, 738, -2632, -2632, -2632, + 1067, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, 760, 927, -2632, 777, -2632, 722, -2632, -2632, -2632, + -2632, -2632, 53529, -2632, -2632, -2632, -2632, 331, 508, -2632, + -2632, -2632, 68, 769, -2632, 1212, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, 775, -2632, 2828, 722, -2632, -2632, + 1131, 153, -2632, 1152, 159, -2632, 1160, 1012, 13420, -2632, + 915, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -138, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, 328, -2632, -2632, 30251, + -2632, -2632, 932, 829, -2632, -2632, 30251, 13919, 52611, 1298, + -2632, 1115, 45516, 859, -2632, -2632, -2632, -2632, -2632, -2632, + 873, 1351, 88, 1364, 13420, 891, 88, 88, 896, 1219, + -2632, -2632, -2632, 135, 922, 924, -2632, 136, 136, -2632, + 926, 935, -2632, 139, 951, 994, 1400, 1404, 98, 1002, + 1015, 927, 88, 13420, -2632, 1046, 136, 1070, 1083, 1097, + 1444, 1127, -2632, 1463, 1137, 87, 90, 1140, 1143, -2632, + 1163, -2632, 140, 13420, 13420, 13420, 1328, 13420, 7931, 41724, + 1497, -2632, 316, 1166, 877, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, 100, 5131, -2632, 1089, -2632, -2632, -2632, + 203, 13420, -2632, 1537, -61, -2632, 142, -2632, -2632, -2632, + 442, 1346, 1091, -2632, -2632, -2632, -2632, 164, 1564, 29303, + 29777, 41724, -2632, -2632, 316, -2632, -2632, -2632, -2632, -2632, + -2632, 409, -2632, 170, 31439, 480, 316, 489, 45516, 45516, + 1628, -2632, -2632, -2632, 36510, 41724, 49308, 1297, -2632, -2632, + -32, -32, 9428, -32, 137, 8, 10925, 14418, 1505, 1392, + 151, 603, 1512, -2632, 1399, 696, 749, 13420, 509, -2632, + 1450, 41724, 34614, 599, 612, 1190, 1273, 1194, 305, 1607, + -2632, 1199, -2632, 1279, 41724, 53529, 167, -2632, 1645, 167, + 167, 155, 1646, 1290, 184, 1445, 259, -150, 1199, 2007, + -2632, 36510, 80, 454, 1199, 41724, 1293, 530, 1199, 97, + 13919, 905, 1032, 249, 1145, 1181, 99, 13919, 1244, 1286, + 1324, 1363, 1384, 1442, 1480, 1500, 1507, 1515, 115, 1561, + 1581, 1583, 1587, 1591, 1598, 119, 1601, 147, 13919, 1603, + 1214, -2632, 31439, -56, -2632, -2632, 1605, 122, -2632, 27880, + 1207, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, 1299, 45516, 1258, + -48, 1565, 1626, 32718, 1226, 1590, 41724, 1461, 2007, 1467, + 1245, 1704, 687, 11424, 1711, -2632, 49782, -2632, -2632, -2632, + -2632, -2632, -2632, 1256, -2632, -2632, 13420, -2632, -2632, -2632, + 1741, -2632, 52611, 52611, 777, 777, -2632, -2632, 1716, 1342, + 1352, 1741, -2632, 1741, -2632, -2632, -2632, 52611, -2632, 45516, + 1265, 1274, 1741, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, 1741, + 1355, -2632, 1358, 1370, 1374, -2632, -2632, -2632, -2632, -2632, + 45516, 45516, -2632, 45516, 45516, -2632, 45516, 45516, 527, 43620, + 932, 37458, -2632, -2632, -2632, -2632, 319, 686, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, 32718, -2632, 1686, + -2632, -2632, -2632, 1267, 533, -2632, 553, 1311, -2632, -2632, + 13420, 316, 13420, 31439, 1325, 13420, 13420, 1282, 1741, 1741, + -2632, 4360, 1741, 1741, 31773, 13420, 27006, 13420, 17911, 11923, + 13420, 13420, 8430, 13420, 31773, 1776, 1776, 25103, -2632, 1448, + 1292, 1300, 772, 5796, 1301, -2632, 566, -2632, 1291, -2632, + 316, 316, 13420, -2632, 13420, 3440, 3440, -2632, 186, 52611, + 13420, 13420, 13420, 13420, 32244, 1385, 132, 45516, 13420, 13420, + 1303, 1153, -2632, 13420, 1521, -2632, 1308, 13420, 1390, 173, + 13420, 13420, 13420, 13420, 13420, 13420, 13420, 13420, 13420, -2632, + -2632, 19394, 188, 1629, 1650, 316, 13420, 258, 231, 13420, + 37932, 10426, 1637, 6933, -2632, 316, 28355, 93, 1637, -2632, + -2632, -2632, -2632, 143, -2632, -2632, -2632, -2632, 1267, -2632, + 1267, 1314, 41724, 199, 36036, -2632, 13420, -2632, 563, 1317, + 1376, 555, 1781, 45516, -2632, 25578, 1606, -2632, 256, 256, + 1322, -2632, 30721, 1606, -2632, -2632, 18396, 1446, 1600, 1538, + -2632, -2632, 1519, 1525, -2632, 1329, 31672, 14917, 14917, -2632, + 1128, 31439, 1269, -2632, -2632, -2632, -2632, -2632, -2632, 477, + -2632, 41724, -14, 1505, 603, 590, -2632, -2632, 1076, 1338, + 50256, 45516, 1613, 1566, 1616, -161, -2632, -2632, -2632, 52611, + -2632, 45516, 45516, 50730, 51204, 33192, 45516, 32718, -2632, -2632, + -2632, -2632, 45516, 1052, 45516, 5461, -2632, -2632, -2632, 167, + -2632, -2632, -2632, -2632, -2632, 45516, 45516, -2632, -2632, 167, + 45516, 45516, 167, -2632, 1120, 45516, 45516, 45516, 45516, 1344, + 45516, 45516, -44, -44, 1548, -2632, 12422, 95, -2632, 13420, + 13420, -2632, 13420, 1518, -2632, 604, -2632, 1560, 96, 1394, + 41724, 41724, 45516, 1406, -2632, -2632, -2632, -2632, -2632, -2632, + 32718, 1353, 1354, 1694, -2632, 2007, 1695, 35088, 622, 543, + 1393, -2632, 606, 13420, 1584, -2632, -2632, 1568, 13420, 623, + 1360, 68, 625, -2632, -2632, 1365, 1274, 1381, 1382, 1366, + 1367, -2632, 627, 52611, 1741, 106, 1368, 1372, 1369, 1318, + 42, 1283, 153, -2632, 159, -2632, 1580, 138, -2632, 1596, + 687, 1834, -2632, -2632, -2632, -2632, -2632, -2632, -2632, 635, + 22253, -2632, -2632, 1836, 877, 1836, 387, -2632, -2632, 1836, + -2632, 1836, -2632, 30251, -2632, 13919, -2632, 52611, -2632, 642, + -2632, 1383, 13420, 109, -2632, 30787, 644, 13420, 1379, 1391, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, 1397, + 1708, -2632, 1398, 1401, 5043, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, 1402, + 1389, 30870, 1403, 17911, 17911, 7931, 1649, -2632, 17911, 1408, + -2632, -2632, 654, 30739, 1292, 1413, 31049, 12921, 13420, 12921, + 12921, 31113, 1292, 1416, 31280, 45516, -2632, 15416, -2632, -2632, + -2632, 13420, 41724, -2632, 13420, 719, 6145, -2632, -2632, -2632, + 6287, 6287, 6287, 31773, -2632, -2632, -2632, 1410, -2632, 17911, + 17911, -2632, 4177, 805, 7931, -2632, -2632, 1710, -2632, 780, + -2632, 1386, -2632, -2632, 2165, -2632, 27006, 31633, 13420, 150, + -2632, 13420, 1303, 13420, 1475, 6287, 6287, 6287, 194, 194, + 89, 89, 89, 297, 231, -2632, -2632, -2632, 1405, 1407, + 1418, 1619, 31439, 1127, 13420, -2632, 31439, 664, 706, 41724, + 2889, 3003, 3272, -2632, -2632, -2632, 20828, 1441, -56, 1328, + 1441, 1741, 3440, -2632, 509, -2632, -2632, -2632, 31439, -2632, + 1311, 20828, 1462, 1471, -110, 23678, 1634, -2632, 45516, -2632, + 45516, -2632, -12, 1436, -2632, -2632, -2632, 1458, 1458, 13420, + 1443, 1458, 1635, 1642, 724, 724, 1128, 1653, -2632, -2632, + 1487, -2632, -2632, -2632, 13420, 8929, 1294, -2632, 1296, -2632, + -2632, -2632, -2632, 1447, -2632, -2632, 1699, -2632, -2632, -2632, + -2632, 1527, 1199, 13420, 1672, -2632, 113, 1449, 1793, -134, + 1748, 45516, -2632, 1659, -2632, 781, 1797, 138, 1798, 138, + 32718, 32718, 32718, 746, -2632, -2632, 877, -2632, -2632, 755, + -2632, -171, -2632, -2632, -2632, 1539, 580, 1199, 2007, -2632, + -2632, -2632, -2632, -2632, -2632, -2632, 124, 587, 1199, 1540, + -2632, 1545, -2632, 1546, 617, 1199, -2632, -2632, 95, 95, + 95, 13919, -2632, 1674, 1680, 1466, 31439, 31439, 31439, 1469, + -2632, 149, -2632, 45516, -2632, -2632, -2632, 1518, 41724, 1470, + 687, -2632, 630, -2632, 877, 45516, 41724, 41724, 41724, -2632, + -2632, -2632, 1472, 1473, -2632, 52611, -62, 1683, 1689, 45516, + 1514, 1194, 1943, -2632, 31439, 1823, 41724, 791, -2632, -2632, + -2632, -2632, 1741, -2632, -2632, 251, 251, -2632, 45516, -2632, + 1488, -2632, 1501, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, 45516, -2632, 1846, 1311, -2632, 32718, + -2632, 35562, -2632, -2632, -2632, -2632, 877, -2632, 877, 1724, + 45516, 28829, 877, 877, -2632, -2632, -2632, -2632, 31394, 13420, + -2632, 1857, 52611, -2632, 6164, -2632, -2632, -2632, 13420, -2632, + -2632, 13420, -2632, 27006, 13420, 1832, -2632, 1991, 1991, 5796, + 52611, 17911, 17911, 17911, 17911, 472, 1070, 17911, 17911, 17911, + 17911, 17911, 17911, 17911, 17911, 17911, 18895, 353, -2632, -2632, + 13420, 13420, 1842, 1832, -2632, 52611, 1513, 1292, 1524, 1530, + 13420, -2632, 52611, 817, 7931, 31355, -2632, 316, 6190, -2632, + 31439, -2632, 3440, 13420, 1706, 3271, 13420, 826, 13420, 1847, + -2632, -2632, 1526, -2632, -2632, 52611, 13420, 1531, 2249, 17911, + 17911, 3402, -2632, 3801, 13420, 7931, -2632, 1548, 1574, 26053, + -2632, 1630, 1630, 1630, 1630, -2632, -2632, 41724, 41724, 41724, + 21303, 1864, 20353, 44094, 1544, 1541, -2632, 44094, 44568, -2632, + 1556, -2632, 316, 13420, 1860, 95, 1448, 1860, 1550, -2632, + -2632, 1551, 1544, 13420, 1700, -2632, -2632, -2632, 1610, -2632, + 854, -2632, 1963, 1700, -2632, 863, -2632, 25578, 1462, 13420, + 316, 125, -2632, -2632, -2632, 1559, -2632, 1458, -2632, -2632, + -2632, 1774, -2632, -2632, -2632, 41724, -2632, 45516, 27488, 1909, + -2632, 45516, 45516, 45516, -2632, 45516, 864, 631, 1567, -2632, + 631, 1889, 192, 1194, 184, 2873, -27, -2632, -2632, -2632, + 1640, 45516, -2632, 45516, -2632, -2632, -2632, -2632, -2632, 33192, + -2632, -2632, -2632, 32718, 26531, 32718, 45516, 45516, 45516, 45516, + 45516, 45516, 45516, 45516, 45516, 45516, 1570, 1575, 1576, 1548, + -2632, -2632, -2632, -2632, -2632, -2632, -150, -2632, -2632, 149, + 1578, 35088, 1393, 1626, 45042, 1579, 1577, -2632, 868, 2007, + 1582, 2036, -2632, 622, 35088, -2632, -2632, -2632, 1997, -2632, + 357, 131, -2632, -2632, 1311, 45516, 1643, -2632, 1274, 1586, + -2632, -2632, 1274, 52611, -2632, -2632, 138, 41724, -2632, 881, + -2632, -2632, -2632, -2632, 45516, 1593, -2632, 1593, -2632, -2632, + 13420, 31439, -2632, 1589, -2632, 31439, 27506, -2632, 31439, 1842, + -2632, 748, 748, 748, 2232, 1912, 444, 1588, 748, 748, + 748, 405, 405, 105, 105, 105, 1991, 353, 31439, 31439, + -2632, -2632, 1594, -2632, -2632, -2632, 1292, 1604, -2632, 5410, + -2632, 889, 45516, -2632, -2632, 281, 13420, 13420, 4177, -2632, + 4993, 13420, 52611, 894, 4177, 189, 13420, 3289, 4244, 13420, + 13420, 3895, 27535, 1611, 13420, 51678, -2632, -2632, 41724, 41724, + 41724, 41724, -2632, -2632, -2632, 44094, 44568, 1602, 19877, 1541, + 1612, 41724, -2632, 1696, 1614, 20828, 1878, 1812, -2632, 20828, + 1812, 107, 1812, 1891, 1696, 24628, -2632, 1696, 1615, 1821, + -2632, 547, 31439, 2058, 1933, 1621, -2632, 1933, 877, -2632, + 31439, 10426, -2632, 1311, 1306, 45516, 316, -47, -2632, 1636, + 45516, -2632, 1700, 31439, -2632, -2632, 27006, -2632, -2632, -2632, + -2632, -2632, 45516, 902, -2632, 909, 631, -2632, 1661, -2632, + 181, 1918, 57, -2632, 32718, 1452, 607, -2632, 1932, 1848, + -2632, 167, -2632, 13420, 607, 1849, 169, 45516, -2632, -2632, + 2046, -2632, 52611, 138, 138, -2632, -2632, 1631, 1632, 1633, + 1647, 1651, 1655, 1656, 1658, 1660, 1663, 1664, 1665, 1666, + 1667, 1670, 1676, 1677, 760, 1679, -2632, 1682, 1559, 1685, + 1687, 1688, 53070, 1690, 1701, 1703, 1705, 1707, 319, 686, + -2632, -2632, -2632, -2632, -2632, -2632, 689, 1709, -2632, 1641, + -2632, -2632, 1712, -2632, 1713, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, 95, 829, 127, 45516, 1662, 2104, 1873, + 1652, -2632, 877, 1393, -2632, 35088, 1069, 168, 1689, -2632, + 112, 1514, -2632, 2037, 1720, 1871, 45516, 1691, -2632, -2632, + -2632, 2131, -2632, 35562, 1593, 31439, -2632, -2632, -2632, 17911, + 2010, 1718, 52611, -2632, -2632, -2632, 13420, -2632, 4177, 4177, + 4993, 916, -2632, 4177, 13420, 13420, 4177, 4177, 13420, -2632, + -2632, 27554, 1887, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + 33666, 44094, 1719, -2632, 38406, -2632, -2632, 45516, 1541, 20828, + -2632, -2632, 506, -2632, 20828, 1986, -2632, 20828, -2632, 45516, + 1721, -2632, 45516, -2632, 9927, 13420, 1755, 877, 1755, -2632, + 1091, -2632, -110, -2632, -2632, 2130, 21778, 2086, 13420, -2632, + -2632, 1725, 631, -2632, 1888, 1661, 1728, -2632, -2632, -2632, + -2632, -2632, -2632, -2632, 933, 1729, 45516, 45516, 17911, -2632, + 607, 198, 133, -2632, 2003, 41724, 1661, 2145, -2632, -2632, + -2632, -2632, 2113, 2193, 2081, -2632, -2632, 31439, -2632, -2632, + 1741, 1741, -2632, -2632, 2157, -2632, -2632, -2632, -2632, 689, + 183, 26531, 45516, 45516, 1738, -2632, -2632, -150, 2112, 938, + 622, 1311, 2083, 35088, -2632, 2199, 1742, 45516, 1514, 676, + 676, -2632, 1883, -2632, 1890, -2632, -2632, 221, -2632, 41724, + -2632, -2632, 21778, 1311, -2632, 2714, 17911, 52611, 943, -2632, + -2632, 4177, 4177, 4177, -2632, 2191, 1548, -2632, 948, 2210, + -2632, 45516, -80, -34, 1754, 1759, -2632, -2632, 949, -2632, + 13420, 1761, -2632, -2632, 20828, 506, 956, -2632, 52611, 45516, + 969, 52611, -2632, 1762, -106, 1763, -2632, 7432, 1765, -2632, + -2632, -2632, -2632, -2632, 31439, 31439, 45516, 1935, -2632, 1935, + 1818, 45516, 13420, -2632, 970, 2190, 66, -35, 31439, -2632, + 41724, -2632, 32718, -2632, 631, -2632, 32718, 13420, -2632, 1305, + 2232, 2230, -2632, -2632, -2632, -2632, 1661, 687, -2632, 45516, + -2632, 2082, -2632, 45516, 1833, 333, 1854, -2632, -2632, -2632, + -2632, 829, 877, 1393, 1689, 1720, 41724, 1311, 622, 357, + -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, + -2632, -2632, -2632, 2211, 1993, 2214, 1643, 975, 2714, 979, + -2632, 13420, 334, 1556, 33666, 1789, -2632, 981, -2632, -2632, + -2632, -2632, -2632, 45516, 840, -2632, 31439, 45516, -2632, -2632, + -2632, 45516, 2157, 1013, -2632, 13420, 1792, 13420, -2632, 15915, + 1790, -2632, 2250, 13420, 1853, 1853, 1311, -2632, 27637, 1441, + 21778, 45516, 45516, 45516, -2632, 1919, 687, 631, 1033, -2632, + 1811, -2632, 27655, 2022, -2632, 2110, -2632, 2054, -2632, 1806, + -2632, 13420, -2632, 1879, -2632, -2632, -2632, 2265, -2632, -2632, + 1810, 1720, 1689, 1514, 2019, -2632, 2020, 1814, 1393, -2632, + 1292, 16414, 16414, 1817, -2632, -2632, 45516, -2632, 1039, 1822, + 1059, -2632, -2632, -2632, 1064, 15915, 1071, -2632, 45516, 1824, + 31439, 1959, -2632, -2632, -2632, 2190, -2632, -2632, -2632, 256, + -2632, 256, 25578, 2054, -2632, 32718, 26531, 2052, 1806, 71, + 2040, 2007, -2632, 31439, -2632, 1311, 35088, -2632, -2632, -2632, + -2632, -2632, 21778, 1441, 17412, 1966, 104, 30768, -2632, -2632, + -2632, -2632, 1088, -2632, 2311, 1985, -2632, -2632, 1090, -2632, + -2632, -2632, 38406, 45516, 1458, 1458, -140, 2040, -2632, -2632, + 2127, -2632, -2632, -2632, -2632, -2632, 117, 2045, -2632, 2047, + 860, 1720, 1095, -2632, 2298, -2632, -2632, -2632, -2632, -2632, + -2632, 1839, 1841, -2632, -2632, -2632, 256, -2632, -2632, -2632, + -2632, -2632, 156, 156, 2216, -2632, 1903, -2632, -2632, -2632, + 1393, 16913, -2632, 2330, 1458, 631, -2632, 2319, -2632, 145, + -2632, -2632, 1441, -2632, 1850, -2632, -2632, -2632, -2632, -2632, + -2632 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -2529, -2529, -2529, 1738, -2529, -2529, -2529, 211, -2529, 886, - -2529, 204, -562, 532, -2529, -2529, -2529, -2529, -2529, -2529, - -917, 8, -2529, -2529, -2529, -2529, 12, 256, -2529, -444, - -1870, -189, -2529, -2442, -2521, -2529, -511, -2407, -1678, -2529, - -1102, 174, -2529, -2094, -2529, -613, -972, -754, -982, -2529, - -24, -2529, 1039, -1099, -1754, -2389, -514, -2529, -587, -2529, - -344, -1741, -559, -539, -2529, -2302, -936, -2529, 1396, -246, - -2529, 573, -2529, -2089, -2529, -2529, 554, -2529, -945, -2529, - -2529, -1789, 189, -483, -2258, -2090, 512, -620, -2529, -532, - 243, -1719, -2529, 584, -2529, -473, -2529, -482, -2136, -2529, - -2529, -2529, 1165, -698, -2529, 1215, -2529, -2529, -2529, 21, - -2529, -2529, -2529, -2529, -2529, -429, 522, -2250, -2529, 461, - -2529, -2529, -2529, -2529, -74, 229, -2529, 23, 128, -22, - -9, 7, 32, 44, 1465, 1481, -2529, -885, 574, -2529, - -2529, -595, -54, -2529, 636, -1965, -2024, -459, 975, 1437, - 1442, -365, -278, -2529, -442, -2529, -1113, -2529, -2529, 633, - 1016, -1285, -1277, -2529, 340, -431, -364, -2529, -2529, -2529, - -2529, -2529, 92, -451, 1007, -2529, 1470, -2529, -2529, -2529, - -2529, -1245, 688, -1972, 381, -1952, -1837, 148, 137, -1115, - -219, 11, 395, -308, -2529, -2529, -305, -1703, -2297, -322, - -321, -2529, -2529, -478, -1110, -684, -2529, -2529, 366, 708, - -2529, -2529, -2529, 732, 972, -2529, -2529, 1389, 1730, -2529, - -578, 2193, 218, -673, 1178, -1033, 1180, -1072, -829, -988, - 1181, 1183, -1212, 3399, -1549, 1175, -5, -2529, -2313, -1574, - -2529, -2529, -82, -2529, -388, -2529, -387, -2529, -2529, -2529, - -369, -2528, -2529, 1114, 804, -2529, -2529, -1231, -2529, 4152, - 699, -2529, -1608, -556, 1203, -713, -976, -1121, -2529, -2529, - -2529, -2529, -2529, -2529, -1158, -1768, -443, 771, -2529, -2529, - 877, -2529, -2529, -983, -579, 980, -549, -843, 777, -2529, - -551, 1122, -2529, 739, -1851, -2529, 410, -2529, 2053, -520, - 273, -1005, 6, -2529, 3375, 223, 1789, -853, -2076, -2529, - -2529, -485, -2142, -910, -2529, -606, -2529, -2529, -2529, -1168, - -2529, 606, -2529, -1098, -2529, -265, -2529, -2529, -2092, -2529, - -2529, -2529, -2529, -2529, -2529, -436, -2529, -468, -463, -2529, - -2529, 4, -778, 1251, -2529, -2529, 582, -2529, 907, -2529, - 725, -2529, -2529, -2529, 1108, -2529, -2529, -2529, 22, 1542, - 402, -2529, 1116, -2529, -2529, -2529, -2529, -2529, 766, -2529, - -1096, -2497, 73, -2335, -1180, -6, -2529, -2529, -2529, -516, - -2529, -2068 + -2632, -2632, -2632, 1745, -2632, -2632, -2632, 209, -2632, 897, + -2632, 200, -551, 540, -2632, -2632, -2632, -2632, -2632, -2632, + -924, 23, -2632, -2632, -2632, -2632, 11, 260, -2632, -452, + -1864, -192, -2632, -2455, -2527, -2632, -520, -2418, -1688, -2632, + -1101, 174, -2632, -2111, -2632, -619, -979, -783, -990, -2632, + -21, -2632, 1198, -1098, -1772, -2460, -524, -2632, -597, -2632, + -352, -1767, -569, -552, -2632, -2349, -937, -2632, 1409, -254, + -2632, 569, -2632, -2106, -2632, -2632, 558, -2632, -939, -2632, + -2632, -1866, 190, -505, -1881, -2121, 510, -635, -2632, -555, + 236, -1742, -2632, 585, -2632, -489, -2632, -485, -2130, -2632, + -2632, -2632, 1176, -667, -2632, 1225, -2632, -2632, -2632, 27, + -2632, -2632, -2632, -2632, -2632, -776, 523, -2254, -2632, 462, + -2632, -2632, -2632, -2632, -81, 224, -2632, 4, 165, -22, + -10, 2, 21, 41, 1476, 1493, -2632, -553, 538, -2632, + -2632, -1774, -603, -46, -2632, 636, -1363, -1732, -459, 982, + 1451, 1454, -377, -397, -2632, -513, -2632, -1681, -2632, -2632, + 626, 1019, -1256, -1233, -2632, 340, -447, -380, -2632, -2632, + -2632, -2632, -2632, 83, -278, -455, 1001, -2632, 1464, -2632, + -2632, -2632, -2632, -1221, 674, -1997, 365, -1969, -1875, 123, + 114, -1176, -247, 25, 370, -343, -2632, -2632, -340, -1712, + -2303, -357, -356, -2632, -2632, -515, -1120, -685, -2632, -2632, + -431, 1921, -2632, -2632, -2632, 1937, 2080, -2632, -2632, 2151, + 2614, -2632, -571, 2671, 855, -677, 1168, -1084, 1169, -1059, + -1092, -885, 1173, 1174, -1226, 3155, -1516, -819, -5, -2632, + -2329, -1566, -2632, -2632, -111, -2632, -422, -2632, -420, -2632, + -2632, -2632, -401, -2631, -2632, 1106, 792, -2632, -2632, -1252, + -2632, 4058, 685, -2632, -1615, -556, 1195, -719, -986, -1151, + -2632, -2632, -2632, -2632, -2632, -2632, -1614, -1804, -784, 759, + -2632, -2632, 867, -2632, -2632, -1210, -588, 964, -563, -843, + 763, -2632, -550, 1116, -2632, 729, -1920, -2632, 393, -2632, + 2111, -522, 428, -984, 6, -2632, 3528, 1468, 1520, -854, + -2080, -2632, -2632, -482, -2195, -911, -2632, -621, -2632, -2632, + -2632, -1175, -2632, 591, -2632, -1097, -2632, -295, -2632, -2632, + -2112, -2632, -2632, -2632, -2632, -2632, -2632, -398, -2632, -475, + -473, -2632, -2632, 19, -780, 1242, -2632, -2632, 447, -2632, + 892, -2632, 770, -2632, 69, -2632, 1101, -2632, -2632, -2632, + 30, 1532, 384, -2632, 1104, -2632, -2632, -2632, -2632, -2632, + 965, -2632, -1095, -2493, 61, -2322, -1180, -6, -2632, -2632, + -2632, -529, -2632, -2077 }; /* 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 -1713 +#define YYTABLE_NINF -1731 static const yytype_int16 yytable[] = { - 473, 469, 991, 639, 599, 727, 957, 904, 43, 1460, - 1130, 1169, 470, 588, 1236, 794, 1123, 1459, 1289, 1424, - 536, 53, 74, 55, 2057, 927, 1213, 916, 1175, 1216, - 1291, 1491, 60, 1435, 1492, 1494, 1615, 1495, 1229, 725, - 1548, 574, 2108, 1519, 707, 1127, 1336, 733, 60, 1431, - 1413, 601, 569, 990, 1471, 996, 2411, 1000, 1346, 1523, - 2330, 2123, 734, 2125, 2413, 2430, 2429, 602, 788, 2076, - 2284, 1957, 1958, 81, 2104, 2017, 1977, 1464, 586, 2440, - 1575, 2443, 1155, 1156, 1654, 1655, 1245, -700, -441, -1060, - -1035, -700, -1711, -1711, -1491, -703, 2301, -1057, -1057, 617, - 795, 609, -444, 1176, 1727, 1176, -1588, 477, 2607, 1167, - 1771, -1060, 810, -1599, -1691, -1691, -1606, 2004, 2005, -703, - 1774, -1702, -1702, -1061, -1709, -1709, 542, 1416, 56, 1496, - 810, -1058, -1058, 1723, -695, 1300, -1599, -1606, 2603, 950, - -1061, -1588, 2779, 2245, 56, -662, 2163, 953, 650, 2051, - -675, -690, 542, 1131, 1960, 1353, 542, 56, 1176, 1665, - 1665, 578, 1427, 587, 2051, 1306, 2543, 1223, 1350, 1223, - 542, 1176, 810, 1462, 810, 1219, 2587, 810, 542, 2631, - 1341, -441, -917, 1300, 591, 1175, 1686, -1491, 600, -917, - 1591, 917, 1602, 1149, 2706, -444, 1337, 1308, 594, 1436, - 1603, 1604, 1605, 2323, -180, 1300, 56, 2735, 1855, -180, - 2299, 2200, 2202, 1306, 2235, 2674, 2807, 2652, 2746, 3, - 4, -401, 2940, 2570, 1444, 1419, 1939, 1447, 1448, 1589, - 2444, 1427, 2170, 2781, 85, 1306, 2748, 1150, 2782, -1491, - 1155, 1156, 2136, 543, 2764, 1308, 555, 2926, 1702, 596, - 596, 1386, -1491, 1710, -936, 1703, 1777, -1491, 1960, 2911, - 2846, -936, -1491, 595, 2898, 2718, 1167, 1308, 940, 2582, - 592, -1491, 2053, 1960, 1593, -1491, 794, 1753, 2693, 2680, - 1351, 2112, 794, 2749, 499, 1792, 1627, 1792, 528, 1469, - 2331, 2951, 2132, 1443, 2352, 546, 1470, 1387, 2066, 946, - 2697, 2674, 2344, 2292, -1491, 2133, 585, 585, 631, 2365, - 632, 1687, 2862, 1281, 2342, 1458, 1300, 2077, 2500, 2540, - 2731, 2581, 2504, -1491, 82, 1292, 1688, 1237, 2732, 2301, - 1551, 1689, 2462, 2067, 2691, 810, 2293, 1127, -1688, -1688, - 596, 2909, 1793, 2597, 2101, 2212, 1306, 2598, 2341, 556, - 540, 2506, 2332, 1348, 2761, 918, 1388, 919, 2527, 613, - 2295, 1778, 2604, -556, 1754, 2353, 1690, 2920, 83, -441, - 948, 941, -1491, 539, 1421, -1491, 678, 2605, 1308, 1348, - 2338, -1491, 2340, -444, 1449, 2345, 1177, 2445, 1177, 1437, - 2541, 2447, 86, 1711, 2899, 794, 794, 1352, 2888, 2747, - 87, 2783, 1627, 1412, 1389, 2692, 2912, 2947, 1151, 2933, - 2806, 1369, 2216, 2217, 2218, 2219, 2690, 2750, 2223, 2224, - 2225, 2226, 2227, 2228, 2229, 2230, 2231, 2232, 2941, 2631, - -441, 1509, 2694, 1592, 542, 88, -1491, 2794, 651, 2704, - 1474, 1177, 1434, 2490, -444, 2354, 2460, 2952, 1856, 2346, - 1434, 2347, 1615, 910, 1177, 1473, 1572, 2532, 2077, 2803, - 2907, 1342, 2894, 1390, 1906, 2674, 2051, 2082, 2051, 2900, - 2262, 2263, 1787, 1338, 2601, 1771, 2864, 597, 2463, 2297, - 2456, 579, 89, 2544, 2089, 1422, 625, 529, 1258, 1365, - 964, 2036, 1863, 2733, 593, 1463, 965, 1844, 1410, 626, - 629, 627, 1905, 2712, 2078, 2942, 1411, 2411, 2863, 588, - 60, 1691, 1152, 1666, 2019, 2413, 721, 2059, -1491, 541, - 1460, 2602, 1450, 1507, 2083, 793, -1491, 2877, 1123, 2641, - 1451, 2588, 2943, -917, 2645, 790, 1579, 2647, 1178, -441, - 1212, 2632, -1491, 1170, -1491, -1491, 478, 958, 1908, 1910, - 1911, 473, 473, -444, 2674, 2606, 621, 2927, 2149, 2150, - 622, 601, 60, 581, 2137, 1171, 2528, 1170, 1274, 2061, - 1153, -700, 621, -1060, -1035, 473, 622, 602, -441, 1172, - -441, -1491, 2534, 921, -1491, -1491, -1491, 1520, 1521, 1171, - -1588, 1901, -444, 1215, -444, -1060, 1844, -1599, 43, 1704, - -1606, 1516, 966, 1174, 938, -936, 56, -1061, 2545, 1329, - 1295, 53, 74, 55, 1039, 473, 1124, 2621, -695, 2805, - -1599, -1606, 60, 2811, -1061, -1588, 929, 2810, 1975, 1157, - 920, 1725, 1557, 1383, 1161, -690, 1344, 1627, 1627, 589, - 1728, 1436, 1627, 1227, 1228, 1227, 1228, 2531, 2572, 2573, - 1170, 1454, 1324, 1325, 1326, 1327, 1328, 1329, 56, 587, - 1606, 1607, 1608, 81, 1609, 1610, 1611, 1612, 1613, 1614, - 590, 798, 1171, 1577, 2756, 1455, 1326, 1327, 1328, 1329, - -180, -180, 799, 1627, 1627, 707, 1172, 2166, 2719, 721, - 1486, 1740, 1821, 911, 1541, 1576, 1300, 1281, 600, 1662, - 1528, 1583, 1824, 1386, 964, 1827, 794, 1907, 1909, 2591, - 965, 1454, 1577, 1127, 1629, 1631, 2051, 1639, 56, 603, - 2051, 2533, 1615, 2819, 2868, 473, 725, 1540, 604, 1972, - 1973, 1974, 1975, 1544, 1292, 1455, 1384, 1652, 620, 2720, - 719, 1123, 1970, 1971, 1972, 1973, 1974, 1975, 2721, 1387, - 2563, 2820, 967, 1549, 2009, 25, 1436, 1577, 1308, 788, - 1487, 621, 796, 912, 797, 622, 946, 1577, 481, 1127, - 647, 2598, 964, 2109, 2564, 2411, 804, 2722, 965, 1924, - 2010, 2183, 635, 2413, 907, 2683, 793, 2187, 645, 553, - 2249, 30, 793, 1039, 721, 571, 1289, 2214, 1221, 730, - 25, 1222, 968, 1922, 1997, 2220, 969, 1488, 1170, 809, - 473, 648, 1960, 1192, 1193, 1436, 966, -1713, -1713, -1713, - 1890, 2060, 1656, 1668, 652, 2236, 482, 60, 1813, 1820, - 1171, 1437, 32, 2038, 2039, 970, 30, 948, 1460, 473, - 1427, 1912, 2946, 1913, 610, 33, 1915, 2723, 588, 946, - 649, 1428, 1929, 1784, 947, 585, 1389, 1930, 2724, 473, - 473, 473, 964, 473, 473, 2921, 2922, 2147, 965, 34, - 1741, 1879, 1465, 653, 1840, 1841, 1842, 32, 1436, 2889, - 1819, 2890, 2705, 35, 966, 2110, 949, 473, 731, 1497, - 964, 1123, 1434, -487, 2258, 2011, 965, 964, -487, 1830, - 2012, 2083, 971, 965, 1837, 793, 793, 1931, 2080, 800, - 1436, 2138, 2617, 719, 2949, 1390, 1436, 2801, 2051, 1427, - 948, 1196, 1197, 56, 1497, 802, 2785, 2051, 35, 25, - 1430, 1468, 2051, 1377, 1378, 2051, 1382, 25, 473, 1170, - 2171, 2221, 473, 473, 2789, 2178, 1437, 938, 1795, 602, - 602, 2222, 602, 473, 2051, 2938, 1674, 1553, 2087, 1887, - 1261, 1171, 810, 810, -487, 30, 967, 1822, 633, 949, - 634, 721, 1825, 30, 966, 1174, 640, 2547, 1627, 1627, - 1627, 1627, 1675, 803, 1627, 1627, 1627, 1627, 1627, 1627, - 1627, 1627, 1627, 1627, 2135, 486, 1039, 487, 1283, 3, - 4, 2689, 966, 1039, 1461, 1437, 32, 1434, 1862, 966, - 804, 641, 2453, -487, 32, 1232, 994, 805, 719, 33, - 969, 1232, 490, 2634, 1039, 2550, 2139, 33, 2635, 1649, - 909, 1650, 2143, 1159, 967, 967, 1627, 1627, 621, 2013, - 2051, 794, 1347, 34, 90, 2725, 642, 476, 2726, 995, - 2014, 34, 1899, 527, 794, 1168, 1491, 35, 924, 1492, - 1494, 529, 1495, 554, 930, 1742, 1434, 567, 1437, 2736, - 600, 600, 2051, 600, 2841, 640, 1165, 1166, 1639, 1987, - 1639, 1639, 2552, 25, 1966, 1876, 1210, 1877, 969, 2111, - 2112, 1363, 1676, 643, 1364, 915, 1935, 1677, 1615, 1294, - 1437, 2120, 1678, 2122, 1366, 964, 1437, 1367, 1297, 931, - 641, 965, 2599, -1686, -1686, 2007, 971, 970, 2113, 30, - 1545, 1345, 1993, 1367, 967, 933, 2291, 1354, 1124, 1434, - 2055, 2363, 1355, 1928, 1232, 1232, 2473, 1932, 1039, 1933, - 2356, 905, 906, 2196, 908, 2159, 2273, 2274, 2275, 2276, - 1571, 473, 967, 1572, 2031, 2339, 2032, 721, 721, 967, - 32, 1434, 2033, 1573, 2034, 2908, 1574, 1434, 2051, 943, - 2939, 945, 721, 33, 998, 2355, 2791, 2364, 969, 2426, - 2505, 2555, 2508, 621, 971, -1035, 2510, 622, 2923, 2513, - 934, 1986, 643, 1988, 1989, 719, 1159, 34, -1687, -1687, - 937, 2292, 1783, 585, 2051, 1736, 969, 999, 1215, 1828, - 936, 35, 944, 969, 1168, 481, 793, 966, 1782, -1689, - -1689, 1367, 2185, 2186, 2556, 962, 790, 959, 2321, 961, - 710, 963, 1124, 1852, 2293, 970, 1853, -1106, 975, 2557, - 2157, 1679, 1829, 2953, 976, 473, 993, 473, 997, 2294, - 473, 473, 1680, 60, 712, 1132, 625, 1129, 2295, 1128, - 473, 1134, 473, 473, 473, 473, 473, 473, 473, 626, - 629, 627, 1883, 482, 971, 1572, 1136, -1713, -1713, -1713, - 60, 1970, 1971, 1972, 1973, 1974, 1975, 473, 1144, 473, - 1137, 2524, 2296, 2051, 721, 473, 473, 473, 473, 1124, - -1690, -1690, 971, 473, 473, -1692, -1692, 1888, 473, 971, - 1367, 1891, 473, 1557, 1574, 473, 473, 473, 473, 473, - 473, 473, 473, 473, 25, 1897, 473, 484, 1898, 25, - 1918, 473, 1146, 1919, 473, 2558, 473, 1936, 1039, 1148, - 1367, 1124, 2559, 2620, 1943, 1979, 1153, 1367, 1367, 56, - 2001, 2126, 2083, 1367, 2127, 1160, 2130, 2291, 25, 2131, - 30, 473, 1163, 2182, 1157, 30, 1367, 967, 921, 2243, - 2254, 1161, 1215, 1367, 1186, 1187, 56, 2297, 2405, 473, - 1181, 719, 719, 2363, 2319, -1693, -1693, 2320, 473, 473, - 2324, 1164, 2535, 2325, 30, 1744, 719, 1795, 1211, 2343, - 1180, 32, 1853, 710, 2435, 794, 32, 1853, 2454, 1183, - 530, 2455, -1493, 2467, 33, 1214, 2468, 1835, 1577, 33, - 721, 969, 2474, -1694, -1694, 1574, 1124, 712, 1124, 2191, - -1695, -1695, 2292, 2495, 2241, 32, -1696, -1696, 34, 1672, - 1192, 1193, 486, 34, 487, 1217, 2536, 2495, 33, 1853, - 1836, 2537, 35, 1218, 1853, 2622, 2684, 531, 1574, 2685, - 2711, -1697, -1697, 1853, 2208, 2293, 489, 1039, 1220, 490, - 473, 473, 34, 473, 2738, 1248, 2741, 1574, 1627, 2742, - 2294, 2753, 2215, 1238, 1215, 1598, 35, 1251, 1542, 2295, - 1543, 1124, 2758, 2452, 713, 2759, 2762, 1249, 2737, 2759, - 56, 1577, 1253, 2306, 473, -1493, -666, 2237, 710, 473, - 2777, -673, 2816, 2778, 2242, 2778, 2817, 971, 719, 1574, - -1698, -1698, 1256, 2296, 721, 1813, 1257, 2414, 2825, 1880, - 2831, 1215, 712, 2759, 2849, 977, 2878, 2850, 2881, 2879, - 2882, 1215, 2884, 1367, 2642, 1367, 1258, 2915, 1196, 1197, - 2759, 793, 2425, 1259, 978, 2919, 594, -1493, 2767, 2934, - -1699, -1699, 2778, 1260, 793, 35, 1039, 1627, 721, -488, - -1493, -1700, -1700, 473, -488, -1493, 1262, 1729, 473, -556, - -1493, -1701, -1701, -1703, -1703, -1704, -1704, -1705, -1705, -1493, - -1706, -1706, -557, -1493, -1707, -1707, -1708, -1708, -1710, -1710, - 588, -663, 2568, -1712, -1712, 979, 1476, 1477, 2297, 1772, - 1773, -534, -534, -664, 473, 473, 473, 2709, 1263, 473, - 2083, 595, -1493, 1194, 1195, 1196, 1197, 1264, 473, 473, - 473, 473, -538, -538, 56, 1627, 1359, 1361, 473, 1266, - -488, -1493, 473, 1267, 719, 473, -537, -537, 1268, 588, - 1269, -667, 1270, -665, 2408, 1271, 1272, 1273, 1274, 1278, - 473, 473, 1290, 1293, 1340, 473, 1334, 713, 1341, 1342, - 2577, 2578, 1357, 1370, 1376, 947, 949, 2196, 1406, 473, - 1408, 1414, 473, 1432, 473, 710, 1433, 1434, 1439, -488, - -1493, 1788, 1440, -1493, 980, 2643, 1441, 1445, 596, -1493, - 1457, 1796, 1453, 1799, 1452, 473, 1810, 1467, 1472, 712, - 2451, 1479, 1814, 1169, 1816, 1480, 1489, 473, 2049, 1484, - 588, 1490, 1497, 1500, 1498, 1503, 1823, 1127, 1504, 470, - 1506, 1826, 473, 2049, 1510, 1831, 1832, 1833, 1834, 1522, - 1838, 1839, 1577, 981, 470, 625, 473, 1587, 719, 542, - 1283, 982, 810, 1515, -1493, 1524, 1525, 1579, 626, 629, - 627, 473, 1531, 983, 1532, 2522, 1535, 1536, 1537, 60, - 1538, 1584, 713, 1570, 1300, 1644, 1664, 1367, 1646, 473, - 1232, 1682, 1648, 1651, 1927, 1671, 1685, 1683, 1706, 1707, - 1723, 1730, 719, 1232, 984, 471, 1124, 1124, 1124, 1283, - 500, 1737, 1745, 1738, 500, 595, 1752, 1764, 1766, 2036, - 545, 500, 550, 1767, 1785, 550, 1765, 1672, 550, 576, - 1790, 1789, 500, 500, 1791, 596, 1845, 1850, 1854, 2405, - 1858, 1864, 1865, 2026, 1866, 597, -1493, 1039, 1867, 986, - 1886, 1881, 1885, 1889, -1493, 1893, 1894, 1895, 1892, 1917, - 1914, 2043, 1916, 1184, 1185, 1896, 1903, 1904, 1925, 1948, - -1493, 987, -1493, -1493, 1937, 56, 2043, 550, 1953, 721, - 587, 710, 710, 2008, 576, 500, 576, 576, 576, 2024, - 2003, 989, 1945, 1946, 1947, 1949, 710, 1950, 2015, 2576, - 1952, 1956, 1978, 1984, 2025, 712, 712, 1991, 2027, -1493, - 2029, 2053, -1493, -1493, -1493, 2028, 2063, 2065, 2072, 2079, - 712, 715, 2091, 1124, 2085, 793, -539, -540, 2090, 2093, - 2094, 2097, 2095, 1460, 2099, 2100, 2106, 2103, 1186, 1187, - 2119, 2121, 2134, 473, 2144, 2140, 721, 2141, 2142, 794, - 1880, 2145, 473, 2148, 2172, 473, 2176, 2173, 473, 713, - 2146, 2156, 2179, 2168, 721, 473, 473, 473, 473, 2169, - 2180, 473, 473, 473, 473, 473, 473, 473, 473, 473, - 473, 2189, 588, 2268, 473, 473, 2190, 2192, 2199, 721, - 2207, 1960, 1981, 1980, 473, 2256, 721, 2238, 473, 2932, - 1188, 1189, 1190, 1191, 1192, 1193, 2269, 473, 1194, 1195, - 473, 2239, 473, 588, 2036, 2282, 2240, 2257, 710, 721, - 473, 2260, 2290, 473, 473, 2304, 2316, 2308, 473, 473, - 588, 2310, 2313, 2314, 2318, 2322, 2329, 2333, 2337, 2351, - 2349, 2129, 712, 2740, 473, 2049, 473, 2049, 2367, 2428, - 2438, 2433, 2437, 2442, 2448, 56, 470, 473, 470, 2434, - 2450, 2458, 2461, 1853, 2464, 2496, 2492, 473, 2501, 977, - 2502, 2465, 2547, 2687, 2509, 2515, 2516, 2499, 2548, 2466, - 2482, 2517, 2530, 473, 2152, 2788, 2795, 2514, 978, 2493, - 2538, 2549, 2566, 2542, 715, 2584, 2567, 2162, -1057, 2571, - -1686, -1687, -1688, 719, 2585, 977, -1689, 2405, 1558, 2583, - 2593, -1690, 1196, 1197, -1691, 2408, -1692, -1693, -1694, -1695, - 2550, -1696, 2551, 2745, 978, -1697, -1698, -1699, 2594, 2611, - 2595, 1124, 1283, -1700, 1399, 1124, 2412, 1124, 2586, 979, - -1701, 2745, 2608, -1703, 710, 713, 713, 2592, 612, 2615, - 615, 2609, 619, 1559, 1232, -1704, 2618, 2614, -1705, 2197, - 713, 2198, 2175, 1283, -1706, 2203, 2204, 2646, 712, -1707, - 719, -1708, -1709, -1710, 2848, 979, -1711, 2552, 2280, 1560, - 2283, -1712, 2760, -1058, 2619, 2760, 2627, 2666, 719, 2670, - 2676, 2633, 721, 2818, 2651, 2679, 2678, 1561, 2681, 715, - 2686, 1562, 2695, 2698, 2699, 2553, 2700, 2701, 2702, 473, - 2710, 2714, 2446, 719, 2715, 2716, 2739, 2832, 2729, 2834, - 719, 2730, 1563, 1198, 1199, 1564, 2743, 2798, 980, 2767, - 2771, 2751, 2752, 2755, 2763, 2765, 2779, 2774, 2793, 2797, - 1565, 2359, 2799, 719, 2812, 2828, 2813, 2814, 710, 2824, - 2802, 2833, 2836, 2905, 2788, 473, 473, 964, 2837, 2838, - 473, 721, 716, 965, 980, 473, 2847, 2851, 473, 473, - 977, 2554, 712, 473, 2694, 2856, 2555, 981, 576, 2853, - 2854, 2860, 713, 2859, 637, 982, 2861, 638, 2865, 978, - 2866, 576, 710, 2867, 473, 2049, 500, 983, 473, 2049, - 2895, 2876, 2880, 2270, 2843, 2901, 470, 2910, 2916, 2917, - 470, 2928, 2925, 981, 2935, 2930, 712, 56, 2937, 2556, - 473, 982, 2927, 638, 500, 500, 2936, 2926, 984, 1566, - 2948, 2950, 2954, 983, 2557, 2366, 1815, 1567, 935, 2117, - 979, 2370, 2526, 2326, 2842, 2669, 2891, 2574, 2436, 2897, - 2945, 2523, 2525, 1124, 2792, 2931, 902, 902, 550, 550, - 719, 550, 473, 2924, 984, 2410, 2728, 2124, 2441, 966, - 1423, 721, 576, 986, 2102, 2153, 715, 2893, 2335, 1568, - 2929, 500, 2098, 2408, 2371, 2892, 1539, 2152, 1518, 2154, - 2193, 2616, 576, 2427, 1349, 987, 1781, 2827, 2081, 1403, - 2773, 2412, 2368, 1402, 576, 1368, 2887, 2312, 713, 986, - 2092, 1761, 2883, 2835, 2520, 989, 719, 2415, 2416, 2417, - 2418, 2419, 2420, 2421, 2422, 2423, 2424, 1780, 2043, 980, - 2558, 987, 2043, 2285, 1407, 716, 2062, 2559, 2757, 2491, - 576, 576, 576, 2507, 2823, 2281, 2822, 2829, 2668, 2830, - 1588, 989, 1590, 1594, 1624, 1595, 56, 56, 2885, 793, - 2886, 2875, 1712, 1999, 2084, 473, 1578, 1940, 721, 1849, - 2022, 2600, 473, 2020, 1722, 2056, 2311, 2158, 981, 2815, - 473, 473, 1732, 1550, 473, 719, 982, 1934, 1371, 0, - 2327, 1734, 0, 0, 0, 0, 473, 2049, 983, 0, - 0, 0, 0, 0, 0, 473, 2049, 0, 470, 0, - 473, 2049, 713, 473, 2049, 0, 0, 470, 0, 967, - 473, 473, 470, 0, 0, 470, 0, 0, 0, 984, - 0, 0, 473, 2049, 473, 0, 0, 0, 0, 0, - 716, 0, 630, 2519, 470, 0, 2521, 0, 0, 0, - 0, 0, 0, 0, 473, 644, 713, 0, 0, 0, - 0, 0, 715, 715, 0, 0, 0, 0, 0, 985, - 1763, 480, 0, 969, 986, 481, 56, 715, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2412, 0, 0, - 0, 0, 0, 710, 0, 719, 987, -1106, 0, 0, - 0, 0, 988, 1250, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 989, 712, 473, 2049, - 0, 0, 473, 721, 0, 719, 2713, 0, 0, 0, - 470, 0, 0, 482, 0, 0, 914, 0, 0, 2043, - 483, 0, 0, 0, 2043, 588, 473, 2043, 2600, 0, - 473, 2049, 0, 0, 721, 0, 0, 721, 0, 0, - 710, 473, 470, 0, 0, 0, 0, 2596, 960, 971, - 1288, 0, 0, 0, 0, 473, 0, 0, 710, 0, - 0, 0, 0, 0, 712, 1124, 0, 484, 1232, 1124, - 473, 0, 719, 0, 0, 0, 0, 0, 0, 715, - 0, -453, 712, 710, 1139, 1141, 1143, 0, 0, 0, - 710, 0, 576, 0, -453, 0, 0, 716, 0, -453, - 0, 0, 0, 0, 0, 718, 0, 712, 0, 500, - 500, 56, 0, 710, 712, 576, 576, 1375, 0, 0, - 0, 0, 0, 473, 0, 0, 473, 2049, 2809, 0, - 0, 0, 0, 56, 0, 485, 0, 712, 470, 0, - 0, 0, 576, 1426, 0, 0, -453, 473, 0, 473, - 0, 473, 0, 0, 0, 576, 0, 0, 0, 0, - 0, 0, 473, 2049, 2043, -453, 0, 0, 0, 0, - 0, 0, 576, 0, 470, 1283, 576, 0, 0, 0, - 0, 0, 486, 473, 487, 1624, 1624, 2839, 0, 0, - 1624, 719, 0, 0, 0, 0, 2410, 0, 0, 0, - 488, 0, 0, 473, 473, 715, 489, 0, 0, 490, - 0, 0, 2688, 0, -453, 0, 0, 473, 0, 0, - 0, 0, 0, -453, -1507, 0, 0, 719, 0, 0, - 710, 1624, 1624, 56, 1124, 2412, 0, 713, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2707, 2708, 0, - 0, 473, 2049, 473, 712, 0, 0, 0, 719, 0, - 0, 719, 2717, 470, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2906, 0, 0, 0, 0, 718, 0, - 0, 0, 0, 716, 716, 0, 710, 0, 0, 0, - 0, 0, 56, 0, 0, 0, 0, 0, 716, 0, - 0, 0, 0, 0, 713, 0, 0, 0, 1483, 715, - 712, 0, 0, 0, 0, 0, 576, -1507, 0, 473, - 0, 0, 713, 2804, 0, 0, 1513, 0, 0, 0, - 0, 0, 0, 2775, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 713, 0, 0, - 0, 0, 0, 715, 713, 710, 1362, 0, 0, 1530, - -453, 2796, 0, 809, 0, 0, 1960, 0, 0, -1507, - 0, 1961, 1962, 1963, 0, 0, 0, 713, 56, 712, - 1373, 0, -1507, 718, 0, 0, 0, -1507, 2251, 0, - 638, 638, -1507, 500, 500, 0, 500, 638, 0, 576, - 0, -1507, 0, 0, 0, -1507, 1415, 0, 0, 0, - 0, 0, 0, 0, 1299, 0, 0, 1300, 0, 1442, - 716, 0, 0, 621, 0, 0, 933, 622, 0, 0, - 0, 0, 0, 0, -1507, 0, 0, 0, 0, 0, - 1466, 0, 0, 0, 0, 0, 1617, 1306, 0, 0, - 0, 0, 0, -1507, -1713, 0, 0, 1643, 0, 719, - 0, 0, 0, 0, 2410, 710, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1308, - 0, 0, 0, 0, 0, 0, 0, 638, 0, 712, - 0, 0, 0, 0, 713, 710, 0, 0, 0, 0, - 0, 0, -1507, 0, 0, -1507, 0, 0, 0, 0, - 0, -1507, 0, 0, 0, 0, 0, 0, 0, 712, - 576, 902, 0, 0, 0, 0, 1624, 1624, 1624, 1624, - 0, 0, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, - 1624, 1624, 576, 0, 576, 0, 716, 0, 1299, 2006, - 713, 1300, 0, 1746, 0, 1751, 1301, 1302, 1303, 0, - 718, 0, 710, 0, 0, 0, -1507, 0, 0, 1965, - 0, 0, 0, 0, 0, 0, 0, 0, 0, -1713, - 1499, 1306, 0, 0, 1624, 1624, 712, 576, 1307, 0, - 0, 0, 0, 0, -1713, 0, 1426, 500, 0, -1713, - 0, 0, 0, 0, 0, 0, 0, 500, 1797, 500, - 1801, 0, 500, 1308, 0, 0, 0, 0, 500, 713, - 500, 2036, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 638, 500, 0, -1713, 0, 638, 500, 1966, 0, - 0, 500, 500, 500, 500, 0, 500, 500, -1507, 0, - 716, 0, 0, 0, 715, 0, -1507, 0, 0, 0, - 0, 0, 0, 1547, 0, 0, 576, 576, 1861, 0, - 0, 0, -1507, 0, -1507, -1507, 0, 0, 0, 0, - 0, 710, 0, 1875, 0, 0, 0, 0, 0, 1317, - 0, 0, 0, 809, 716, 0, 1960, 0, 0, 0, - 0, 1961, 1962, 1963, 0, 712, 0, 0, 0, 0, - 0, -1507, 0, 1309, -1507, -1507, -1507, 710, 0, 0, - 0, 715, 0, 0, 0, 0, 0, 1299, 1310, 713, - 1300, 0, 0, 1311, 0, 1301, 1302, 1303, 0, 715, - 0, 712, 0, 0, 0, 0, 718, 718, 710, 0, - 0, 710, 1304, 0, -1713, -1713, 0, 0, 0, 713, - 1306, 718, 0, 0, 715, 0, 0, 1307, 1314, 0, - 0, 715, 712, 0, 0, 712, 0, 0, 0, -1713, - 0, 0, 0, 0, 1721, 0, 0, 0, 0, 0, - 0, 0, 1308, 809, 715, 0, 1960, 0, 0, 0, - 0, 1961, 1962, 1963, 0, 0, 1731, 0, 1733, -1713, - 0, 0, 0, 0, 0, 0, 0, 0, 2252, 0, - 0, 500, 0, 1317, 0, 0, 713, 0, 1288, 0, - 0, 1967, 1968, 1969, 0, 1970, 1971, 1972, 1973, 1974, - 1975, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1776, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1617, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1964, -1713, - 0, 0, 0, 718, 0, 0, 1324, 1325, 1326, 1327, - 1328, 1329, 1309, 0, 0, 576, 0, 0, 0, 1965, - 0, 0, 2052, 0, 0, 0, 0, 1310, 0, 0, - 0, 715, 1311, 1319, 0, 0, 0, 2052, 0, 1299, - 0, 2071, 1300, 0, 2074, 0, 1751, 1301, 1302, 1303, - 1859, 1860, 0, 1312, 1313, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1304, 713, 0, 1314, 809, 710, - 0, 1960, 1306, 0, 0, 0, 1961, 1962, 1963, 1307, - 0, 0, 0, 0, 0, 0, 809, 715, 1966, 1960, - 0, 0, 1483, 712, 1961, 1962, 1963, 0, 0, 0, - 0, 713, 0, 0, 1308, 1315, 0, 0, 1316, 0, - 0, 2476, 0, 0, 0, 716, 0, 0, 0, 1965, - 0, 0, 1317, 0, 0, 1318, 0, 0, 0, 718, - 0, 0, 713, 1320, 0, 713, 1321, 1322, 1323, 0, - 1324, 1325, 1326, 1327, 1328, 1329, 1624, 0, 0, 0, - 0, 0, 1483, 0, 0, 0, 715, 576, 0, 0, - 0, 0, 0, 0, 1483, 576, 576, 576, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 500, 0, - 0, 0, 716, 0, 0, 576, 0, 0, 1966, 0, - 0, 0, 0, 0, 0, 0, 0, 2188, 0, 0, - 716, 0, 0, 0, 1309, 0, 0, 0, 0, 0, - 0, 0, 1319, 638, 0, 0, 0, 0, 0, 1310, - 0, 0, 0, 0, 1311, 716, 0, 0, 0, 1483, - 1483, 0, 716, 718, 0, 1624, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1312, 1313, 0, 0, 0, - 0, 0, 1617, 0, 0, 716, 0, 0, 0, 1314, - 0, 0, 0, 0, 0, 0, 715, 0, 0, 0, - 0, 0, 0, 0, 1965, 0, 0, 718, 0, 2035, - 0, 1967, 1968, 1969, 0, 1970, 1971, 1972, 1973, 1974, - 1975, 0, 1965, 0, 0, 0, 715, 1315, 0, 0, - 1316, 0, 0, 1624, 0, 0, 0, 0, 0, 0, - 0, 0, 1320, 0, 1317, 1321, 1322, 1323, 0, 1324, - 1325, 1326, 1327, 1328, 1329, 0, 0, 0, 2272, 0, - 0, 0, 1951, 713, 0, 0, 576, 576, 576, 471, - 0, 2052, 2289, 1966, 0, 0, 2289, 2303, 0, 0, + 477, 473, 1139, 999, 56, 965, 801, 734, 1132, 1473, + 646, 714, 474, 606, 595, 912, 1238, 1178, 1472, 1245, + 924, 61, 1532, 44, 1628, 1298, 1768, 54, 2077, 1771, + 75, 1184, 935, 1437, 576, 540, 2103, 61, 1300, 2108, + 1448, 1504, 2130, 1136, 1505, 1507, 732, 1508, 740, 1561, + 1444, 608, 1484, 2145, 1345, 2147, 581, 1426, 1536, 741, + 2457, 82, 795, 609, 1222, 2309, 1355, 1225, 1640, 2126, + 2458, 998, 2096, 1004, 2436, 1008, 593, 2438, 1477, 1667, + 1668, 2037, 1588, 616, 2166, 2167, 2168, 2468, 1254, 2471, + 551, -441, -715, -707, 2270, -715, 1164, 1165, -1047, 2326, + 1309, -444, -1072, -712, -1606, 547, 481, -712, -1072, 818, + -1069, -1069, -1709, -1709, 624, 818, 1980, 1977, 1978, 2631, + -1617, -1617, 1997, 1176, -1624, -1624, 1185, -1073, -1720, -1720, + 1315, -1073, -1727, -1727, 1362, -1070, -1070, 1740, 1412, 2811, + -1606, -674, 802, 2188, -687, -702, 958, 547, 547, 2635, + 961, 2737, 1789, 1350, 547, 1440, 1736, 1140, 657, 1509, + -1729, -1729, 1317, 2024, 2025, 57, 1475, 1359, 1232, 547, + 2071, 1232, 1678, 818, 2571, 918, 818, 1792, 818, 1605, + 1429, 57, 1228, 585, -441, 2071, 1640, 1602, -180, 1184, + 1678, 2659, 2324, -180, -444, 57, 1185, 598, 2260, 1440, + 2615, 594, 925, 1457, 1158, 1309, 1460, 1461, 2225, 2227, + 2158, 1185, 1604, -929, 2976, 1715, -948, 1185, 1346, 2195, + -929, 1699, 1716, -948, 2767, 2778, 607, 2705, 1397, 2348, + 3, 4, 2632, 603, 2814, 1315, 2555, 2962, 2472, 2680, + 2933, 2610, 1309, 1168, 57, 603, 1959, 2633, 1159, -401, + 2724, 2813, 2839, 544, 2598, 1164, 1165, 562, 1795, 2367, + 2987, 1462, -1706, -1706, 1875, 1177, 2946, 1317, 2796, 543, + 801, 2780, 1315, 2944, 1398, 1810, 2317, 801, 1432, 1360, + 2763, 1176, 1499, 1863, 599, 2354, 2881, 83, 2764, 601, + 2086, 1482, 1309, 1765, 1201, 1202, 1219, 1394, 1483, 2568, + 1456, 2335, 1810, 546, 1317, 1467, 2750, 2377, 1309, 954, + 2318, 2154, 2073, 2705, 647, 2629, 2722, 2134, 2528, 1301, + 2781, 1290, 2532, 1564, 2155, 2087, 2534, 1246, 818, 1468, + 806, 84, 1811, 26, 1399, 2320, 1136, 2326, 1315, 2475, + 2983, 807, 2609, 596, 2626, 2390, 1700, 1357, 2897, 2355, + 648, 2625, 2366, 1500, 1317, 588, 602, 2097, 2237, 2123, + 563, 2239, 1701, 2630, 1980, 1796, 926, 1702, 927, 31, + 1317, 2569, 2934, 1357, -441, 2357, 2793, 685, 2378, 2363, + 1766, 2365, 956, 1400, -444, 649, 1606, -566, 2723, 2261, + 801, 801, 638, 545, 639, 2838, 2956, 2473, 1361, 2815, + 1501, 1463, 1395, 1703, 1205, 1206, 2725, 1168, 2779, 1464, + 33, 1425, 1267, 1186, 2735, 2947, 1980, 1378, 2988, 919, + 2923, 1160, 2977, 1640, 1640, 1177, 2929, 2634, 1640, 1434, + 2518, 1447, 650, 603, 1522, 2488, 1351, -441, 1864, 503, + 1487, 1486, 1401, 532, 1628, 2659, 2556, -444, 2969, 2935, + 2721, 553, 658, 1585, 2782, 2765, 2322, 1927, 1929, 1637, + 2379, 36, 592, 592, 1925, 2241, 2242, 2243, 2244, 1640, + 1640, 2248, 2249, 2250, 2251, 2252, 2253, 2254, 2255, 2256, + 2257, 2705, 2484, 1186, 2942, 2097, 634, 2835, 2560, 920, + 1926, 1805, 1476, 2898, 2071, 2572, 2071, 1347, 1186, 1449, + 1862, 2978, 812, 61, 1186, 632, 1423, 586, 1876, 633, + 1424, 600, 636, 595, 2744, 620, 2079, 1520, 2106, 1789, + 728, 2899, 1132, 2287, 2288, 1473, 1883, 1161, 2979, 800, + 1679, 2436, 2669, 1162, 2438, 1374, 2159, 2673, 2174, 2175, + 2675, 2098, 1435, 2111, 1179, 1449, -441, 1179, 2039, 482, + 1704, 2963, 2660, 2912, 797, 61, -444, 628, 477, 477, + 1592, 629, 966, 2616, 610, 1187, 1180, 608, -929, 1180, + 1717, -948, 604, 2705, 2490, 2081, 2649, 1778, 1338, 609, + 1181, -707, 477, 1183, 628, -441, -1047, -441, 629, 2562, + -1072, -712, -1606, 1304, 1995, -444, -1072, -444, 1921, 1862, + 2316, 56, 2245, 1533, 1534, 929, 597, 2573, -1617, -1617, + 1529, 1723, -1624, -1624, 804, -1073, 611, 1471, 61, -1073, + 44, 1047, 477, 1133, 54, 946, 1570, 75, -1606, 1166, + 937, 2837, 1170, -702, 1738, 1353, 1741, 2591, 2843, 1467, + 1283, 948, 2842, 2538, 642, 928, 2541, 57, 1236, 1237, + 1221, 1236, 1237, 2600, 2601, 1949, 1224, 714, 82, 2851, + 1950, 2592, 2559, 1468, 1928, 1930, 1931, 485, -180, -180, + 1753, 2736, 1541, 1590, 1440, 2317, 1839, 2788, 1510, 2614, + 1335, 1336, 1337, 1338, 2711, 1441, 1842, 1440, 2852, 1845, + 1566, 1450, 1899, 1675, 1449, 818, 728, 1397, 1443, 57, + 594, 1554, 801, 2751, 1589, 2728, 1290, 2191, 1179, 2318, + 1596, 1951, 1590, 1136, 2619, 1333, 1334, 1335, 1336, 1337, + 1338, 1628, 2491, 1642, 1644, 2319, 1652, 486, 2109, 1301, + 1180, 627, 477, 818, 2320, 1132, 2903, 1450, 732, 1553, + 2246, 2561, 607, 1398, 949, 1557, 1665, 652, 2369, 2071, + 2247, 1724, 1447, 2071, 2752, 1562, 817, 1590, 795, 1980, + 655, 954, 57, 2753, -1731, -1731, -1731, 1590, 2321, 1136, + 1449, 1640, 1640, 1640, 1640, 2626, 656, 1640, 1640, 1640, + 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1942, 1179, 2670, + 1944, 2208, 2754, 800, 1669, 2714, 2274, 2212, 1447, 1948, + 800, 1047, 728, 1952, 2131, 1953, 2436, 628, 1298, 2438, + 1180, 629, 1478, 1308, 1637, 1637, 1309, 2017, 477, 1637, + 1449, 2833, 1230, 61, 1181, 1231, 1831, 1449, 1510, 1640, + 1640, 659, 2370, 2080, 956, 1681, 1838, 1990, 1991, 1992, + 1993, 1994, 1995, 660, 2662, 2826, 1315, 477, 1473, 2663, + 738, 1754, 1400, -1731, 954, 2322, 595, 1449, 2982, 955, + 1637, 1637, 2755, 2006, 1910, 2008, 2009, 477, 477, 477, + 972, 477, 477, 808, 2756, 2169, 973, 1802, 1317, 1858, + 1859, 1860, 547, 957, 2283, 1932, 1450, 1933, 1481, 1132, + 1935, 1992, 1993, 1994, 1995, 477, 985, 2371, 490, 2372, + 491, 810, 2106, 1372, 1837, 86, 1373, -490, 26, 811, + 2029, 1401, -490, 800, 800, 986, 2132, -453, -1704, -1704, + 26, 2100, 2160, 1848, 1813, 494, 812, 956, 1855, 654, + -453, 3, 4, 628, 813, -453, 2030, 1356, 2157, 2817, + 1386, 1387, 2671, 1393, 31, 2161, 477, 1447, 2026, 2821, + 477, 477, 609, 609, 2071, 609, 31, 917, 737, 2196, + 647, 477, 1450, 2071, 2203, 1179, 987, 57, 2071, 946, + 923, 2071, 1907, 2645, 1375, 2165, 957, 1376, -1731, 728, + -490, 932, 974, 1840, -453, 33, 938, 1180, 1843, 560, + 2071, 1174, 1175, 533, -1731, 578, 648, 33, 34, -1731, + 972, 1183, 939, -453, 1047, 1270, 973, 640, 941, 641, + 34, 1047, 1450, 913, 914, 942, 916, 592, 1882, 1450, + 944, 1558, 35, 1447, 1376, 533, 1474, 1584, 1919, -490, + 1585, 2184, 1047, 1986, 35, -1731, 36, 2481, 628, 945, + -1047, 801, 629, 1292, 617, -1705, -1705, 1586, 1755, 1450, + 1587, 952, -453, 2031, 801, 967, 988, 1749, 2032, 969, + 1224, -453, 2720, 1662, 2757, 1663, 87, 2758, 975, 2051, + 971, 2052, 1955, 1447, 88, 972, 2071, 1896, 650, 1897, + 1447, 973, 1504, 970, 1800, 1505, 1507, 1376, 1508, 972, + 1326, 1652, 2007, 1652, 1652, 973, 983, 2876, 1872, 972, + 1903, 1873, 984, 1585, 1628, 973, 989, 1001, 2071, 89, + 1447, 2053, 974, 2054, 990, 607, 607, 1908, 607, 1911, + 1376, 1917, 1587, 2133, 1918, 2134, 991, 1137, 2027, 1938, + 2768, 2501, 1939, 2013, 975, 2075, 1956, 1133, 1963, 1376, + 951, 1376, 953, 972, 2533, 2388, 2536, 1047, 1999, 973, + 2142, 1376, 2144, 2135, 1005, 2381, 90, 992, -1707, -1707, + 477, 2221, 1637, 1637, 1637, 1637, 728, 728, 1637, 1637, + 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 2058, 2059, + 1138, 728, -1731, 2364, 1143, 976, 1141, 974, 2975, 977, + 1145, 2943, 2957, 2958, -1708, -1708, 2380, 2454, 2389, 2033, + -453, 974, 1146, 91, 994, 1153, 480, 1155, 2071, 1157, + 2034, 974, 531, 2021, 2959, 1166, 1376, 1172, 2627, 978, + 1637, 1637, 1162, 561, 1169, 800, 995, 574, -1731, -1731, + -1731, 1170, 1990, 1991, 1992, 1993, 1994, 1995, 2210, 2211, + 2148, 1133, 2985, 2149, 2071, 2182, 997, 1190, 2346, 2152, + 797, 61, 2153, 1173, 477, 974, 477, -1710, -1710, 477, + 477, 634, 1189, 628, 975, 26, 941, 629, 1192, 477, + 2989, 477, 477, 477, 477, 477, 477, 477, 61, 1640, + 632, 1220, -1731, 1687, 633, 2207, 979, 636, 1376, 1333, + 1334, 1335, 1336, 1337, 1338, 1227, 477, 26, 477, -1711, + -1711, 31, 1223, 728, 477, 477, 477, 477, 1133, 1688, + 1226, 2268, 477, 477, 1224, 1002, 1229, 477, 1570, 977, + 2279, 477, 1247, 1376, 477, 477, 477, 477, 477, 477, + 477, 477, 477, 31, 1257, 477, 2071, -1712, -1712, 975, + 477, 2648, 33, 477, 1258, 477, 534, 1047, 2344, 1003, + 1133, 2345, 1260, 975, 2968, 34, -678, 2349, 2368, 2106, + 2350, 1873, 2463, 975, 1262, 1873, 592, 972, 1640, -685, + 477, 2430, 2575, 973, 33, 2482, -1713, -1713, 2483, 35, + 1813, 726, 1267, 2495, 1265, 1757, 2496, 34, 2502, 1266, + 477, 1587, 929, 535, 977, 57, 2564, -1714, -1714, 1873, + 2388, 477, 477, 2565, 1006, -675, 1873, 975, 977, -676, + 2650, 35, 801, 1587, 1801, 1268, 979, 1269, 977, 36, + 2578, 1689, 57, 2563, 978, 36, 1690, 2715, 1271, 1590, + 2716, 1691, 2743, 728, 26, 1873, 1640, 2770, 1007, 1133, + 1587, 1133, 2773, 2785, -566, 2774, 1224, 2233, 978, -679, + 2790, 1615, 2216, 2791, 2266, -1715, -1715, 2523, 1846, 1616, + 1617, 1618, 977, 2794, 2809, 2240, 2791, 2810, -677, 2848, + 31, 2523, 2810, 2849, 1287, 2857, 1587, 2580, 1224, 974, + 1047, 1790, 1791, 477, 477, 1685, 477, -567, 548, 548, + 2262, 979, 1847, -1716, -1716, 1272, 2769, 2267, 2298, 2299, + 2300, 2301, 1195, 1196, 1133, 979, 1299, 2863, 1273, 2331, + 2791, 33, 1590, -1717, -1717, 979, 2924, 477, 2925, 2575, + -1718, -1718, 477, 1900, 34, 2576, 475, 2884, -1719, -1719, + 2885, 504, 1831, 2913, 2439, 504, 2914, 728, 2577, 1275, + 549, 549, 552, 504, 557, 1343, 57, 557, 35, 2480, + 557, 583, 1349, 2916, 504, 504, 1224, 726, 2917, 979, + 1350, 1376, 36, 1276, 800, 2919, 2453, 2578, 1376, 2579, + 1201, 1202, 1692, 2823, -1721, -1721, 1277, 800, 2583, 1047, + 485, 728, 2950, 1693, 2954, 2791, 477, 2799, 1351, 2970, + 1278, 477, 2810, 2974, -1722, -1722, -1723, -1723, 2596, 557, + -1724, -1724, 2552, -1118, -1725, -1725, 583, 504, 583, 583, + 583, -1726, -1726, 595, -1728, -1728, -1730, -1730, 1489, 1490, + 1279, 2584, -542, -542, 2580, 1203, 1204, 477, 477, 477, + 1280, 975, 477, 1281, 2106, 2316, 1282, 2585, 2741, 2433, + 486, 477, 477, 477, 477, 1205, 1206, -546, -546, -545, + -545, 477, 1555, 2581, 1556, 477, 1283, 817, 477, 1302, + 1980, 1366, 595, 726, 1379, 1981, 1982, 1983, 955, 1385, + 1637, 26, 957, 477, 477, 1419, 26, 1421, 477, 1427, + 1205, 1206, 1853, 1445, 57, 1446, 977, 1447, 601, 1368, + 1370, 1454, 477, 1452, 488, 477, 1453, 477, 2479, 1458, + 1465, -491, 1466, 2221, 1470, 1480, -491, 31, 1485, 1492, + 2317, 1493, 31, 1497, 817, 1502, 1854, 1980, 477, 1503, + 2582, 1510, 1981, 1982, 1983, 2583, 2605, 2606, 2105, 1513, + 477, 2069, 1511, 595, 2586, 1516, 1571, 1178, 1517, 2276, + 1519, 2587, 474, 1136, 2318, 477, 2069, 1523, 33, 1528, + 818, 1535, 1537, 33, 634, 602, 1544, 474, 1590, 1637, + 2319, 34, 1538, 477, 1583, 1545, 34, 1548, 2584, 2320, + 1549, 61, 1363, 632, -491, 1597, 1592, 633, 477, 477, + 636, 1572, 1550, 979, 2585, 35, 1551, 1309, 1657, 1376, + 35, 2550, 1659, 1664, 1695, 1677, 1684, 477, 1661, 36, + 1292, 1696, 1698, 2321, 36, 1736, 1719, 1573, 1743, 1720, + 1750, 490, 1751, 491, 1133, 1133, 1133, 1758, 602, 1769, + 1780, 1779, 1781, -491, 1782, 1574, 1784, 1637, 2430, 1575, + 1783, 1803, 603, 1807, 1808, 493, 1809, 603, 494, 1870, + 726, 1874, 1878, 1984, 1886, 1887, 1884, 1885, 1901, 1292, + 1576, 1906, 1905, 1577, 1909, 1047, 1912, 1913, 1914, 1806, + 1915, 1916, 1923, 1934, 1936, 1985, 1924, 1685, 1578, 1814, + 1937, 1817, 1945, 1965, 1828, 1957, 1968, 2604, 2028, 2035, + 1832, 2586, 1834, 2046, 1973, 1966, 2023, 2044, 2587, 728, + 2322, 1967, 1969, 2073, 1841, 1970, 1972, 1976, 2045, 1844, + 2047, 2063, 1998, 1849, 1850, 1851, 1852, 2004, 1856, 1857, + 2011, 2048, 2049, 2085, 2083, 57, 2063, 2092, 2099, -547, + 594, 2113, 1985, 1619, 1620, 1621, -548, 1622, 1623, 1624, + 1625, 1626, 1627, 1133, 1986, 800, 2101, 2112, 2116, 2117, + 2119, 1900, 2121, 2122, 2115, 2125, 2128, 2141, 2143, 2170, + 1473, 2156, 2162, 477, 801, 2171, 728, 2163, 2164, 1579, + 2172, 2173, 477, 2181, 2197, 477, 2193, 1580, 477, 2201, + 2194, 604, 2198, 2205, 728, 477, 477, 477, 477, 2204, + 2214, 477, 477, 477, 477, 477, 477, 477, 477, 477, + 477, 1986, 595, 2215, 477, 477, 2217, 2224, 2232, 728, + 2001, 2293, 1980, 583, 477, 2000, 728, 2263, 477, 644, + 1581, 803, 645, 548, 805, 2281, 583, 477, 2264, 2282, + 477, 504, 477, 595, 2265, 2285, 2294, 726, 726, 728, + 477, 2056, 2307, 477, 477, 2329, 915, 2333, 477, 477, + 595, 2315, 726, 985, 2338, 2339, 2341, 2347, 645, 504, + 504, 2343, 2356, 2772, 477, 2069, 477, 2069, 2358, 2362, + 2374, 2376, 986, 2392, 2450, 549, 474, 477, 474, 2451, + 2452, 2456, 2466, 2461, 2462, 2465, 2470, 477, 2478, 2476, + 2489, 2492, 985, 2486, 910, 910, 557, 557, 2493, 557, + 1873, 2820, 2827, 477, 2718, 2520, 2433, 2529, 2494, 2524, + 583, 986, 57, 2430, 2530, 2510, 2521, 2527, 2542, 504, + 2537, 2543, 2544, 987, 2545, 2547, 2566, 2570, 2558, 2594, + 583, 2595, 2599, 2611, 2612, 2613, -1069, -1704, -1705, 1987, + 1988, 1989, 583, 1990, 1991, 1992, 1993, 1994, 1995, 2777, + 2621, 2622, -1706, 1133, 2636, 2623, -1707, 1133, 2437, 1133, + -1708, -1709, 987, -1710, 2639, -1711, 2620, 2777, -1712, -1713, + -1714, -1715, -1716, 2792, 726, -1717, 2792, 2643, 583, 583, + 583, -1718, -1719, 1308, -1721, 2637, 1309, -1722, 2646, 1292, + -1723, 2883, -1724, -1725, 2642, -1726, 1987, 1988, 1989, 2655, + 1990, 1991, 1992, 1993, 1994, 1995, -1727, 619, -1728, 622, + -1729, 626, -1730, 988, -1070, 2674, 1315, 728, 2474, 2696, + 1292, 2647, 2661, -1731, 2679, 2850, 2701, 2707, 2384, 2709, + 2710, 2712, 2717, 2726, 477, 2305, 2729, 2308, 2730, 2731, + 2733, 2732, 2740, 2746, 2742, 2747, 2748, 2761, 1317, 2864, + 817, 2866, 988, 1980, 2762, 2771, 2775, 2783, 1981, 1982, + 1983, 2830, 2784, 989, 2787, 2795, 2797, 1308, 2803, 2806, + 1309, 990, 2799, 2811, 2820, 2860, 2825, 1241, 2829, 2831, + 477, 477, 2940, 991, 1241, 477, 728, 2834, 2844, 2845, + 477, 2846, 2856, 477, 477, 2865, 2869, 2868, 477, 2871, + 1315, 2882, 989, 2886, 726, 2725, 2888, -1731, 2889, 2891, + 990, 2895, 2894, 2896, 992, 2900, 2901, 2902, 2036, 477, + 2069, 2911, 991, 477, 2069, 2922, 2915, 2295, 2930, 2945, + 2951, 474, 1317, 2936, 2952, 474, 2961, 2200, 2964, 2878, + 2966, 2971, 1259, 2972, 2973, 477, 2962, 2963, -1731, 2984, + 972, 2986, 943, 992, 2990, 2391, 973, 2551, 2553, 2395, + 1833, 994, 1303, 985, -1731, 2139, 2554, 2351, 2877, -1731, + 2700, 1306, 2926, 2464, 2932, 2602, 2981, 2824, 1133, 57, + 2967, 2433, 986, 995, 1354, 2960, 2760, 477, 2124, 2146, + 2928, 1436, 2965, 2178, 2469, 1364, 728, 1241, 1241, 2396, + 994, 2120, 2286, 997, 2927, -1731, 1552, 1531, 726, 1297, + 2179, 2218, 2644, 2455, 1358, 2104, 1799, 2859, 2873, 2955, + 2114, 1416, 995, 1415, 1377, 1776, 2437, 2337, 2918, 2867, + 2548, 2805, -1731, 987, 1798, 2082, 1420, 2310, 2789, 2519, + 2306, 2855, 997, 2854, 2861, 2535, 2862, 2699, -1731, 1601, + 1603, 583, 726, -1731, 1607, 1608, 2920, 717, 1985, 2921, + 1326, 2910, 974, 1725, 2019, 2107, 1869, 1591, 504, 504, + 1960, 2042, 2040, 719, 583, 583, 1384, 1735, 2076, 2336, + 2628, 2847, 2183, 1563, 1745, 1954, 1380, 800, 1747, -1731, + 2063, 0, 2352, 477, 2063, 0, 728, 0, 0, 0, + 477, 583, 1439, 0, 0, 0, 0, 0, 477, 477, + 0, 0, 477, 0, 583, 0, 0, 0, 57, 57, + 0, 0, 0, 988, 477, 2069, 0, 1986, 0, 0, + 0, 583, 0, 477, 2069, 583, 474, 0, 477, 2069, + 0, 477, 2069, 0, 1326, 474, 0, 0, 477, 477, + 474, 0, -1731, 474, 0, 2360, 0, 0, 0, 0, + 477, 2069, 477, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 474, 989, 0, 0, 0, 0, 0, 2393, + 0, 990, 477, 0, 484, 0, 0, 0, 485, 0, + 0, 0, 0, 991, 2440, 2441, 2442, 2443, 2444, 2445, + 2446, 2447, 2448, 2449, 637, 0, 0, 0, 0, 0, + 0, -1118, 0, 0, 975, 2437, 720, 651, 0, 0, + 0, 0, 0, 0, 992, 0, 0, 0, 0, 0, + 0, 0, 0, 717, 0, 2745, -1731, 0, 0, 0, + 0, 57, 0, 0, 0, 0, 477, 2069, 486, 719, + 477, 728, -1731, 0, 0, 487, 0, 2628, 474, 1333, + 1334, 1335, 1336, 1337, 1338, 993, 0, 0, 1496, 977, + 0, 994, 0, 0, 477, 595, 583, 0, 477, 2069, + 0, 0, 728, 0, 0, 728, 1526, 722, 0, 0, + 474, 477, 0, 995, 0, 0, 0, 0, 0, 996, + 0, 922, 488, 0, 2063, 0, 477, 0, 0, 2063, + 0, 0, 2063, 997, 0, 0, 1133, 0, 0, 1543, + 1133, 477, 1987, 1988, 1989, 0, 1990, 1991, 1992, 1993, + 1994, 1995, 817, 968, 0, 1980, -1731, 0, 0, 717, + 1981, 1982, 1983, 1333, 1334, 1335, 1336, 1337, 1338, 1611, + 645, 645, 0, 504, 504, 719, 504, 645, 0, 583, + 726, 2841, 0, 0, 0, 0, 979, 0, 0, 1148, + 1150, 1152, 489, 0, 0, 477, 0, 0, 477, 2069, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1966, 0, 715, 0, 0, 0, 0, 0, 0, - 0, 0, 716, 0, 0, 0, 1751, 0, 0, 0, - 0, 1967, 1968, 1969, 0, 1970, 1971, 1972, 1973, 1974, - 1975, 0, 576, 0, 500, 0, 0, 0, 1483, 1426, - 1483, 0, 1513, 809, 1319, 0, 1960, 0, 0, 0, - 0, 1961, 1962, 1963, 0, 0, 0, 0, 500, 0, - 2369, 2155, 0, 0, 0, 0, 0, 0, 716, 2164, - 2165, 2167, 0, 500, 500, 500, 500, 500, 500, 500, - 500, 500, 500, 0, 0, 0, 0, 0, 0, 2181, - 0, 0, 0, 0, 0, 1426, 0, 0, 576, 0, - 0, 0, 0, 0, 0, 0, 886, 886, 1426, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1513, - 0, 0, 715, 0, 0, 0, 0, 0, 0, 0, - 0, 576, 0, 0, 0, 0, 0, 716, 1483, 0, - 0, 0, 0, 0, 1320, 0, 0, 1321, 1322, 1323, - 0, 1324, 1325, 1326, 1327, 1328, 1329, 0, 715, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1034, - 1041, 1299, 0, 0, 1300, 0, 1967, 1968, 1969, 0, - 1970, 1971, 1972, 1973, 1974, 1975, 2469, 0, 0, 715, - 0, 0, 715, 0, 1967, 1968, 1969, 0, 1970, 1971, - 1972, 1973, 1974, 1975, 1306, 0, 0, 0, 0, 2485, - 0, -1713, 576, 576, 576, 576, 0, 0, 718, 2289, - 2303, 0, 2289, 0, 0, 2494, 0, 0, 0, 2052, - 0, 0, 0, 2052, -39, 0, 1308, 0, 0, 2512, - 2277, 2278, 2279, 0, 0, 0, 0, 716, 0, -1713, - 0, 0, 0, 1, 0, 902, 0, 0, 0, 2071, - 0, 0, 0, 2, 1751, 3, 4, 0, 1617, 0, - 0, 0, 0, 0, 0, 0, 1426, 716, 0, 0, - 0, 5, 0, 0, 0, 718, 0, 0, 0, 0, - 6, 0, 0, 0, 0, 0, 2334, 0, 0, 0, - 0, 2575, 7, 718, 0, 0, 2016, 0, 0, 0, - 0, 0, 0, 8, 0, 0, 0, 1231, 1966, 0, - 0, 0, 0, 1231, 0, 9, 0, 10, 718, 0, - 0, 0, 0, 0, 0, 718, -1713, 0, 0, 0, - 0, 0, 0, 0, 716, 11, 0, 0, 1034, 0, - 0, -1713, 0, 0, 0, 0, -1713, 0, 718, 12, - 0, 0, 2432, 0, 0, 1254, 0, 1483, 0, 13, - 0, 0, 0, 0, 0, 14, 1875, 0, 0, 0, - 0, 0, 0, 15, 0, 16, 17, 2612, 0, 0, - 715, -1713, 0, 0, 1265, 1547, 0, 0, 18, 0, + 474, 0, 720, 0, 0, 0, 57, 0, 0, 477, + 0, 477, 0, 477, 0, 0, 1630, 477, 0, 0, + 0, 0, 0, 0, 477, 2069, 0, 1656, 57, 490, + 2874, 491, 0, 0, 0, 0, 474, 726, 0, 0, + 0, 0, 0, 0, 0, 477, 0, 492, 0, 0, + 0, 1742, 0, 493, 0, 726, 494, 645, 0, 2063, + 0, 0, 0, 0, 0, 477, 477, 0, 0, 0, + 0, 0, 1292, 722, 0, 0, 0, 0, 0, 477, + 726, 0, 0, 0, 0, 0, 0, 726, 0, 0, + 583, 910, 0, 0, 0, 0, 0, 0, 0, 1133, + 2437, 0, 0, 0, 0, 0, 0, 0, 720, -1509, + 726, 0, 583, 0, 583, 0, 477, 2069, 477, 2941, + 0, 0, 0, 1759, 0, 1764, 717, 0, 474, 985, + 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 719, 0, 0, 0, 0, 0, 986, 0, + -1731, 0, 0, 0, 0, 0, 0, 1193, 1194, 0, + 0, 583, 0, 0, 0, 0, 0, 0, 0, 0, + 1439, 504, 0, 0, 0, 0, 0, 0, 0, 722, + 0, 504, 1815, 504, 1819, 477, 504, 0, 0, 0, + 0, 57, 504, 0, 504, 0, 0, 0, 0, 987, + 2382, 0, -1509, 0, 0, 645, 504, 0, 2383, 0, + 645, 504, 0, 0, 0, 504, 504, 504, 504, 1986, + 504, 504, 0, -1511, 0, 2719, 0, 0, 0, 726, + 0, 0, 1195, 1196, 0, 0, 0, 0, 0, 0, + 583, 583, 1881, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1371, 0, -1509, 0, 0, 1895, 1241, 0, + 2738, 2739, 1947, 0, 0, 2384, 0, -1509, 0, 0, + 0, 1241, -1509, 0, 0, 2749, 1382, -1509, 0, 0, + 57, 0, 0, 0, 0, 720, -1509, 0, 726, 988, + -1509, 0, 0, 0, 0, 0, 1197, 1198, 1199, 1200, + 1201, 1202, 1428, 0, 1203, 1204, 0, 0, 0, 0, + 0, 0, 0, 717, 717, 1455, -1511, 0, 0, 0, + 0, -1509, 0, 0, 0, 0, 0, 0, 717, 719, + 719, 0, 0, 0, 0, 0, 1479, 0, 0, 989, + -1509, 0, 0, 0, 719, 0, 0, 990, 0, 2807, + 0, 0, 0, 0, 0, 0, 722, 726, 0, 991, + 723, 2385, 0, 0, 0, 0, 0, 0, -1511, 0, + 0, 0, 0, 0, 0, 0, 0, 2828, 0, 0, + 0, -1511, 0, 0, 0, 0, -1511, 0, 0, -1509, + 992, -1511, -1509, 0, 0, 504, 0, 0, -1509, 0, + -1511, 0, 1297, 0, -1511, 0, 0, 0, 0, 0, + 1205, 1206, 0, 0, 1987, 1988, 1989, 725, 1990, 1991, + 1992, 1993, 1994, 1995, 0, 0, 0, 0, 0, 0, + 0, 0, -1509, 0, 0, -1511, 1630, 994, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1296, 0, 0, 0, 1275, 1276, 1277, 0, 0, 1284, - 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, - 0, 471, 2289, 0, 1231, 2639, 1231, 1231, 500, 0, - 2052, 0, 1339, 0, 0, 2052, 1317, 0, 2052, 0, - 2650, 0, 0, 2653, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 716, 0, 20, 0, 2675, 0, 0, - 0, 0, 0, 0, 0, 718, 2486, 2487, 2488, 2489, - 0, 0, 0, 0, 0, 0, 0, 638, 500, 0, - 0, 0, 0, 1381, 0, 0, 576, 1393, 1398, 716, - 0, 0, 0, 1231, 0, 0, 1231, 1231, 0, 0, - 0, 1967, 1968, 1969, 0, 1970, 1971, 1972, 1973, 1974, - 1975, 0, 0, 500, 500, 0, 0, 0, 0, 0, - 716, 718, 0, 716, 1426, 0, -1713, 0, 500, 0, - 0, 0, 21, 0, 0, 22, 0, 0, 0, 0, - 576, 1034, 0, 2675, 0, 0, 0, 0, 1034, 1299, - 0, 0, 1300, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 500, 23, 0, 0, 0, 0, 0, 1034, - 0, 24, 0, 0, 0, 2052, 0, 0, 0, 0, - 2653, 0, 1306, 0, 0, 25, 0, 0, 0, -1713, - 718, 0, 26, 0, 0, 2770, 27, 0, 0, 500, - 0, 0, 0, 0, 0, 0, 28, 0, 576, 0, - 0, 0, 0, 0, 1308, 0, 0, 29, 0, 0, - 0, 30, 0, 0, 0, 0, -1713, 500, 0, 0, - 0, 638, 0, 1324, 1325, 1326, 1327, 1328, 1329, 0, - 0, 0, 0, 576, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, - 0, 0, 32, 0, 0, 0, 0, 0, 0, 809, - 0, 471, 1960, 0, 0, 33, 1517, 1961, 1962, 1963, - 2826, 0, 0, 1034, 500, 0, 0, 1526, 2650, 1527, - 0, 0, 0, 0, 2477, 0, 0, 0, 1533, 34, - 718, 0, 0, 0, 0, 0, 0, 2675, 638, 638, - 638, 0, 0, 35, -1713, 1534, -39, 0, 1298, 0, - 0, 716, 0, 1299, 0, 0, 1300, 0, 0, -1713, - 718, 1301, 1302, 1303, -1713, 0, 0, 0, 0, 0, - 0, 0, 1552, 1554, 0, 0, 0, 0, 1304, 0, - 2696, 1305, 0, 2650, 0, 0, 1306, 0, 0, 0, - 0, 0, 0, 1307, 0, 2770, 0, 2639, 0, -1713, - 0, 0, 0, 0, 1585, 1586, 1751, 0, 1599, 1600, - 0, 0, 1299, 0, 0, 1300, 0, 0, 1308, 0, - 1426, 0, 0, 0, 0, 1582, 2675, 718, 0, 0, - 0, 0, 0, 0, 2734, 1601, 0, 1618, 0, 0, - 1630, 1633, 1638, 1641, 0, 1306, 0, 638, 0, 0, - 0, 0, -1713, 0, 1317, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1653, 0, 0, 0, 0, 0, - 1657, 1658, 1659, 1660, 0, 0, 0, 1308, 1669, 1670, - 1184, 1185, 0, 1681, 0, 0, 0, 1684, 0, 0, - 1692, 1693, 1694, 1695, 1696, 1697, 1698, 1699, 1700, 0, - 0, 1701, 2784, 0, 0, 1965, 1709, 0, 0, 1713, - 0, 886, 0, 1034, 0, 0, 0, 0, 1309, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1299, - 0, 0, 1300, 1310, 0, 0, 1735, 2808, 1311, 1770, - 1770, 0, 0, 0, -1713, 0, 718, 2261, 0, 0, - 0, 0, 0, 0, 0, 1186, 1187, 0, 0, 1312, - 1313, 0, 1306, 1276, 1277, 0, 0, 0, 0, -1713, - 0, 0, 0, 1314, 1966, 1299, 0, -1713, 1300, 0, - 0, 0, 718, 1301, 1302, 1303, 0, 0, 0, 0, - 0, 1231, -1713, 0, 1308, 0, 0, -1713, 0, 0, - 1304, 1231, 0, 2247, 1231, 0, 0, 0, 1306, 0, - 0, 1315, 0, 718, 1316, 1307, 718, 1188, 1189, 1190, - 1191, 1192, 1193, 0, 0, 1194, 1195, 0, 1317, 0, - 0, 1318, -1713, 0, 0, 0, 0, 0, 0, 0, - 1308, 0, 1034, 0, -1713, 1846, 1847, 0, 1848, 0, - 0, 1324, 1325, 1326, 1327, 1328, 1329, 0, 0, 1299, - 0, 0, 1300, 0, 2264, 0, 0, 1301, 1302, 1303, - 0, 0, 0, 0, 0, 0, 1900, 1902, 0, 1884, - 0, 0, 0, 0, 1304, 0, 0, 1317, 0, 0, - 0, 0, 1306, 0, -1713, 0, 0, 0, 0, 1307, - 0, 0, 1231, 0, 0, 0, 0, 0, 0, -1713, - 0, 0, 0, 0, -1713, 1231, 0, 0, 1319, 0, - 0, 0, 0, 0, 1308, 0, 0, 0, 0, 1196, - 1197, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1309, 1034, 0, 0, 0, 0, 0, 0, 1938, -1713, - 0, 0, 0, 1944, 0, 1310, 0, 0, 0, 0, - 1311, 0, 0, 0, 0, 0, 0, 1967, 1968, 1969, - 0, 1970, 1971, 1972, 1973, 1974, 1975, -1713, 0, 0, - 0, 1312, 1313, 0, 0, 0, 0, 0, 0, 0, - 0, 1959, 0, 0, 0, 1314, 0, 0, 0, 0, - 0, 0, 0, 1638, 1317, 1638, 1638, 0, 1332, 0, - 0, 0, 0, 1995, 718, 0, 0, 1998, 1320, 0, - 2000, 1321, 1322, 1323, 1309, 1324, 1325, 1326, 1327, 1328, - 1329, 0, 0, 1315, 0, 0, 1316, 0, 0, 1310, - 1198, 1199, 0, 0, 1311, 0, 0, 0, 1332, 0, - 1317, 0, 0, 1318, 2018, 0, 0, 2021, 0, 2023, - 1200, 0, 0, 0, 0, 1312, 1313, 0, 0, 0, - 0, 0, 0, 2058, 0, 0, 0, -1713, 0, 1314, - 0, 0, 0, 0, 1324, 1325, 1326, 1327, 1328, 1329, - 1299, 0, 0, 1300, -1713, 0, 0, 0, 1301, 1302, - 1303, 0, 0, 0, 2088, 2088, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1304, 0, 1315, 0, 0, - 1316, 1381, 0, 1306, 0, 0, 0, 0, 0, 0, - 1307, 0, 0, 0, 1317, 0, 1398, 1318, 0, 0, - 1319, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2096, 1308, 1332, 0, 0, 0, - 0, 0, 0, 1332, 0, 0, 0, 0, 0, 0, + 717, 0, 0, 0, -1511, -1509, 0, 0, 0, 995, + 0, 0, 0, 0, 0, 0, 719, 726, 0, 583, + 0, 0, 720, 720, 0, 0, 2072, 1512, 0, 997, + 0, 2386, 0, 0, 2387, 0, 0, 720, 0, 0, + 0, 2072, -1525, 0, 0, 2091, 0, 726, 2094, 817, + 1764, 0, 1980, -1511, 0, 0, -1511, 1981, 1982, 1983, + 2056, 0, -1511, 0, 2151, 0, 0, 817, 0, 0, + 1980, 1207, 1208, 0, 2277, 1981, 1982, 1983, 0, 0, + 0, 0, 0, 0, 0, 0, 723, -1509, 0, 0, + 0, 1209, 2504, 722, 722, -1509, -1511, 0, 0, 0, + 0, 1496, 0, 0, 0, 0, 0, 0, 722, 2177, + 1560, -1509, 0, -1509, -1509, 0, 0, 726, 0, -1511, + 0, 0, 2187, 0, 0, 0, 0, 0, 0, 0, + 717, 0, 0, 0, 0, -1525, 1447, 0, 0, 0, + 0, 0, 0, 725, 0, 0, 719, 0, 0, 0, + -1509, 0, 0, -1509, -1509, -1509, 0, 0, 0, 720, + 0, 0, 0, 1496, 0, 0, 0, 0, 583, 0, + 0, 0, 0, 0, 2056, 1496, 583, 583, 583, 1241, + 1308, 0, 0, 1309, 2222, 0, 2223, -1525, 0, 504, + 2228, 2229, 723, 0, 0, 0, 583, 0, 0, 0, + -1525, -1511, 0, 0, 0, -1525, 0, 0, 2213, -1511, + -1525, 0, 0, 1315, 0, 0, 0, 0, 0, -1525, + -1731, 0, 0, -1525, 645, -1511, 0, -1511, -1511, 0, + 722, 1734, 0, 0, 717, 0, 726, 0, 0, 0, + 1496, 1496, 0, 0, 0, 1317, 0, 0, 0, 725, + 719, 0, 0, 1744, -1525, 1746, 0, 1985, 0, 0, + 0, 0, 0, 1630, -1511, 0, 0, -1511, -1511, -1511, + 0, 0, 726, -1525, 0, 1985, 0, 0, 717, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 720, + 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, + 0, 0, 1794, 726, 0, 0, 726, 0, 0, 0, + 0, 0, 0, 0, 0, 2289, 0, 0, 0, 1193, + 1194, 0, -1525, 0, 0, -1525, 1986, 0, 0, 0, + 0, -1525, 0, 0, 0, 0, 0, 0, 0, 2297, + 0, 0, 0, 0, 1986, -1731, 0, 583, 583, 583, + 475, 0, 2072, 2314, 0, 0, 0, 2314, 2328, 0, + 722, -1731, 0, 0, 0, -1525, -1731, 0, 0, 723, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1299, - 0, 0, 1300, 0, -1713, 0, 0, 1301, 1302, 1303, - 0, 1324, 1325, 1326, 1327, 1328, 1329, 0, 0, 0, - 0, 0, 1034, 0, 1304, 0, 0, 0, 0, 0, - 0, 0, 1306, 0, 1319, 0, 0, 0, 0, 1307, - 0, 0, 0, 0, 0, 0, 0, 2184, 0, 0, - 1320, 0, 0, 1321, 1322, 1323, 0, 1324, 1325, 1326, - 1327, 1328, 1329, 0, 1308, 1309, 0, 1647, 0, 0, + 0, 1879, 1880, 0, 0, 0, 0, 1764, -1525, 0, + 0, 0, 2435, 720, 1195, 1196, 0, 0, 0, 0, + 0, 0, -1731, 0, 0, 583, 0, 504, 0, 0, + 0, 1496, 1439, 1496, 0, 1526, 0, 2177, 0, 0, + 0, 0, 0, 0, 0, 0, 725, 0, 0, 0, + 0, 504, 0, 2394, 0, 0, 0, 720, 0, 0, + 0, 0, 0, 2056, 0, 0, 504, 504, 504, 504, + 504, 504, 504, 504, 504, 504, 0, 1326, 1197, 1198, + 1199, 1200, 1201, 1202, 722, 0, 1203, 1204, 0, 0, + -1525, 1439, 0, 0, 583, 0, 0, 0, -1525, 0, + 0, 0, 0, 0, 1439, 0, 0, 0, 0, 894, + 894, 0, 0, 0, -1525, 1526, -1525, -1525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 583, 722, 0, + 0, 726, 0, 0, 1496, 0, 0, 0, 0, 0, + 0, 1987, 1988, 1989, 0, 1990, 1991, 1992, 1993, 1994, + 1995, 0, 0, -1525, 0, 0, -1525, -1525, -1525, 1987, + 1988, 1989, 0, 1990, 1991, 1992, 1993, 1994, 1995, -1731, + 0, 0, 1042, 1049, 0, 0, 723, 723, 0, 0, + 0, 0, 2497, 0, 0, 0, 0, 0, 0, 0, + 0, 723, 1205, 1206, 0, 0, 2549, 0, 0, 1308, + 0, 0, 1309, 0, 0, 2513, 717, 0, 583, 583, + 583, 583, 0, 0, 0, 2314, 2328, 0, 2314, 0, + 0, 2522, 719, 0, 0, 2072, 0, 0, 0, 2072, + 2055, 0, 1315, 725, 725, 2540, 0, 0, 0, -1731, + 0, 0, 0, 0, 0, 0, 0, 0, 725, 0, + 0, 910, 0, 0, 0, 2091, 0, 0, 0, 0, + 1764, 0, 0, 0, 1317, 0, 1630, 0, 0, -1731, + 0, 0, 1439, 717, 0, 0, 1333, 1334, 1335, 1336, + 1337, 1338, 0, 0, 0, 0, 0, 0, 0, 719, + 0, 717, 0, 1308, 0, 0, 1309, 2603, 0, 0, + 0, 0, 0, 1207, 1208, 0, 0, 719, 0, 0, + 0, 0, 0, 723, 0, 0, 717, 0, 0, 0, + 2624, 0, 0, 717, 0, 0, 1315, 0, 0, 0, + 0, 0, 719, -1731, 2290, 0, 0, 0, 0, 719, + 0, 1241, 0, 0, 0, 0, 717, 0, 0, 0, + 0, 0, 1042, 0, 0, 0, 0, 0, 1317, 0, + 0, 0, 719, 0, -1731, 720, 1496, 0, 0, 1263, + 725, 0, 0, 0, 0, 1895, 0, 0, 0, 2180, + -1731, 0, 0, 0, 0, -1731, 2640, 2189, 2190, 2192, + 0, 0, 0, 0, 0, 0, 0, 0, 1274, 0, + 0, 0, 0, 0, 0, 2698, 0, 2206, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1284, 1285, + 1286, -1731, 0, 1293, 0, 0, 0, 0, 2508, 0, + 475, 2314, 720, 0, 2667, 0, 722, 504, 0, 2072, + 0, 0, 0, 723, 2072, 0, 1348, 2072, 0, 2678, + 720, 0, 2681, 0, 0, 0, 0, 0, -1731, 0, + 0, 0, 0, 0, 0, 717, 2706, 0, 0, 2435, + 0, 0, 0, 0, -1731, 720, 1326, 0, 0, -1731, + 0, 719, 720, 0, 0, 0, 645, 504, 0, 0, + 0, 0, 0, 0, 0, 583, 0, 1392, 0, 0, + 725, 1406, 1411, 722, 0, 720, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -1731, 0, 0, 0, 0, + 0, 722, 504, 504, 717, 0, 0, 0, 0, 0, + 0, 0, 0, 1439, 0, 0, 0, 504, 0, 0, + 719, 0, 0, 0, 0, 0, 722, 723, 0, 583, + 0, 0, 2706, 722, 0, 1042, 0, 0, 2302, 2303, + 2304, 0, 1042, 0, 0, 0, 0, 0, -1731, 0, + 1326, 504, 0, 0, 0, 1308, 722, 0, 1309, 0, + 0, 0, 0, 1042, 2072, 0, 0, 0, 0, 2681, + 0, 723, 0, 717, 0, 0, 0, 0, 0, 0, + 2836, 0, 0, 0, 725, 0, 2802, 0, 1315, 719, + 0, 504, 0, 0, 0, -1731, 2359, 0, 0, 0, + 583, 0, 0, 0, 720, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 504, + 1317, 0, 817, 645, 0, 1980, 0, 0, 725, 0, + 1981, 1982, 1983, 0, 0, 0, 583, 0, 0, 0, + 0, 0, -1731, 0, 0, 0, 0, 2505, -1731, 0, + 0, 0, 0, 0, 0, 1333, 1334, 1335, 1336, 1337, + 1338, 0, 0, 720, 475, 2460, 0, 0, 0, 0, + 0, 0, 0, 2858, 0, 722, 0, 504, 1042, 0, + 0, 2678, 0, 717, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1240, 1560, 719, + 2706, 645, 645, 645, 1240, 0, 0, 0, 0, 0, + 0, 0, 0, 717, 0, 0, 0, 0, 0, 0, + -1731, 0, 0, 0, 2435, 0, 0, 0, 0, 719, + 0, 0, 720, 1600, 722, 547, -1731, 0, 0, 0, + 0, -1731, -1731, 0, 0, 0, 2678, 0, 0, 1333, + 1334, 1335, 1336, 1337, 1338, 0, 0, 0, 2802, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1310, 0, 964, 0, 0, 1311, 0, 0, 965, 0, - 0, 0, 0, 0, 0, 977, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1312, 1313, 0, 0, - 0, 0, 0, 0, 978, 0, 0, 0, 2206, 0, - 1314, 0, 0, 0, 0, 0, 0, 2210, 0, 0, - 2211, 0, 0, 2213, 1320, 0, 0, 1321, 1322, 1323, - 0, 1324, 1325, 1326, 1327, 1328, 1329, 0, 0, 0, - 0, 1647, 1184, 1185, 0, 0, 0, 0, 1315, 2233, - 2234, 1316, 0, 0, 1309, 979, 0, 0, 0, 0, - 0, 0, 0, 2244, 0, 1317, 0, 0, 1318, 1310, - 0, 0, 2250, 0, 1311, 2253, 1332, 2255, 0, 0, - 0, 0, 0, 0, 966, 2259, 0, 1332, 0, 0, - 0, 1625, 0, 2266, 2267, 1312, 1313, 1332, 1332, 1332, - 0, 0, 0, 0, 0, 0, 1332, 0, 0, 1314, - 0, 0, 0, 0, 0, 0, 0, 1186, 1187, 0, - 0, 0, 2307, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2315, 1299, 0, 0, 1300, 0, 0, 0, - 0, 1301, 1302, 1303, 980, 0, 0, 1315, 2328, 0, - 1316, 0, 0, 0, 0, 1319, 0, 0, 1304, 0, - 0, 1332, 1299, 0, 1317, 1300, 1306, 1318, 0, 0, - -1713, -1713, -1713, 1307, 0, 0, 0, 1231, 0, 1188, - 1189, 1190, 1191, 1192, 1193, 0, 0, 1194, 1195, 0, - 0, 0, 0, 981, 0, 1306, 0, 0, 1308, 0, - 0, 982, 1307, 1332, 0, 0, 0, 0, 1299, 0, - 0, 1300, 0, 983, 0, 1332, 1301, 1302, 1303, 0, - 1332, 0, 0, 0, 0, 0, 0, 1308, 0, 0, - 0, 0, 0, 1304, 967, 0, 0, 0, 0, 0, - 0, 1306, 0, 0, 984, 0, 0, 0, 1307, 0, - 0, 0, 0, 0, 1319, 1320, 0, 0, 1321, 1322, - 1323, 0, 1324, 1325, 1326, 1327, 1328, 1329, 0, 0, - 0, 0, 2002, 1308, 2457, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1817, 0, 0, 0, 969, 986, - 0, 1196, 1197, 0, 0, 0, 0, 0, 1309, 0, + 0, 0, 1764, 0, 0, 0, 0, -1731, 0, 2514, + 2515, 2516, 2517, 717, 0, 0, 1439, 0, 0, 0, + 1595, 1305, 2706, 0, 0, 0, 0, 0, 0, 719, + 1614, 0, 1631, 722, 0, 1643, 1646, 1651, 1654, 0, + 0, 0, 2667, 645, 0, 1240, 0, 1240, 1240, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1666, + 1985, 0, 1326, 0, 0, 1670, 1671, 1672, 1673, 1193, + 1194, 0, 720, 1682, 1683, 0, 0, 0, 1694, 0, + 0, 0, 1697, 0, 0, 1705, 1706, 1707, 1708, 1709, + 1710, 1711, 1712, 1713, 0, 0, 1714, 0, 0, 0, + 0, 1722, 720, 0, 1726, 0, 894, 0, 1042, 723, + 0, 0, 0, 0, 1240, 0, 0, 1240, 1240, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1986, + 0, 1748, 717, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 722, 1195, 1196, 0, 0, 719, 0, + 0, 0, 0, 0, -1731, 0, 0, 0, 0, 0, + 0, 0, 1285, 1286, 0, 0, 725, 0, 717, 0, + 0, 0, 720, 722, 0, 0, 723, 0, 0, 0, + 0, 0, 0, 0, 719, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 723, 0, 0, 0, 0, 717, + 0, 0, 717, 0, 0, 0, 0, 0, 1197, 1198, + 1199, 1200, 1201, 1202, 0, 719, 1203, 1204, 719, 723, + 0, 0, 0, 0, 0, 0, 723, 0, 0, 0, + 0, 0, 0, 725, 0, 0, 0, 0, 0, 0, + 0, 1042, 0, 722, 1866, 1867, 0, 1868, 0, 723, + 0, 725, 0, 0, -1731, 0, 0, 0, 0, 0, + 0, 1333, 1334, 1335, 1336, 1337, 1338, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 725, 0, 1904, 0, + 0, 0, 0, 725, 0, 0, 0, 0, 0, 0, + 0, 720, 0, 0, 0, 0, 2727, 0, 1530, 0, + 0, 0, 0, 0, 0, 0, 725, 0, 0, 1539, + 0, 1540, 0, 0, 0, 0, 0, 0, 0, 0, + 1546, 0, 1205, 1206, 1987, 1988, 1989, 720, 1990, 1991, + 1992, 1993, 1994, 1995, 0, 0, 0, 1547, 0, 0, + 1042, 0, 0, 0, 0, 0, 0, 1958, 0, 0, + 2766, 0, 1964, 0, 0, 0, 0, 0, 720, 0, + 0, 720, 722, 0, 1565, 1567, 0, 0, 723, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 987, 0, 1310, 0, 0, 0, 1818, 1311, 0, - 2470, 2471, 0, 0, 0, 2472, 0, 1309, 0, 0, - 2475, 989, 0, 2478, 2479, 0, 0, 0, 2483, 1312, - 1313, 0, 1310, 0, 0, 0, 0, 1311, 0, 0, - 0, 0, 0, 1314, 1320, 0, 0, 1321, 1322, 1323, - 0, 1324, 1325, 1326, 1327, 1328, 1329, 0, 0, 0, - 0, 2209, 0, 1309, 0, 0, 0, 0, 0, 0, - 0, 0, 1314, 0, 971, 886, 0, 0, 1310, 0, - 0, 1315, 0, 1311, 1316, 0, 0, 0, 0, 0, - 0, 1231, 1198, 1199, 1332, 0, 1231, 0, 1317, 0, - 0, 1318, 0, 0, 1312, 1313, 0, 0, 0, 0, - 0, 0, 0, 1332, 0, 0, 0, 2569, 1314, 0, - 0, 0, 0, 0, 0, 0, 0, 1317, 0, 0, - 1332, 0, 1625, 1625, 0, 1976, 0, 1625, 1552, 1554, - 0, 0, 1332, 0, 0, 1332, 0, 0, 0, 0, - 1332, 0, 0, 1332, 0, 0, 1315, 0, 0, 1316, - 0, 0, 0, 0, 0, 1332, 0, 0, 0, 1332, - 1332, 1332, 1332, 1317, 0, 0, 1318, 0, 1625, 1625, - 0, 1332, 1332, 0, 0, 0, 0, 0, 1319, 0, - 0, 0, 0, 1332, 0, 977, 1332, 0, 0, 0, - 0, 0, 0, 0, 1332, 1332, 1332, 1332, 1332, 1332, - 1332, 1332, 1332, 1332, 978, 0, 0, 1319, 0, 0, - 0, 1332, 0, 0, 0, 1332, 0, 1995, 0, 0, - 0, 0, 0, 0, 0, 2623, 2624, 0, 0, 2625, - 0, 0, 0, 0, 0, 0, 0, 1332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1319, 0, 979, 2357, 0, 0, 0, - 0, 0, 0, 0, 2358, 2664, 2665, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1320, 2677, - 0, 1321, 1322, 1323, 0, 1324, 1325, 1326, 1327, 1328, - 1329, 0, 0, 0, 0, 2248, 0, 1552, 1554, 0, - 0, 0, 0, 0, 0, 0, 0, 1320, 1231, 0, - -1713, -1713, -1713, 0, 1324, 1325, 1326, 1327, 1328, 1329, - 0, 2359, 0, 0, 0, 0, 0, 0, 0, 0, + 1979, 0, 0, 0, 0, 0, 1598, 1599, 722, 0, + 1612, 1613, 1651, 0, 1651, 1651, 0, 717, 0, 0, + 0, 0, 2015, 0, 0, 0, 2018, 0, 0, 2020, + -39, 2816, 0, 719, 0, 725, 0, 723, 0, 722, + 0, 0, 722, 1207, 1208, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 3, 4, 2038, 0, 0, 2041, 2840, 2043, 0, + 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 725, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 723, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 980, 0, 0, 0, 1332, 1332, - 1332, 0, 0, 1320, 0, 0, 1321, 1322, 1323, 0, - 1324, 1325, 1326, 1327, 1328, 1329, 0, 0, 0, 0, - 2336, 0, 1299, 0, 0, 1300, 0, 0, 0, 0, - 1301, 1302, 1303, 0, 0, 0, 1332, 0, 0, 0, - 0, 2754, 0, 981, 0, 0, 0, 1304, 0, 0, - 0, 982, 0, 0, 0, 1306, 1284, 0, 0, 0, - 0, 0, 1307, 983, 0, 2360, 1299, 0, 0, 1300, - 2776, 0, 0, 0, 1301, 1302, 1303, 0, 0, 0, - 0, 0, 0, 0, 0, 2790, 0, 1308, 0, 0, - 1332, 1304, 0, 0, 984, 0, 1332, 0, 0, 1306, - 0, 0, 0, 0, 0, 0, 1307, 0, 0, 1976, - 1976, 1332, 0, 1625, 1625, 1625, 1625, 0, 0, 1625, - 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1976, - 0, 1308, 0, 0, 0, 0, 0, 0, 0, 986, - 0, 0, 0, 0, 0, 0, 0, 1332, 0, 0, - 1332, 0, 1332, 0, 0, 0, 1976, 1976, 0, 0, - 0, 987, 0, 0, 0, 0, 2664, 0, 0, 0, - 1332, 1625, 1625, 1332, 0, 1332, 0, 0, 0, 0, - 0, 989, 0, 2361, 0, 0, 2362, 1309, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2858, 0, - 0, 0, 1310, 0, 0, 0, 0, 1311, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2872, 2872, - 0, 0, 0, 0, 0, 0, 1231, 0, 1312, 1313, - 0, 1309, 2664, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1314, 0, 0, 0, 1310, 0, 1332, 0, - 0, 1311, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2872, 0, - 0, 0, 1312, 1313, 0, 0, 0, 0, 0, 0, - 1315, 1299, 0, 1316, 1300, 0, 1314, 0, 1434, 0, - 0, 0, 0, 0, 0, 0, 0, 1317, 0, 0, - 1318, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1306, 0, 0, 0, 0, 0, - 0, -1713, 0, 0, 1315, 0, 0, 1316, 0, 0, - 0, 0, 0, 0, 2872, 0, 0, 0, 0, 0, - 0, 1317, 0, 0, 1318, 0, 1308, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1332, 0, - 0, 0, 1332, 1332, 0, 1332, 0, 0, 1976, 1976, - 1976, 1976, 0, 0, 0, 1976, 1976, 1976, 1976, 1976, - 1976, 1976, 1976, 1976, 1976, 1332, 1332, 1319, 0, 0, - 0, 0, 0, 0, 0, 0, 1332, 0, 0, 0, - 1299, 0, 1332, 1300, 0, 1332, 0, 1332, 1301, 1302, - 1303, 1332, 0, 0, 1976, 1976, 2265, 0, 1332, 1332, - 0, 0, 0, 0, 0, 1304, 0, 0, 0, 0, - 0, 1319, 0, 1306, 0, 0, 0, 0, 0, 0, - 1307, 0, 0, 0, 0, 0, -1713, 0, 0, 1299, - 0, 0, 1300, 0, 0, 0, 0, 0, 0, 1332, - 0, -1713, 0, 0, 0, 1308, -1713, 1332, 0, 0, + 0, 9, 0, 10, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1392, 0, 0, 0, 0, 0, + 0, 11, 0, 0, 0, 1788, 1788, 0, 0, 1411, + 1712, 0, 0, 0, 0, 12, 0, 0, 0, 0, + 0, 0, 1341, 725, 0, 13, 0, 0, 2118, 0, + 0, 14, 0, 0, 0, 0, 720, 0, 0, 15, + 0, 16, 17, 0, 0, 0, 0, 0, 506, 0, + 0, 0, 0, 0, 18, 0, 0, 1240, 0, 0, + 0, 0, 1341, 0, 0, 0, 0, 1240, 0, 0, + 1240, 1308, 0, 0, 1309, 0, 723, 0, 0, 1310, + 1311, 1312, 0, 19, 0, 0, 1042, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, + 0, 507, 0, 0, 1315, 0, 723, 722, 0, 0, + 0, 1316, 0, 0, 0, 0, 0, 508, 0, 0, + 0, 1308, 0, 21, 1309, 0, 0, 0, 0, 1310, + 1311, 1312, 0, 725, 0, 0, 1317, 0, 0, 0, + 0, 0, 1920, 1922, 0, 0, 1313, 0, 0, 0, + 0, 0, 0, 0, 1315, 0, 0, 0, 0, 0, + 0, 1316, 0, 725, 0, 0, 0, 0, 1240, 0, + 1341, 509, 0, 0, 0, 0, 723, 1341, 0, 0, + 510, 1240, 0, 0, 2231, 0, 1317, 0, 0, 0, + 0, 0, 511, 2235, 0, 0, 2236, 512, 0, 2238, + 22, 0, 0, 23, 1307, 0, 0, 0, 0, 1308, + 0, 0, 1309, 0, 0, 0, 0, 1310, 1311, 1312, + 0, 0, 0, 0, 513, 2258, 2259, 0, 0, 0, + 0, 0, 24, 725, 1313, 0, 1318, 1314, 0, 2269, + 0, 25, 1315, 0, 0, 0, 0, 0, 2275, 1316, + 0, 2278, 1319, 2280, 0, 26, 0, 1320, 0, 0, + 0, 2284, 27, 0, 0, 0, 28, 0, 514, 2291, + 2292, 0, 515, 0, 1317, 0, 29, 0, 0, -1731, + -1731, 0, 0, 0, 0, 0, 1318, 30, 0, 0, + 0, 31, 0, 1323, 0, 723, 0, 0, 2332, 0, + 0, 0, 1319, 0, 0, 0, 0, 1320, 2340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1332, 0, 1306, 0, 0, 0, 0, 1320, 0, -1713, - 1321, 1322, 1323, 0, 1324, 1325, 1326, 1327, 1328, 1329, - 0, -1713, 0, 0, 2459, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1308, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2353, 0, 0, 32, 0, 1321, + 1322, 723, 33, 0, -1731, 516, 0, 0, 0, 2078, + 0, 0, 0, 1323, 0, 34, 0, 0, 1326, 517, + 0, 0, 725, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 723, 0, 0, 723, 0, 0, 0, 35, + 0, 0, 2110, 2110, 1318, 0, 0, 0, 0, 0, + 0, 1324, 518, 36, 1325, 519, -39, 0, 725, 0, + 1319, 1341, 0, 520, 0, 1320, 521, 0, 1326, 0, + 0, 1327, 1341, 0, 0, 0, 1638, 0, 0, 0, + 0, 0, 1341, 1341, 1341, 522, 0, 1321, 1322, 725, + 0, 1341, 725, 0, 0, 0, 0, 0, 523, 0, + 0, 1323, 0, 0, 0, 524, 0, 0, 0, 0, + 1328, 0, 0, 0, 525, 0, 0, 0, 0, 0, + 526, 0, 0, 0, 0, 2485, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1324, + 0, 0, 1325, 0, 0, 527, 1341, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1326, 0, 1308, 1327, + 1328, 1309, 0, 0, 0, 0, 1310, 1311, 1312, 0, + 0, 2498, 2499, 0, 0, 0, 2500, 0, 0, 0, + 2209, 2503, 0, 1313, 2506, 2507, 2272, 0, 0, 2511, + 1341, 1315, 0, 0, 0, 0, 0, 0, 1316, 0, + 0, 0, 0, 0, 1341, 0, 0, 0, 0, 1341, + 1329, 0, 0, 1330, 1331, 1332, 0, 1333, 1334, 1335, + 1336, 1337, 1338, 1317, 972, 0, 0, 0, 0, 0, + 973, 0, 0, 0, 0, 0, 894, 985, 0, 0, + 723, 0, 0, 0, 0, 0, 0, 0, 1328, 0, + 0, 0, 0, 0, 0, 0, 986, 0, 0, 0, + 1329, 0, 0, 1330, 1331, 1332, 0, 1333, 1334, 1335, + 1336, 1337, 1338, 0, 0, 0, 0, 0, 2597, 0, + 1971, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 725, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 987, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1320, 0, 0, 1321, 1322, 1323, 0, 1324, 1325, - 1326, 1327, 1328, 1329, 0, 0, 0, 0, 2481, 0, - 0, 0, 0, 0, 0, 0, 1317, 0, 0, 0, - 0, 0, 0, 0, 0, 1309, 0, 0, 0, 0, + 0, 0, 0, 1318, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 974, 0, 0, 1319, + 0, 0, 0, 0, 1320, 0, 0, 0, 1329, 0, + 0, 1330, 1331, 1332, 0, 1333, 1334, 1335, 1336, 1337, + 1338, 0, 0, 0, 0, 0, 1321, 1322, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1310, 0, 0, 0, 2480, 1311, 0, 0, 0, 0, + 1323, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2015, 0, 1341, 0, 0, 0, 988, 0, 2651, + 2652, 0, 0, 2653, 0, 0, 0, 0, 0, 0, + 0, 0, 1341, 0, 0, 0, 0, 0, 1324, 0, + 0, 1325, 1240, 0, 0, 0, 0, 0, 0, 1341, + 0, 1638, 1638, 0, 1996, 1326, 1638, 0, 1327, 2694, + 2695, 1341, 0, 0, 1341, 0, 0, 989, 0, 1341, + 0, 0, 1341, 2708, 0, 990, 0, 0, 0, 0, + 0, 0, 0, 0, 1341, 0, 0, 991, 1341, 1341, + 1341, 1341, 0, 0, 0, 0, 0, 1638, 1638, 0, + 1341, 1341, 0, 0, 0, 0, 0, 0, 975, 0, + 0, 0, 1341, 0, 0, 1341, 0, 0, 992, 0, + 0, 0, 0, 1341, 1341, 1341, 1341, 1341, 1341, 1341, + 1341, 1341, 1341, 0, 0, 0, 0, 0, 0, 0, + 1341, 0, 0, 0, 1341, 0, 0, 1328, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1835, + 0, 0, 0, 977, 1308, 994, 1341, 1309, 0, 0, + 0, 0, 1310, 1311, 1312, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2786, 0, 995, 0, 1313, + 0, 0, 0, 1836, 0, 0, 0, 1315, 0, 0, + 0, 0, 1293, 0, 1316, 0, 0, 997, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2808, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1317, + 0, 0, 2822, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1329, 0, 0, + 1330, 1331, 1332, 0, 1333, 1334, 1335, 1336, 1337, 1338, + 979, 0, 0, 0, 1660, 0, 0, 0, 0, 1240, + 0, 0, 0, 0, 1240, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1341, 1341, 1341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1312, 1313, 0, 1332, - 0, 0, 0, 1625, -1713, 0, 0, 0, 0, 0, - 1314, 0, 1332, 1332, 1332, 0, 0, 1332, 0, -1713, - 1332, 1332, 0, 0, -1713, 1332, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -1713, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1315, 0, - 0, 1316, 0, 0, 0, 0, 0, 0, 0, -1713, - 0, 0, 0, 0, 0, 1317, 0, 0, 1318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2694, 0, 1565, 1567, 2870, 0, + 0, 0, 1341, 0, 0, 0, 0, 0, 0, 1318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1625, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1319, 2893, 0, 0, 0, + 1320, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2907, 2907, 0, 0, + 0, 0, 1321, 1322, 0, 0, 1341, 0, 0, 0, + 2694, 0, 1341, 0, 0, 0, 1323, 0, 0, 0, + 0, 0, 0, 0, 0, 1996, 1996, 1341, 0, 1638, + 1638, 1638, 1638, 0, 0, 1638, 1638, 1638, 1638, 1638, + 1638, 1638, 1638, 1638, 1638, 1996, 0, 0, 0, 2907, + 0, 0, 0, 0, 1324, 0, 0, 1325, 0, 0, + 0, 0, 0, 1341, 0, 0, 1341, 0, 1341, 0, + 0, 1326, 1996, 1996, 1327, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1341, 1638, 1638, 1341, + 0, 1341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1332, 0, 0, 1317, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2907, 0, 1565, 1567, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -1713, 0, 0, 0, - 0, 0, 0, 1324, 1325, 1326, 1327, 1328, 1329, 0, - 0, 0, 0, 0, 0, 1319, 0, 0, 0, 1976, - 1625, 0, 0, 0, 0, 1332, 1332, 1332, 0, 0, + 0, 0, 0, 1308, 0, 0, 1309, 0, 0, 0, + 0, 1310, 1311, 1312, 0, 0, 0, 0, 0, 0, + 0, 0, 1308, 1328, 0, 1309, 1341, 0, 1313, 0, + 1310, 1311, 1312, 0, 0, 0, 1315, 0, 0, 0, + 0, 0, 0, 1316, 0, 0, 0, 1313, 1308, 0, + 0, 1309, 0, 0, 0, 1315, 1310, 1311, 1312, 0, + 0, 0, 1316, 0, 0, 0, 0, 0, 1317, 0, + 0, 0, 0, 1313, 0, 0, 0, 0, 0, 0, + 0, 1315, 0, 0, 0, 0, 0, 1317, 1316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1317, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1329, 0, 0, 1330, 1331, 1332, 0, + 1333, 1334, 1335, 1336, 1337, 1338, 0, 0, 0, 1341, + 1660, 0, 0, 1341, 1341, 1308, 1341, 0, 1309, 1996, + 1996, 1996, 1996, -1731, -1731, -1731, 1996, 1996, 1996, 1996, + 1996, 1996, 1996, 1996, 1996, 1996, 1341, 1341, 1318, 0, + 0, 0, 0, 0, 0, 0, 0, 1341, 1315, 0, + 0, 0, 0, 1341, 1319, 1316, 1341, 1318, 1341, 1320, + 0, 0, 1341, 0, 0, 1996, 1996, 0, 0, 1341, + 1341, 0, 0, 1319, 0, 0, 0, 0, 1320, 0, + 1317, 1321, 1322, 1318, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1323, 0, 0, 0, 1319, + 1321, 1322, 0, 0, 1320, 0, 0, 0, 0, 0, + 1341, 0, 0, 0, 1323, 0, 0, 0, 1341, 0, + 0, 0, 0, 0, 0, 0, 1321, 1322, 0, 0, + 0, 1341, 0, 1324, 1240, 0, 1325, 0, 0, 0, + 1323, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1326, 0, 1324, 1327, 0, 1325, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1326, + 0, 0, 1327, 0, 0, 0, 0, 0, 1324, 0, + 1318, 1325, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1326, 1319, 0, 1327, 0, + 0, 1320, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, -1713, 0, 1332, 1332, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1976, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1323, 0, 0, + 0, 0, 1328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1320, 0, 0, 1321, 1322, - 1323, 0, 1324, 1325, 1326, 1327, 1328, 1329, 0, 0, - 0, 0, 2626, 0, 0, 0, 0, 0, 1976, 0, + 0, 1328, 0, 1341, 0, 0, 0, 1638, 0, 0, + 0, 0, 0, 0, 0, 0, 1341, 1341, 1341, 0, + 0, 1341, 0, 0, 1341, 1341, 0, 1328, 0, 1341, + 0, 0, 1326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1332, 0, 0, 0, - 0, 0, 0, 0, -1713, 0, 0, 0, 0, 0, - 0, 1324, 1325, 1326, 1327, 1328, 1329, 0, 1332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1001, 806, 542, 807, 808, 809, 810, 811, 0, 0, - 0, 0, 0, 0, 0, 0, 92, 93, 94, 95, - 96, 97, 98, 99, 1002, 100, 101, 102, 0, 0, - 0, 0, 812, 0, 0, 103, 104, 0, 105, 106, - 107, 1003, 109, 110, 111, 112, 813, 1004, 814, 815, - 1332, 117, 118, 119, 120, 121, 122, 816, 817, 123, - 124, 818, 819, 127, 1332, 128, 129, 130, 131, 820, - 0, 1005, 0, 134, 135, 136, 137, 138, 139, 1006, - 141, 142, 143, 0, 144, 145, 146, 147, 148, 149, - 0, 1007, 151, 152, 153, 822, 823, 824, 1008, 826, - 827, 828, 155, 156, 157, 158, 159, 160, 161, 829, - 830, 164, 831, 165, 0, 166, 167, 168, 169, 170, - 171, 0, 172, 173, 174, 175, 176, 1009, 0, 177, - 178, 668, 180, 181, 0, 182, 183, 184, 0, 185, - 186, 187, 0, 188, 189, 190, 191, 832, 193, 194, - 195, 196, 833, 834, 198, 0, 199, 200, 835, 202, - 0, 203, 0, 204, 1010, 0, 1011, 207, 208, 209, - 1012, 211, 0, 212, 0, 836, 837, 215, 0, 216, - 217, 218, 219, 220, 221, 1013, 223, 224, 225, 226, - 0, 227, 228, 229, 230, 231, 232, 0, 233, 1014, - 235, 236, 237, 238, 239, 838, 839, 0, 840, 0, - 243, 1015, 1016, 246, 1017, 248, 249, 250, 251, 252, - 0, 0, 253, 1018, 255, 1019, 0, 257, 258, 259, - 841, 842, 260, 261, 262, 263, 264, 1020, 266, 267, - 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, - 278, 279, 280, 281, 282, 283, 843, 1021, 844, 287, - 288, 289, 290, 845, 291, 292, 1022, 294, 846, 847, - 296, 848, 298, 299, 300, 0, 301, 302, 0, 0, - 849, 304, 305, 0, 0, 306, 307, 1023, 309, 1024, - 850, 312, 313, 314, 315, 316, 317, 318, 319, 320, - 321, 0, 322, 323, 851, 325, 326, 327, 328, 329, - 330, 0, 331, 332, 333, 334, 335, 336, 337, 338, - 339, 852, 341, 342, 343, 344, 0, 345, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, 356, 0, - 357, 358, 1025, 360, 361, 362, 853, 364, 365, 366, - 367, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 376, 377, 378, 379, 854, 380, 381, 382, 383, 384, - 1026, 386, 387, 855, 389, 0, 390, 391, 392, 393, - 394, 395, 396, 397, 398, 399, 400, 1027, 402, 856, - 404, 0, 405, 406, 0, 407, 1028, 409, 410, 411, - 412, 413, 0, 857, 858, 0, 0, 416, 417, 859, - 419, 860, 861, 421, 422, 1029, 424, 425, 426, 427, - 428, 0, 0, 429, 430, 431, 432, 433, 863, 0, - 434, 435, 436, 437, 438, 439, 864, 1030, 441, 1031, - 443, 444, 445, 446, 0, 0, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, - 865, 0, 0, 0, 0, 0, 0, 866, 867, 1032, - 0, 0, 0, 0, 869, 0, 870, 1033, 0, 0, - 0, 871, 0, 872, 873, 91, 806, 542, 807, 808, - 809, 810, 811, 0, 0, 0, 0, 0, 0, 0, - 0, 92, 93, 94, 95, 96, 97, 98, 99, 0, - 100, 101, 102, 0, 0, 0, 0, 812, 0, 0, - 103, 104, 0, 105, 106, 107, 108, 109, 110, 111, - 112, 813, 114, 814, 815, 0, 117, 118, 119, 120, - 121, 122, 816, 817, 123, 124, 818, 819, 127, 0, - 128, 129, 130, 131, 820, 0, 821, 0, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 0, 144, - 145, 146, 147, 148, 149, 0, 150, 151, 152, 153, - 822, 823, 824, 825, 826, 827, 828, 155, 156, 157, - 158, 159, 160, 161, 829, 830, 164, 831, 165, 0, - 166, 167, 168, 169, 170, 171, 0, 172, 173, 174, - 175, 176, 0, 0, 177, 178, 668, 180, 181, 0, - 182, 183, 184, 0, 185, 186, 187, 0, 188, 189, - 190, 191, 832, 193, 194, 195, 196, 833, 834, 198, - 0, 199, 200, 835, 202, 0, 203, 0, 204, 205, - 0, 206, 207, 208, 209, 210, 211, 0, 212, 0, - 836, 837, 215, 0, 216, 217, 218, 219, 220, 221, - 222, 223, 224, 225, 226, 0, 227, 228, 229, 230, - 231, 232, 0, 233, 234, 235, 236, 237, 238, 239, - 838, 839, 0, 840, 0, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 0, 0, 253, 254, 255, - 256, 0, 257, 258, 259, 841, 842, 260, 261, 262, - 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1329, 0, 0, 1330, 1331, 1332, 0, 1333, + 1334, 1335, 1336, 1337, 1338, 0, 1638, 0, 0, 2022, + 0, 1329, 0, 0, 1330, 1331, 1332, 0, 1333, 1334, + 1335, 1336, 1337, 1338, 0, 1341, 0, 0, 2234, 0, + 0, 0, 0, 0, 1328, 0, 0, 1329, 0, 0, + 1330, 1331, 1332, 0, 1333, 1334, 1335, 1336, 1337, 1338, + 0, 0, 0, 0, 2273, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1996, 1638, 0, 0, 0, 0, 1341, + 1341, 1341, 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, 1341, 1341, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1329, 0, 1341, -1731, -1731, -1731, + 0, 1333, 1334, 1335, 1336, 1337, 1338, 0, 1996, 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, 1996, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1341, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1341, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1341, 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, 1341, 0, + 0, 0, 0, 0, 0, 0, 1009, 814, 547, 815, + 816, 817, 818, 819, 0, 0, 0, 0, 0, 0, + 0, 1341, 93, 94, 95, 96, 97, 98, 99, 100, + 1010, 101, 102, 103, 0, 1341, 0, 0, 820, 0, + 0, 104, 105, 0, 106, 107, 108, 1011, 110, 111, + 112, 113, 821, 1012, 822, 823, 0, 118, 119, 120, + 121, 122, 123, 824, 825, 124, 125, 826, 827, 128, + 0, 129, 130, 131, 132, 828, 0, 1013, 0, 135, + 136, 137, 138, 139, 140, 1014, 142, 143, 144, 0, + 145, 146, 147, 148, 149, 150, 0, 1015, 152, 153, + 154, 830, 831, 832, 1016, 834, 835, 836, 156, 157, + 158, 159, 160, 161, 162, 837, 838, 165, 839, 166, + 0, 167, 168, 169, 170, 171, 172, 0, 173, 174, + 175, 176, 177, 1017, 0, 178, 179, 675, 181, 182, + 0, 183, 184, 185, 0, 186, 187, 188, 0, 189, + 190, 191, 192, 840, 194, 195, 196, 197, 841, 842, + 199, 0, 200, 201, 843, 203, 0, 204, 0, 205, + 1018, 0, 1019, 208, 209, 210, 1020, 212, 0, 213, + 0, 844, 845, 216, 0, 217, 218, 219, 220, 221, + 222, 223, 1021, 225, 226, 227, 228, 0, 229, 230, + 231, 232, 233, 234, 0, 235, 1022, 237, 238, 239, + 240, 241, 242, 846, 847, 0, 848, 0, 246, 1023, + 1024, 249, 1025, 251, 252, 253, 254, 255, 0, 0, + 256, 1026, 258, 1027, 0, 260, 261, 262, 849, 850, + 263, 264, 265, 266, 267, 1028, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, - 283, 843, 285, 844, 287, 288, 289, 290, 845, 291, - 292, 293, 294, 846, 847, 296, 848, 298, 299, 300, - 0, 301, 302, 0, 0, 849, 304, 305, 0, 0, - 306, 307, 308, 309, 310, 850, 312, 313, 314, 315, - 316, 317, 318, 319, 320, 321, 0, 322, 323, 851, - 325, 326, 327, 328, 329, 330, 0, 331, 332, 333, - 334, 335, 336, 337, 338, 339, 852, 341, 342, 343, - 344, 0, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 0, 357, 358, 359, 360, 361, - 362, 853, 364, 365, 366, 367, 368, 369, 370, 371, - 372, 373, 374, 25, 375, 376, 377, 378, 379, 854, - 380, 381, 382, 383, 384, 385, 386, 387, 855, 389, - 0, 390, 391, 392, 393, 394, 395, 396, 397, 398, - 399, 400, 401, 402, 856, 404, 0, 405, 406, 30, - 407, 408, 409, 410, 411, 412, 413, 0, 857, 858, - 0, 0, 416, 417, 859, 419, 860, 861, 421, 422, - 862, 424, 425, 426, 427, 428, 0, 0, 429, 430, - 431, 432, 433, 863, 0, 434, 435, 436, 437, 438, - 568, 864, 0, 441, 442, 443, 444, 445, 446, 0, - 0, 447, 0, 33, 448, 449, 450, 451, 452, 453, + 283, 284, 285, 286, 851, 1029, 852, 290, 291, 292, + 293, 853, 294, 295, 1030, 297, 854, 855, 299, 856, + 301, 302, 303, 0, 304, 305, 0, 0, 857, 307, + 308, 0, 0, 309, 310, 1031, 312, 1032, 858, 315, + 316, 317, 318, 319, 320, 321, 322, 323, 324, 0, + 325, 326, 859, 328, 329, 330, 331, 332, 333, 0, + 334, 335, 336, 337, 338, 339, 0, 340, 341, 342, + 860, 344, 345, 346, 347, 0, 348, 349, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 0, + 361, 362, 1033, 364, 365, 366, 861, 368, 369, 370, + 371, 372, 373, 374, 375, 376, 377, 378, 0, 379, + 380, 381, 382, 383, 862, 384, 385, 386, 387, 388, + 1034, 390, 391, 863, 393, 0, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, 404, 1035, 406, 864, + 408, 0, 409, 410, 0, 411, 1036, 413, 414, 415, + 416, 417, 0, 865, 866, 0, 0, 420, 421, 867, + 423, 868, 869, 425, 426, 1037, 428, 429, 430, 431, + 432, 0, 0, 433, 434, 435, 436, 437, 871, 0, + 438, 439, 440, 441, 442, 443, 872, 1038, 445, 1039, + 447, 448, 449, 450, 0, 0, 451, 0, 0, 452, + 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, + 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, + 873, 0, 0, 0, 0, 0, 0, 874, 875, 1040, + 0, 0, 0, 0, 877, 0, 878, 1041, 0, 0, + 0, 879, 0, 880, 881, 92, 814, 547, 815, 816, + 817, 818, 819, 0, 0, 0, 0, 0, 0, 0, + 0, 93, 94, 95, 96, 97, 98, 99, 100, 0, + 101, 102, 103, 0, 0, 0, 0, 820, 0, 0, + 104, 105, 0, 106, 107, 108, 109, 110, 111, 112, + 113, 821, 115, 822, 823, 0, 118, 119, 120, 121, + 122, 123, 824, 825, 124, 125, 826, 827, 128, 0, + 129, 130, 131, 132, 828, 0, 829, 0, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 0, 145, + 146, 147, 148, 149, 150, 0, 151, 152, 153, 154, + 830, 831, 832, 833, 834, 835, 836, 156, 157, 158, + 159, 160, 161, 162, 837, 838, 165, 839, 166, 0, + 167, 168, 169, 170, 171, 172, 0, 173, 174, 175, + 176, 177, 0, 0, 178, 179, 675, 181, 182, 0, + 183, 184, 185, 0, 186, 187, 188, 0, 189, 190, + 191, 192, 840, 194, 195, 196, 197, 841, 842, 199, + 0, 200, 201, 843, 203, 0, 204, 0, 205, 206, + 0, 207, 208, 209, 210, 211, 212, 0, 213, 0, + 844, 845, 216, 0, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, 0, 229, 230, 231, + 232, 233, 234, 0, 235, 236, 237, 238, 239, 240, + 241, 242, 846, 847, 0, 848, 0, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 0, 0, 256, + 257, 258, 259, 0, 260, 261, 262, 849, 850, 263, + 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + 284, 285, 286, 851, 288, 852, 290, 291, 292, 293, + 853, 294, 295, 296, 297, 854, 855, 299, 856, 301, + 302, 303, 0, 304, 305, 0, 0, 857, 307, 308, + 0, 0, 309, 310, 311, 312, 313, 858, 315, 316, + 317, 318, 319, 320, 321, 322, 323, 324, 0, 325, + 326, 859, 328, 329, 330, 331, 332, 333, 0, 334, + 335, 336, 337, 338, 339, 0, 340, 341, 342, 860, + 344, 345, 346, 347, 0, 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 0, 361, + 362, 363, 364, 365, 366, 861, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 26, 379, 380, + 381, 382, 383, 862, 384, 385, 386, 387, 388, 389, + 390, 391, 863, 393, 0, 394, 395, 396, 397, 398, + 399, 400, 401, 402, 403, 404, 405, 406, 864, 408, + 0, 409, 410, 31, 411, 412, 413, 414, 415, 416, + 417, 0, 865, 866, 0, 0, 420, 421, 867, 423, + 868, 869, 425, 426, 870, 428, 429, 430, 431, 432, + 0, 0, 433, 434, 435, 436, 437, 871, 0, 438, + 439, 440, 441, 442, 575, 872, 0, 445, 446, 447, + 448, 449, 450, 0, 0, 451, 0, 34, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 865, 0, 34, 0, 0, - 0, 0, 866, 867, 0, 0, 0, 0, 0, 869, - 0, 870, 2766, 0, 0, 0, 871, 0, 872, 873, - 91, 806, 542, 807, 808, 809, 810, 811, 0, 0, - 0, 0, 0, 0, 0, 0, 92, 93, 94, 95, - 96, 97, 98, 99, 0, 100, 101, 102, 0, 0, - 0, 0, 812, 0, 0, 103, 104, 0, 105, 106, - 107, 108, 109, 110, 111, 112, 813, 114, 814, 815, - 0, 117, 118, 119, 120, 121, 122, 816, 817, 123, - 124, 818, 819, 127, 0, 128, 129, 130, 131, 820, - 0, 821, 0, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 0, 144, 145, 146, 147, 148, 149, - 0, 150, 151, 152, 153, 822, 823, 824, 825, 826, - 827, 828, 155, 156, 157, 158, 159, 160, 161, 829, - 830, 164, 831, 165, 0, 166, 167, 168, 169, 170, - 171, 0, 172, 173, 174, 175, 176, 0, 0, 177, - 178, 668, 180, 181, 0, 182, 183, 184, 0, 185, - 186, 187, 0, 188, 189, 190, 191, 832, 193, 194, - 195, 196, 833, 834, 198, 0, 199, 200, 835, 202, - 0, 203, 0, 204, 205, 0, 206, 207, 208, 209, - 210, 211, 0, 212, 0, 836, 837, 215, 0, 216, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 873, + 0, 35, 0, 0, 0, 0, 874, 875, 0, 0, + 0, 0, 0, 877, 0, 878, 2798, 0, 0, 0, + 879, 0, 880, 881, 92, 814, 547, 815, 816, 817, + 818, 819, 0, 0, 0, 0, 0, 0, 0, 0, + 93, 94, 95, 96, 97, 98, 99, 100, 0, 101, + 102, 103, 0, 0, 0, 0, 820, 0, 0, 104, + 105, 0, 106, 107, 108, 109, 110, 111, 112, 113, + 821, 115, 822, 823, 0, 118, 119, 120, 121, 122, + 123, 824, 825, 124, 125, 826, 827, 128, 0, 129, + 130, 131, 132, 828, 0, 829, 0, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 0, 145, 146, + 147, 148, 149, 150, 0, 151, 152, 153, 154, 830, + 831, 832, 833, 834, 835, 836, 156, 157, 158, 159, + 160, 161, 162, 837, 838, 165, 839, 166, 0, 167, + 168, 169, 170, 171, 172, 0, 173, 174, 175, 176, + 177, 0, 0, 178, 179, 675, 181, 182, 0, 183, + 184, 185, 0, 186, 187, 188, 0, 189, 190, 191, + 192, 840, 194, 195, 196, 197, 841, 842, 199, 0, + 200, 201, 843, 203, 0, 204, 0, 205, 206, 0, + 207, 208, 209, 210, 211, 212, 0, 213, 0, 844, + 845, 216, 0, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 0, 229, 230, 231, 232, + 233, 234, 0, 235, 236, 237, 238, 239, 240, 241, + 242, 846, 847, 0, 848, 0, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 0, 0, 256, 257, + 258, 259, 0, 260, 261, 262, 849, 850, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 851, 288, 852, 290, 291, 292, 293, 853, + 294, 295, 296, 297, 854, 855, 299, 856, 301, 302, + 303, 0, 304, 305, 0, 0, 857, 307, 308, 0, + 0, 309, 310, 311, 312, 313, 858, 315, 316, 317, + 318, 319, 320, 321, 322, 323, 324, 0, 325, 326, + 859, 328, 329, 330, 331, 332, 333, 0, 334, 335, + 336, 337, 338, 339, 0, 340, 341, 342, 860, 344, + 345, 346, 347, 0, 348, 349, 350, 351, 352, 353, + 354, 355, 356, 357, 358, 359, 360, 0, 361, 362, + 363, 364, 365, 366, 861, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, 378, 26, 379, 380, 381, + 382, 383, 862, 384, 385, 386, 387, 388, 389, 390, + 391, 863, 393, 0, 394, 395, 396, 397, 398, 399, + 400, 401, 402, 403, 404, 405, 406, 864, 408, 0, + 409, 410, 31, 411, 412, 413, 414, 415, 416, 417, + 0, 865, 866, 0, 0, 420, 421, 867, 423, 868, + 869, 425, 426, 870, 428, 429, 430, 431, 432, 0, + 0, 433, 434, 435, 436, 437, 871, 0, 438, 439, + 440, 441, 442, 575, 872, 0, 445, 446, 447, 448, + 449, 450, 0, 0, 451, 0, 34, 452, 453, 454, + 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, + 465, 466, 467, 468, 469, 470, 471, 472, 873, 0, + 35, 0, 0, 0, 0, 874, 875, 0, 0, 0, + 0, 0, 877, 0, 878, 0, 0, 0, 0, 879, + 0, 880, 881, 92, 814, 547, 815, 816, 817, 818, + 819, 0, 0, 0, 0, 0, 0, 0, 0, 93, + 94, 95, 96, 97, 98, 99, 100, 0, 101, 102, + 103, 0, 0, 0, 0, 820, 0, 0, 104, 105, + 0, 106, 107, 108, 109, 110, 111, 112, 113, 821, + 115, 822, 823, 1647, 118, 119, 120, 121, 122, 123, + 824, 825, 124, 125, 826, 827, 128, 0, 129, 130, + 131, 132, 828, 0, 829, 0, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 0, 145, 146, 147, + 148, 149, 150, 0, 151, 152, 153, 154, 830, 831, + 832, 833, 834, 835, 836, 156, 157, 158, 159, 160, + 161, 162, 837, 838, 165, 839, 166, 0, 167, 168, + 169, 170, 171, 172, 0, 173, 174, 175, 176, 177, + 0, 0, 178, 179, 675, 181, 182, 0, 183, 184, + 185, 0, 186, 187, 188, 0, 189, 190, 191, 192, + 840, 194, 195, 196, 197, 841, 842, 199, 0, 200, + 201, 843, 203, 0, 204, 0, 205, 206, 1648, 207, + 208, 209, 210, 211, 212, 0, 213, 0, 844, 845, + 216, 0, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 0, 229, 230, 231, 232, 233, + 234, 0, 235, 236, 237, 238, 239, 240, 241, 242, + 846, 847, 0, 848, 0, 246, 247, 248, 249, 250, + 251, 252, 253, 254, 255, 0, 1649, 256, 257, 258, + 259, 0, 260, 261, 262, 849, 850, 263, 264, 265, + 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, + 286, 851, 288, 852, 290, 291, 292, 293, 853, 294, + 295, 296, 297, 854, 855, 299, 856, 301, 302, 303, + 0, 304, 305, 0, 0, 857, 307, 308, 0, 0, + 309, 310, 311, 312, 313, 858, 315, 316, 317, 318, + 319, 320, 321, 322, 323, 324, 0, 325, 326, 859, + 328, 329, 330, 331, 332, 333, 0, 334, 335, 336, + 337, 338, 339, 0, 340, 341, 342, 860, 344, 345, + 346, 347, 0, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 0, 361, 362, 363, + 364, 365, 366, 861, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 0, 379, 380, 381, 382, + 383, 862, 384, 385, 386, 387, 388, 389, 390, 391, + 863, 393, 0, 394, 395, 396, 397, 398, 399, 400, + 401, 402, 403, 404, 405, 406, 864, 408, 0, 409, + 410, 0, 411, 412, 413, 414, 415, 416, 417, 0, + 865, 866, 0, 1650, 420, 421, 867, 423, 868, 869, + 425, 426, 870, 428, 429, 430, 431, 432, 0, 0, + 433, 434, 435, 436, 437, 871, 0, 438, 439, 440, + 441, 442, 443, 872, 0, 445, 446, 447, 448, 449, + 450, 0, 0, 451, 0, 0, 452, 453, 454, 455, + 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 873, 0, 0, + 0, 0, 0, 0, 874, 875, 0, 0, 0, 0, + 0, 877, 0, 878, 0, 0, 0, 0, 879, 0, + 880, 881, 92, 814, 547, 815, 816, 817, 818, 819, + 0, 0, 0, 0, 0, 0, 0, 0, 93, 94, + 95, 96, 97, 98, 99, 100, -935, 101, 102, 103, + 0, 0, 0, -935, 820, 0, 0, 104, 105, 0, + 106, 107, 108, 109, 110, 111, 112, 113, 821, 115, + 822, 823, 0, 118, 119, 120, 121, 122, 123, 824, + 825, 124, 125, 826, 827, 128, 0, 129, 130, 131, + 132, 828, 0, 829, 0, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 0, 145, 146, 147, 148, + 149, 150, 0, 151, 152, 153, 154, 830, 831, 832, + 833, 834, 835, 836, 156, 157, 158, 159, 160, 161, + 162, 837, 838, 165, 839, 166, 0, 167, 168, 169, + 170, 171, 172, 0, 173, 174, 175, 176, 177, 0, + 0, 178, 179, 675, 181, 182, 0, 183, 184, 185, + 0, 186, 187, 188, 0, 189, 190, 191, 192, 840, + 194, 195, 196, 197, 841, 842, 199, 0, 200, 201, + 843, 203, 0, 204, 0, 205, 206, 0, 207, 208, + 209, 210, 211, 212, 0, 213, 0, 844, 845, 216, + 0, 217, 218, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 228, 0, 229, 230, 231, 232, 233, 234, + 0, 235, 236, 237, 238, 239, 240, 241, 242, 846, + 847, 0, 848, 0, 246, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 0, 0, 256, 257, 258, 259, + 0, 260, 261, 262, 849, 850, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 851, 288, 852, 290, 291, 292, 293, 853, 294, 295, + 296, 297, 854, 855, 299, 856, 301, 302, 303, 0, + 304, 305, 0, 0, 857, 307, 308, 0, 0, 309, + 310, 311, 312, 313, 858, 315, 316, 317, 318, 319, + 320, 321, 322, 323, 324, 0, 325, 326, 859, 328, + 329, 330, 331, 332, 333, 0, 334, 335, 336, 337, + 338, 339, 0, 340, 341, 342, 860, 344, 345, 346, + 347, 0, 348, 349, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 0, 361, 362, 363, 364, + 365, 366, 861, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 0, 379, 380, 381, 382, 383, + 862, 384, 385, 386, 387, 388, 389, 390, 391, 863, + 393, -935, 394, 395, 396, 397, 398, 399, 400, 401, + 402, 403, 404, 405, 406, 864, 408, 0, 409, 410, + 0, 411, 412, 413, 414, 415, 416, 417, 0, 865, + 866, 0, 0, 420, 421, 867, 423, 868, 869, 425, + 426, 870, 428, 429, 430, 431, 432, 0, 0, 433, + 434, 435, 436, 437, 871, 0, 438, 439, 440, 441, + 442, 443, 872, 0, 445, 446, 447, 448, 449, 450, + 0, 0, 451, 0, 0, 452, 453, 454, 455, 456, + 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, + 467, 468, 469, 470, 471, 472, 873, 0, 0, 0, + 0, 0, 0, 874, 875, 0, 0, 0, 0, 0, + 877, 0, 878, 0, 0, 0, 0, 879, 0, 880, + 881, 92, 814, 547, 815, 816, 817, 818, 819, 0, + 0, 0, 0, 0, 0, 0, 0, 93, 94, 95, + 96, 97, 98, 99, 100, 1388, 101, 102, 103, 0, + 0, 0, 0, 820, 0, 0, 104, 105, 0, 106, + 107, 108, 109, 110, 111, 112, 113, 821, 115, 822, + 823, 0, 118, 119, 120, 121, 122, 123, 824, 825, + 124, 125, 826, 827, 128, 0, 129, 130, 131, 132, + 828, 0, 829, 0, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 0, 145, 146, 147, 148, 149, + 150, 0, 151, 152, 153, 154, 830, 831, 832, 833, + 834, 835, 836, 156, 157, 158, 159, 160, 161, 162, + 837, 838, 165, 839, 166, 0, 167, 168, 169, 170, + 171, 172, 0, 173, 174, 175, 176, 177, 0, 0, + 178, 179, 675, 181, 182, 0, 183, 184, 185, 0, + 186, 187, 188, 0, 189, 190, 191, 192, 840, 194, + 195, 196, 197, 841, 842, 199, 0, 200, 201, 843, + 203, 0, 204, 0, 205, 206, 0, 207, 208, 209, + 210, 211, 212, 0, 213, 0, 844, 845, 216, 0, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 0, 227, 228, 229, 230, 231, 232, 0, 233, 234, - 235, 236, 237, 238, 239, 838, 839, 0, 840, 0, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 0, 0, 253, 254, 255, 256, 0, 257, 258, 259, - 841, 842, 260, 261, 262, 263, 264, 265, 266, 267, + 227, 228, 0, 229, 230, 231, 232, 233, 234, 0, + 235, 236, 237, 238, 239, 240, 241, 242, 846, 847, + 0, 848, 0, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 0, 0, 256, 257, 258, 259, 0, + 260, 261, 262, 849, 850, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, - 278, 279, 280, 281, 282, 283, 843, 285, 844, 287, - 288, 289, 290, 845, 291, 292, 293, 294, 846, 847, - 296, 848, 298, 299, 300, 0, 301, 302, 0, 0, - 849, 304, 305, 0, 0, 306, 307, 308, 309, 310, - 850, 312, 313, 314, 315, 316, 317, 318, 319, 320, - 321, 0, 322, 323, 851, 325, 326, 327, 328, 329, - 330, 0, 331, 332, 333, 334, 335, 336, 337, 338, - 339, 852, 341, 342, 343, 344, 0, 345, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, 356, 0, - 357, 358, 359, 360, 361, 362, 853, 364, 365, 366, - 367, 368, 369, 370, 371, 372, 373, 374, 25, 375, - 376, 377, 378, 379, 854, 380, 381, 382, 383, 384, - 385, 386, 387, 855, 389, 0, 390, 391, 392, 393, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 856, - 404, 0, 405, 406, 30, 407, 408, 409, 410, 411, - 412, 413, 0, 857, 858, 0, 0, 416, 417, 859, - 419, 860, 861, 421, 422, 862, 424, 425, 426, 427, - 428, 0, 0, 429, 430, 431, 432, 433, 863, 0, - 434, 435, 436, 437, 438, 568, 864, 0, 441, 442, - 443, 444, 445, 446, 0, 0, 447, 0, 33, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 851, + 288, 852, 290, 291, 292, 293, 853, 294, 295, 296, + 297, 854, 855, 299, 856, 301, 302, 303, 0, 304, + 305, 0, 0, 857, 307, 308, 0, 0, 309, 310, + 311, 312, 313, 858, 315, 316, 317, 318, 319, 320, + 321, 322, 323, 324, 0, 325, 326, 859, 328, 329, + 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, + 339, 0, 340, 341, 342, 860, 344, 345, 346, 347, + 0, 348, 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 0, 361, 362, 363, 364, 365, + 366, 861, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 0, 379, 380, 381, 382, 383, 862, + 384, 385, 386, 387, 388, 389, 390, 391, 863, 393, + 0, 394, 395, 396, 397, 398, 399, 400, 401, 402, + 403, 404, 405, 406, 864, 408, 0, 409, 410, 0, + 411, 412, 413, 414, 415, 416, 417, 0, 865, 866, + 0, 0, 420, 421, 867, 423, 868, 869, 425, 426, + 870, 428, 429, 430, 431, 432, 0, 0, 433, 434, + 435, 436, 437, 871, 0, 438, 439, 440, 441, 442, + 443, 872, 0, 445, 446, 447, 448, 449, 450, 0, + 0, 451, 0, 0, 452, 453, 454, 455, 456, 457, + 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 873, 0, 0, 0, 0, + 0, 0, 874, 875, 1389, 0, 0, 0, 0, 877, + 0, 878, 0, 0, 0, 0, 879, 0, 880, 881, + 92, 814, 547, 815, 816, 817, 818, 819, 0, 0, + 0, 0, 0, 0, 0, 0, 93, 94, 95, 96, + 97, 98, 99, 100, 2682, 101, 102, 103, 0, 0, + 0, 0, 820, 0, 0, 104, 105, 0, 106, 107, + 108, 109, 110, 111, 112, 113, 821, 115, 822, 823, + 0, 118, 119, 120, 121, 122, 123, 824, 825, 124, + 125, 826, 827, 128, 0, 129, 130, 131, 132, 828, + 0, 829, 0, 135, 136, 137, 138, 139, 140, 141, + 142, 143, 144, 0, 145, 146, 147, 148, 149, 150, + 0, 151, 152, 2683, 154, 830, 831, 832, 833, 834, + 835, 836, 156, 157, 158, 159, 160, 161, 162, 837, + 838, 165, 839, 166, 0, 167, 168, 169, 170, 171, + 172, 0, 173, 174, 175, 176, 177, 0, 0, 178, + 179, 675, 181, 182, 0, 183, 184, 185, 0, 186, + 187, 188, 0, 189, 190, 191, 192, 840, 194, 195, + 196, 197, 841, 842, 199, 0, 200, 201, 843, 203, + 0, 204, 0, 205, 206, 0, 207, 208, 209, 210, + 211, 212, 0, 213, 0, 2684, 845, 216, 0, 217, + 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 228, 0, 229, 230, 231, 232, 233, 234, 0, 235, + 236, 237, 238, 239, 240, 241, 242, 846, 847, 0, + 848, 0, 246, 247, 248, 249, 250, 251, 252, 253, + 254, 255, 0, 0, 256, 257, 258, 259, 0, 260, + 261, 262, 849, 850, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 851, 288, + 852, 290, 291, 292, 293, 853, 294, 295, 296, 297, + 854, 855, 299, 856, 301, 302, 303, 0, 304, 305, + 0, 0, 857, 307, 308, 0, 0, 309, 310, 311, + 312, 313, 858, 315, 316, 317, 318, 319, 320, 321, + 322, 323, 324, 0, 325, 326, 859, 328, 329, 330, + 331, 332, 333, 0, 334, 335, 336, 337, 338, 339, + 0, 340, 341, 342, 860, 344, 345, 346, 347, 0, + 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, + 358, 359, 360, 0, 361, 362, 363, 364, 365, 2685, + 861, 368, 369, 370, 371, 372, 373, 374, 375, 376, + 377, 378, 0, 379, 380, 381, 382, 383, 862, 384, + 385, 386, 387, 388, 389, 390, 391, 863, 393, 0, + 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, + 404, 405, 406, 864, 408, 0, 409, 410, 0, 411, + 412, 413, 414, 415, 416, 417, 0, 865, 866, 0, + 0, 420, 421, 867, 423, 868, 869, 425, 426, 870, + 428, 429, 430, 431, 432, 0, 0, 433, 434, 435, + 436, 437, 871, 0, 438, 439, 440, 441, 442, 443, + 872, 0, 445, 446, 447, 448, 449, 450, 0, 0, + 451, 0, 0, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, - 865, 0, 34, 0, 0, 0, 0, 866, 867, 0, - 0, 0, 0, 0, 869, 0, 870, 0, 0, 0, - 0, 871, 0, 872, 873, 91, 806, 542, 807, 808, - 809, 810, 811, 0, 0, 0, 0, 0, 0, 0, - 0, 92, 93, 94, 95, 96, 97, 98, 99, 0, - 100, 101, 102, 0, 0, 0, 0, 812, 0, 0, - 103, 104, 0, 105, 106, 107, 108, 109, 110, 111, - 112, 813, 114, 814, 815, 1634, 117, 118, 119, 120, - 121, 122, 816, 817, 123, 124, 818, 819, 127, 0, - 128, 129, 130, 131, 820, 0, 821, 0, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 0, 144, - 145, 146, 147, 148, 149, 0, 150, 151, 152, 153, - 822, 823, 824, 825, 826, 827, 828, 155, 156, 157, - 158, 159, 160, 161, 829, 830, 164, 831, 165, 0, - 166, 167, 168, 169, 170, 171, 0, 172, 173, 174, - 175, 176, 0, 0, 177, 178, 668, 180, 181, 0, - 182, 183, 184, 0, 185, 186, 187, 0, 188, 189, - 190, 191, 832, 193, 194, 195, 196, 833, 834, 198, - 0, 199, 200, 835, 202, 0, 203, 0, 204, 205, - 1635, 206, 207, 208, 209, 210, 211, 0, 212, 0, - 836, 837, 215, 0, 216, 217, 218, 219, 220, 221, - 222, 223, 224, 225, 226, 0, 227, 228, 229, 230, - 231, 232, 0, 233, 234, 235, 236, 237, 238, 239, - 838, 839, 0, 840, 0, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 0, 1636, 253, 254, 255, - 256, 0, 257, 258, 259, 841, 842, 260, 261, 262, + 469, 470, 471, 472, 873, 0, 0, 0, 0, 0, + 0, 874, 875, 2686, 0, 0, 0, 0, 877, 0, + 2687, 0, 0, 0, 0, 879, 0, 880, 881, 92, + 814, 547, 815, 816, 817, 818, 819, 0, 0, 0, + 0, 0, 0, 0, 0, 93, 94, 95, 96, 97, + 98, 99, 100, 0, 101, 102, 103, 0, 0, 0, + 0, 820, 0, 0, 104, 105, 0, 106, 107, 108, + 109, 110, 111, 112, 113, 821, 115, 822, 823, 0, + 118, 119, 120, 121, 122, 123, 824, 825, 124, 125, + 826, 827, 128, 0, 129, 130, 131, 132, 828, 0, + 829, 0, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 0, 145, 146, 147, 148, 149, 150, 0, + 151, 152, 153, 154, 830, 831, 832, 833, 834, 835, + 836, 156, 157, 158, 159, 160, 161, 162, 837, 838, + 165, 839, 166, 0, 167, 168, 169, 170, 171, 172, + 0, 173, 174, 175, 176, 177, 0, 0, 178, 179, + 675, 181, 182, 0, 183, 184, 185, 0, 186, 187, + 188, 0, 189, 190, 191, 192, 840, 194, 195, 196, + 197, 841, 842, 199, 0, 200, 201, 843, 203, 0, + 204, 0, 205, 206, 0, 207, 208, 209, 210, 211, + 212, 0, 213, 0, 844, 845, 216, 0, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 0, 229, 230, 231, 232, 233, 234, 0, 235, 236, + 237, 238, 239, 240, 241, 242, 846, 847, 0, 848, + 0, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 0, 0, 256, 257, 258, 259, 0, 260, 261, + 262, 849, 850, 263, 264, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 851, 288, 852, + 290, 291, 292, 293, 853, 294, 295, 296, 297, 854, + 855, 299, 856, 301, 302, 303, 0, 304, 305, 0, + 0, 857, 307, 308, 0, 0, 309, 310, 311, 312, + 313, 858, 315, 316, 317, 318, 319, 320, 321, 322, + 323, 324, 0, 325, 326, 859, 328, 329, 330, 331, + 332, 333, 0, 334, 335, 336, 337, 338, 339, 0, + 340, 341, 342, 860, 344, 345, 346, 347, 0, 348, + 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, + 359, 360, 0, 361, 362, 363, 364, 365, 366, 861, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 0, 379, 380, 381, 382, 383, 862, 384, 385, + 386, 387, 388, 389, 390, 391, 863, 393, 0, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 405, 406, 864, 408, 0, 409, 410, 0, 411, 412, + 413, 414, 415, 416, 417, 0, 865, 866, 0, 0, + 420, 421, 867, 423, 868, 869, 425, 426, 870, 428, + 429, 430, 431, 432, 0, 0, 433, 434, 435, 436, + 437, 871, 0, 438, 439, 440, 441, 442, 443, 872, + 0, 445, 446, 447, 448, 449, 450, 0, 0, 451, + 0, 0, 452, 453, 454, 455, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 873, 0, 0, 0, 0, 0, 0, + 874, 875, 876, 0, 0, 0, 0, 877, 0, 878, + 0, 0, 0, 0, 879, 0, 880, 881, 92, 1402, + 547, 815, 816, 817, 1403, 819, 0, 0, 0, 0, + 0, 0, 0, 0, 93, 94, 95, 96, 97, 98, + 99, 100, 1404, 101, 102, 103, 0, 0, 0, 0, + 820, 0, 0, 104, 105, 0, 106, 107, 108, 109, + 110, 111, 112, 113, 821, 115, 822, 823, 0, 118, + 119, 120, 121, 122, 123, 824, 825, 124, 125, 826, + 827, 128, 0, 129, 130, 131, 132, 828, 0, 829, + 0, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 0, 145, 146, 147, 148, 149, 150, 0, 151, + 152, 153, 154, 830, 831, 832, 833, 834, 835, 836, + 156, 157, 158, 159, 160, 161, 162, 837, 838, 165, + 839, 166, 0, 167, 168, 169, 170, 171, 172, 0, + 173, 174, 175, 176, 177, 0, 0, 178, 179, 675, + 181, 182, 0, 183, 184, 185, 0, 186, 187, 188, + 0, 189, 190, 191, 192, 840, 194, 195, 196, 197, + 841, 842, 199, 0, 200, 201, 843, 203, 0, 204, + 0, 205, 206, 0, 207, 208, 209, 210, 211, 212, + 0, 213, 0, 844, 845, 216, 0, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228, 0, + 229, 230, 231, 232, 233, 234, 0, 235, 236, 237, + 238, 239, 240, 241, 242, 846, 847, 0, 848, 0, + 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, + 0, 0, 256, 257, 258, 259, 0, 260, 261, 262, + 849, 850, 263, 264, 265, 266, 267, 268, 269, 270, + 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, + 281, 282, 283, 284, 285, 286, 851, 288, 852, 290, + 291, 292, 293, 853, 294, 295, 296, 297, 854, 855, + 299, 856, 301, 302, 303, 0, 304, 305, 0, 0, + 857, 307, 308, 0, 0, 309, 310, 311, 312, 313, + 858, 315, 316, 317, 318, 319, 320, 321, 322, 323, + 324, 0, 325, 326, 859, 328, 329, 330, 331, 332, + 333, 0, 334, 335, 336, 337, 338, 339, 0, 340, + 341, 342, 860, 344, 345, 346, 347, 0, 348, 349, + 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, + 360, 0, 361, 362, 363, 364, 365, 366, 861, 368, + 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, + 0, 379, 380, 381, 382, 383, 862, 384, 385, 386, + 387, 388, 389, 390, 391, 863, 393, 0, 394, 395, + 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, + 406, 864, 408, 0, 409, 410, 0, 411, 412, 413, + 414, 415, 416, 417, 0, 865, 866, 0, 0, 420, + 421, 867, 423, 868, 869, 425, 426, 870, 428, 429, + 430, 431, 432, 0, 0, 433, 434, 435, 436, 437, + 871, 0, 438, 439, 440, 441, 442, 443, 872, 0, + 445, 446, 447, 448, 449, 450, 0, 0, 451, 0, + 0, 452, 453, 454, 455, 456, 457, 458, 459, 460, + 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, + 471, 472, 873, 0, 0, 0, 0, 0, 0, 874, + 875, 0, 0, 0, 0, 0, 877, 0, 878, 0, + 0, 0, 0, 879, 0, 880, 881, 1009, 814, 547, + 815, 816, 817, 818, 819, 0, 0, 0, 0, 0, + 0, 0, 0, 93, 94, 95, 96, 97, 98, 99, + 100, 0, 101, 102, 103, 0, 0, 0, 0, 820, + 0, 0, 104, 105, 0, 106, 107, 108, 1011, 110, + 111, 112, 113, 821, 1012, 822, 823, 0, 118, 119, + 120, 121, 122, 123, 824, 825, 124, 125, 826, 827, + 128, 0, 129, 130, 131, 132, 828, 0, 1013, 0, + 135, 136, 137, 138, 139, 140, 1014, 142, 143, 144, + 0, 145, 146, 147, 148, 149, 150, 0, 1015, 152, + 153, 154, 830, 831, 832, 1016, 834, 835, 836, 156, + 157, 158, 159, 160, 161, 162, 837, 838, 165, 839, + 166, 0, 167, 168, 169, 170, 171, 172, 0, 173, + 174, 175, 176, 177, 0, 0, 178, 179, 675, 181, + 182, 0, 183, 184, 185, 0, 186, 187, 188, 0, + 189, 190, 191, 192, 840, 194, 195, 196, 197, 841, + 842, 199, 0, 200, 201, 843, 203, 0, 204, 0, + 205, 1018, 0, 1019, 208, 209, 210, 1020, 212, 0, + 213, 0, 844, 845, 216, 0, 217, 218, 219, 220, + 221, 222, 223, 1021, 225, 226, 227, 228, 0, 229, + 230, 231, 232, 233, 234, 0, 235, 1022, 237, 238, + 239, 240, 241, 242, 846, 847, 0, 848, 0, 246, + 1023, 1024, 249, 1025, 251, 252, 253, 254, 255, 0, + 0, 256, 1026, 258, 1027, 0, 260, 261, 262, 849, + 850, 263, 264, 265, 266, 267, 1028, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 851, 1029, 852, 290, 291, + 292, 293, 853, 294, 295, 1030, 297, 854, 855, 299, + 856, 301, 302, 303, 0, 304, 305, 0, 0, 857, + 307, 308, 0, 0, 309, 310, 1031, 312, 1032, 858, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 0, 325, 326, 859, 328, 329, 330, 331, 332, 333, + 0, 334, 335, 336, 337, 338, 339, 0, 340, 341, + 342, 860, 344, 345, 346, 347, 0, 348, 349, 350, + 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, + 0, 361, 362, 1033, 364, 365, 366, 861, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 0, + 379, 380, 381, 382, 383, 862, 384, 385, 386, 387, + 388, 1034, 390, 391, 863, 393, 0, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, 404, 1035, 406, + 864, 408, 0, 409, 410, 0, 411, 1036, 413, 414, + 415, 416, 417, 0, 865, 866, 0, 0, 420, 421, + 867, 423, 868, 869, 425, 426, 1037, 428, 429, 430, + 431, 432, 0, 0, 433, 434, 435, 436, 437, 871, + 0, 438, 439, 440, 441, 442, 443, 872, 0, 445, + 1039, 447, 448, 449, 450, 0, 0, 451, 0, 0, + 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 873, 0, 0, 0, 0, 0, 0, 874, 875, + 0, 0, 0, 0, 0, 877, 0, 878, 1521, 0, + 0, 0, 879, 0, 880, 881, 92, 814, 547, 815, + 816, 817, 818, 819, 0, 0, 0, 0, 0, 0, + 0, 0, 93, 94, 95, 96, 97, 98, 99, 100, + 0, 101, 102, 103, 0, 0, 0, 0, 820, 0, + 0, 104, 105, 0, 106, 107, 108, 109, 110, 111, + 112, 113, 821, 115, 822, 823, 0, 118, 119, 120, + 121, 122, 123, 824, 825, 124, 125, 826, 827, 128, + 0, 129, 130, 131, 132, 828, 0, 829, 0, 135, + 136, 137, 138, 139, 140, 141, 142, 143, 144, 0, + 145, 146, 147, 148, 149, 150, 0, 151, 152, 153, + 154, 830, 831, 832, 833, 834, 835, 836, 156, 157, + 158, 159, 160, 161, 162, 837, 838, 165, 839, 166, + 0, 167, 168, 169, 170, 171, 172, 0, 173, 174, + 175, 176, 177, 0, 0, 178, 179, 675, 181, 182, + 0, 183, 184, 185, 0, 186, 187, 188, 0, 189, + 190, 191, 192, 840, 194, 195, 196, 197, 841, 842, + 199, 0, 200, 201, 843, 203, 0, 204, 0, 205, + 206, 0, 207, 208, 209, 210, 211, 212, 0, 213, + 0, 844, 845, 216, 0, 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 228, 0, 229, 230, + 231, 232, 233, 234, 0, 235, 236, 237, 238, 239, + 240, 241, 242, 846, 847, 0, 848, 0, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, 0, 0, + 256, 257, 258, 259, 0, 260, 261, 262, 849, 850, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, - 283, 843, 285, 844, 287, 288, 289, 290, 845, 291, - 292, 293, 294, 846, 847, 296, 848, 298, 299, 300, - 0, 301, 302, 0, 0, 849, 304, 305, 0, 0, - 306, 307, 308, 309, 310, 850, 312, 313, 314, 315, - 316, 317, 318, 319, 320, 321, 0, 322, 323, 851, - 325, 326, 327, 328, 329, 330, 0, 331, 332, 333, - 334, 335, 336, 337, 338, 339, 852, 341, 342, 343, - 344, 0, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 0, 357, 358, 359, 360, 361, - 362, 853, 364, 365, 366, 367, 368, 369, 370, 371, - 372, 373, 374, 0, 375, 376, 377, 378, 379, 854, - 380, 381, 382, 383, 384, 385, 386, 387, 855, 389, - 0, 390, 391, 392, 393, 394, 395, 396, 397, 398, - 399, 400, 401, 402, 856, 404, 0, 405, 406, 0, - 407, 408, 409, 410, 411, 412, 413, 0, 857, 858, - 0, 1637, 416, 417, 859, 419, 860, 861, 421, 422, - 862, 424, 425, 426, 427, 428, 0, 0, 429, 430, - 431, 432, 433, 863, 0, 434, 435, 436, 437, 438, - 439, 864, 0, 441, 442, 443, 444, 445, 446, 0, - 0, 447, 0, 0, 448, 449, 450, 451, 452, 453, + 283, 284, 285, 286, 851, 288, 852, 290, 291, 292, + 293, 853, 294, 295, 296, 297, 854, 855, 299, 856, + 301, 302, 303, 0, 304, 305, 0, 0, 857, 307, + 308, 0, 0, 309, 310, 311, 312, 313, 858, 315, + 316, 317, 318, 319, 320, 321, 322, 323, 324, 0, + 325, 326, 859, 328, 329, 330, 331, 332, 333, 0, + 334, 335, 336, 337, 338, 339, 0, 340, 341, 342, + 860, 344, 345, 346, 347, 0, 348, 349, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 0, + 361, 362, 363, 364, 365, 366, 861, 368, 369, 370, + 371, 372, 373, 374, 375, 376, 377, 378, 0, 379, + 380, 381, 382, 383, 862, 384, 385, 386, 387, 388, + 389, 390, 391, 863, 393, 0, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, 404, 405, 406, 864, + 408, 0, 409, 410, 0, 411, 412, 413, 414, 415, + 416, 417, 0, 865, 866, 0, 0, 420, 421, 867, + 423, 868, 869, 425, 426, 870, 428, 429, 430, 431, + 432, 0, 0, 433, 434, 435, 436, 437, 871, 0, + 438, 439, 440, 441, 442, 443, 872, 0, 445, 446, + 447, 448, 449, 450, 0, 0, 451, 0, 0, 452, + 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, + 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, + 873, 0, 0, 0, 0, 0, 0, 874, 875, 0, + 0, 0, 0, 0, 877, 0, 878, 1641, 0, 0, + 0, 879, 0, 880, 881, 1009, 814, 547, 815, 816, + 817, 818, 819, 0, 0, 0, 0, 0, 0, 0, + 0, 93, 94, 95, 96, 97, 98, 99, 100, 0, + 101, 102, 103, 0, 0, 0, 0, 820, 0, 0, + 104, 105, 0, 106, 107, 108, 1011, 110, 111, 112, + 113, 821, 1012, 822, 823, 0, 118, 119, 120, 121, + 122, 123, 824, 825, 124, 125, 826, 827, 128, 0, + 129, 130, 131, 132, 828, 0, 1013, 0, 135, 136, + 137, 138, 139, 140, 1014, 142, 143, 144, 0, 145, + 146, 147, 148, 149, 150, 0, 1015, 152, 153, 154, + 830, 831, 832, 1016, 834, 835, 836, 156, 157, 158, + 159, 160, 161, 162, 837, 838, 165, 839, 166, 0, + 167, 168, 169, 170, 171, 172, 0, 173, 174, 175, + 176, 177, 0, 0, 178, 179, 675, 181, 182, 0, + 183, 184, 185, 0, 186, 187, 188, 0, 189, 190, + 191, 192, 840, 194, 195, 196, 197, 841, 842, 199, + 0, 200, 201, 843, 203, 0, 204, 0, 205, 1018, + 0, 1019, 208, 209, 210, 1020, 212, 0, 213, 0, + 844, 845, 216, 0, 217, 218, 219, 220, 221, 222, + 223, 1021, 225, 226, 227, 228, 0, 229, 230, 231, + 232, 233, 234, 0, 235, 1022, 237, 238, 239, 240, + 241, 242, 846, 847, 0, 848, 0, 246, 1023, 1024, + 249, 1025, 251, 252, 253, 254, 255, 0, 0, 256, + 1026, 258, 1027, 0, 260, 261, 262, 849, 850, 263, + 264, 265, 266, 267, 1028, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + 284, 285, 286, 851, 1029, 852, 290, 291, 292, 293, + 853, 294, 295, 1030, 297, 854, 855, 299, 856, 301, + 302, 303, 0, 304, 305, 0, 0, 857, 307, 308, + 0, 0, 309, 310, 1031, 312, 1032, 858, 315, 316, + 317, 318, 319, 320, 321, 322, 323, 324, 0, 325, + 326, 859, 328, 329, 330, 331, 332, 333, 0, 334, + 335, 336, 337, 338, 339, 0, 340, 341, 342, 860, + 344, 345, 346, 347, 0, 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 0, 361, + 362, 1033, 364, 365, 366, 861, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 0, 379, 380, + 381, 382, 383, 862, 384, 385, 386, 387, 388, 1034, + 390, 391, 863, 393, 0, 394, 395, 396, 397, 398, + 399, 400, 401, 402, 403, 404, 1035, 406, 864, 408, + 0, 409, 410, 0, 411, 1036, 413, 414, 415, 416, + 417, 0, 865, 866, 0, 0, 420, 421, 867, 423, + 868, 869, 425, 426, 1037, 428, 429, 430, 431, 432, + 0, 0, 433, 434, 435, 436, 437, 871, 0, 438, + 439, 440, 441, 442, 443, 872, 1861, 445, 1039, 447, + 448, 449, 450, 0, 0, 451, 0, 0, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 865, 0, 0, 0, 0, - 0, 0, 866, 867, 0, 0, 0, 0, 0, 869, - 0, 870, 0, 0, 0, 0, 871, 0, 872, 873, - 91, 806, 542, 807, 808, 809, 810, 811, 0, 0, - 0, 0, 0, 0, 0, 0, 92, 93, 94, 95, - 96, 97, 98, 99, 0, 100, 101, 102, 0, 0, - 0, 0, 812, 0, 0, 103, 104, 0, 105, 106, - 107, 108, 109, 110, 111, 112, 813, 114, 814, 815, - 0, 117, 118, 119, 120, 121, 122, 816, 817, 123, - 124, 818, 819, 127, 0, 128, 129, 130, 131, 820, - 0, 821, 0, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 0, 144, 145, 146, 147, 148, 149, - 0, 150, 151, 152, 153, 822, 823, 824, 825, 826, - 827, 828, 155, 156, 157, 158, 159, 160, 161, 829, - 830, 164, 831, 165, 0, 166, 167, 168, 169, 170, - 171, 0, 172, 173, 174, 175, 176, 0, 0, 177, - 178, 668, 180, 181, 0, 182, 183, 184, 0, 185, - 186, 187, 0, 188, 189, 190, 191, 832, 193, 194, - 195, 196, 833, 834, 198, 0, 199, 200, 835, 202, - 0, 203, 0, 204, 205, 0, 206, 207, 208, 209, - 210, 211, 0, 212, 0, 836, 837, 215, 0, 216, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 873, + 0, 0, 0, 0, 0, 0, 874, 875, 0, 0, + 0, 0, 0, 877, 0, 878, 0, 0, 0, 0, + 879, 0, 880, 881, 92, 814, 547, 815, 816, 817, + 818, 819, 0, 0, 0, 0, 0, 0, 0, 0, + 93, 94, 95, 96, 97, 98, 99, 100, 0, 101, + 102, 103, 0, 0, 0, 0, 820, 0, 0, 104, + 105, 0, 106, 107, 108, 109, 110, 111, 112, 113, + 821, 115, 822, 823, 0, 118, 119, 120, 121, 122, + 123, 824, 825, 124, 125, 826, 827, 128, 0, 129, + 130, 131, 132, 828, 0, 829, 0, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 0, 145, 146, + 147, 148, 149, 150, 0, 151, 152, 153, 154, 830, + 831, 832, 833, 834, 835, 836, 156, 157, 158, 159, + 160, 161, 162, 837, 838, 165, 839, 166, 0, 167, + 168, 169, 170, 171, 172, 0, 173, 174, 175, 176, + 177, 0, 0, 178, 179, 675, 181, 182, 0, 183, + 184, 185, 0, 186, 187, 188, 0, 189, 190, 191, + 192, 840, 194, 195, 196, 197, 841, 842, 199, 0, + 200, 201, 843, 203, 0, 204, 0, 205, 206, 1648, + 207, 208, 209, 210, 211, 212, 0, 213, 0, 844, + 845, 216, 0, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 0, 229, 230, 231, 232, + 233, 234, 0, 235, 236, 237, 238, 239, 240, 241, + 242, 846, 847, 0, 848, 0, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 0, 0, 256, 257, + 258, 259, 0, 260, 261, 262, 849, 850, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 851, 288, 852, 290, 291, 292, 293, 853, + 294, 295, 296, 297, 854, 855, 299, 856, 301, 302, + 303, 0, 304, 305, 0, 0, 857, 307, 308, 0, + 0, 309, 310, 311, 312, 313, 858, 315, 316, 317, + 318, 319, 320, 321, 322, 323, 324, 0, 325, 326, + 859, 328, 329, 330, 331, 332, 333, 0, 334, 335, + 336, 337, 338, 339, 0, 340, 341, 342, 860, 344, + 345, 346, 347, 0, 348, 349, 350, 351, 352, 353, + 354, 355, 356, 357, 358, 359, 360, 0, 361, 362, + 363, 364, 365, 366, 861, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, 378, 0, 379, 380, 381, + 382, 383, 862, 384, 385, 386, 387, 388, 389, 390, + 391, 863, 393, 0, 394, 395, 396, 397, 398, 399, + 400, 401, 402, 403, 404, 405, 406, 864, 408, 0, + 409, 410, 0, 411, 412, 413, 414, 415, 416, 417, + 0, 865, 866, 0, 0, 420, 421, 867, 423, 868, + 869, 425, 426, 870, 428, 429, 430, 431, 432, 0, + 0, 433, 434, 435, 436, 437, 871, 0, 438, 439, + 440, 441, 442, 443, 872, 0, 445, 446, 447, 448, + 449, 450, 0, 0, 451, 0, 0, 452, 453, 454, + 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, + 465, 466, 467, 468, 469, 470, 471, 472, 873, 0, + 0, 0, 0, 0, 0, 874, 875, 0, 0, 0, + 0, 0, 877, 0, 878, 0, 0, 0, 0, 879, + 0, 880, 881, 92, 814, 547, 815, 816, 817, 818, + 819, 0, 0, 0, 0, 0, 0, 0, 0, 93, + 94, 95, 96, 97, 98, 99, 100, 0, 101, 102, + 103, 0, 0, 0, 0, 820, 0, 0, 104, 105, + 0, 106, 107, 108, 109, 110, 111, 112, 113, 821, + 115, 822, 823, 0, 118, 119, 120, 121, 122, 123, + 824, 825, 124, 125, 826, 827, 128, 0, 129, 130, + 131, 132, 828, 0, 829, 0, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 0, 145, 146, 147, + 148, 149, 150, 0, 151, 152, 153, 154, 830, 831, + 832, 833, 834, 835, 836, 156, 157, 158, 159, 160, + 161, 162, 837, 838, 165, 839, 166, 0, 167, 168, + 169, 170, 171, 172, 0, 173, 174, 175, 176, 177, + 0, 0, 178, 179, 675, 181, 182, 0, 183, 184, + 185, 0, 186, 187, 188, 0, 189, 190, 191, 192, + 840, 194, 195, 196, 197, 841, 842, 199, 0, 200, + 201, 843, 203, 0, 204, 0, 205, 206, 0, 207, + 208, 209, 210, 211, 212, 0, 213, 0, 844, 845, + 216, 0, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 0, 229, 230, 231, 232, 233, + 234, 0, 235, 236, 237, 238, 239, 240, 241, 242, + 846, 847, 0, 848, 0, 246, 247, 248, 249, 250, + 251, 252, 253, 254, 255, 0, 0, 256, 257, 258, + 259, 0, 260, 261, 262, 849, 850, 263, 264, 265, + 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, + 286, 851, 288, 852, 290, 291, 292, 293, 853, 294, + 295, 296, 297, 854, 855, 299, 856, 301, 302, 303, + 0, 304, 305, 0, 0, 857, 307, 308, 0, 0, + 309, 310, 311, 312, 313, 858, 315, 316, 317, 318, + 319, 320, 321, 322, 323, 324, 0, 325, 326, 859, + 328, 329, 330, 331, 332, 333, 0, 334, 335, 336, + 337, 338, 339, 0, 340, 341, 342, 860, 344, 345, + 346, 347, 0, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 0, 361, 362, 363, + 364, 365, 366, 861, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 0, 379, 380, 381, 382, + 383, 862, 384, 385, 386, 387, 388, 389, 390, 391, + 863, 393, 0, 394, 395, 396, 397, 398, 399, 400, + 401, 402, 403, 404, 405, 406, 864, 408, 0, 409, + 410, 0, 411, 412, 413, 414, 415, 416, 417, 0, + 865, 866, 0, 0, 420, 421, 867, 423, 868, 869, + 425, 426, 870, 428, 429, 430, 431, 432, 0, 0, + 433, 434, 435, 436, 437, 871, 0, 438, 439, 440, + 441, 442, 443, 872, 0, 445, 446, 447, 448, 449, + 450, 0, 0, 451, 0, 0, 452, 453, 454, 455, + 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 873, 0, 0, + 0, 0, 0, 0, 874, 875, 0, 0, 0, 0, + 0, 877, 0, 878, 0, 0, 0, 0, 879, 0, + 880, 881, 1009, 814, 547, 815, 816, 817, 818, 819, + 0, 0, 0, 0, 0, 0, 0, 0, 93, 94, + 95, 96, 97, 98, 99, 100, 0, 101, 102, 103, + 0, 0, 0, 0, 820, 0, 0, 104, 105, 0, + 106, 107, 108, 1011, 110, 111, 112, 113, 821, 1012, + 822, 823, 0, 118, 119, 120, 121, 122, 123, 824, + 825, 124, 125, 826, 827, 128, 0, 129, 130, 131, + 132, 828, 0, 1013, 0, 135, 136, 137, 138, 139, + 140, 1014, 142, 143, 144, 0, 145, 146, 147, 148, + 149, 150, 0, 1015, 152, 153, 154, 830, 831, 832, + 1016, 834, 835, 836, 156, 157, 158, 159, 160, 161, + 162, 837, 838, 165, 839, 166, 0, 167, 168, 169, + 170, 171, 172, 0, 173, 174, 175, 176, 177, 0, + 0, 178, 179, 675, 181, 182, 0, 183, 184, 185, + 0, 186, 187, 188, 0, 189, 190, 191, 192, 840, + 194, 195, 196, 197, 841, 842, 199, 0, 200, 201, + 843, 203, 0, 204, 0, 205, 1018, 0, 1019, 208, + 209, 210, 1020, 212, 0, 213, 0, 844, 845, 216, + 0, 217, 218, 219, 220, 221, 222, 223, 1021, 225, + 226, 227, 228, 0, 229, 230, 231, 232, 233, 234, + 0, 235, 1022, 237, 238, 239, 240, 241, 242, 846, + 847, 0, 848, 0, 246, 1023, 1024, 249, 1025, 251, + 252, 253, 254, 255, 0, 0, 256, 1026, 258, 1027, + 0, 260, 261, 262, 849, 850, 263, 264, 265, 266, + 267, 1028, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 851, 1029, 852, 290, 291, 292, 293, 853, 294, 295, + 1030, 297, 854, 855, 299, 856, 301, 302, 303, 0, + 304, 305, 0, 0, 857, 307, 308, 0, 0, 309, + 310, 1031, 312, 1032, 858, 315, 316, 317, 318, 319, + 320, 321, 322, 323, 324, 0, 325, 326, 859, 328, + 329, 330, 331, 332, 333, 0, 334, 335, 336, 337, + 338, 339, 0, 340, 341, 342, 860, 344, 345, 346, + 347, 0, 348, 349, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 0, 361, 362, 1033, 364, + 365, 366, 861, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 0, 379, 380, 381, 382, 383, + 862, 384, 385, 386, 387, 388, 1034, 390, 391, 863, + 393, 0, 394, 395, 396, 397, 398, 399, 400, 401, + 402, 403, 404, 1035, 406, 864, 408, 0, 409, 410, + 0, 411, 1036, 413, 414, 415, 416, 417, 0, 865, + 866, 0, 0, 420, 421, 867, 423, 868, 869, 425, + 426, 1037, 428, 429, 430, 431, 432, 0, 0, 433, + 434, 435, 436, 437, 871, 0, 438, 439, 440, 441, + 442, 443, 872, 0, 445, 1039, 447, 448, 449, 450, + 0, 0, 451, 0, 0, 452, 453, 454, 455, 456, + 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, + 467, 468, 469, 470, 471, 472, 873, 0, 0, 0, + 0, 0, 0, 874, 875, 0, 0, 0, 0, 0, + 877, 0, 878, 0, 0, 0, 0, 879, 0, 880, + 881, 92, 814, 547, 815, 816, 817, 818, 819, 0, + 0, 0, 0, 0, 0, 0, 0, 93, 94, 95, + 96, 97, 98, 99, 100, 0, 101, 102, 103, 0, + 0, 0, 0, 820, 0, 0, 104, 105, 0, 106, + 107, 108, 109, 110, 111, 112, 113, 821, 115, 822, + 823, 0, 118, 119, 120, 121, 122, 123, 824, 825, + 124, 125, 826, 827, 128, 0, 129, 130, 131, 132, + 828, 0, 829, 0, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 0, 145, 146, 147, 148, 149, + 150, 0, 151, 152, 153, 154, 830, 831, 832, 833, + 834, 835, 836, 156, 157, 158, 159, 160, 161, 162, + 837, 838, 165, 839, 166, 0, 167, 168, 169, 170, + 171, 172, 0, 173, 174, 175, 176, 177, 0, 0, + 178, 179, 675, 181, 182, 0, 183, 184, 185, 0, + 186, 187, 188, 0, 189, 190, 191, 192, 840, 194, + 195, 196, 197, 841, 842, 199, 0, 200, 201, 843, + 203, 0, 204, 0, 205, 206, 0, 207, 208, 209, + 210, 211, 212, 0, 213, 0, 844, 845, 216, 0, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 0, 227, 228, 229, 230, 231, 232, 0, 233, 234, - 235, 236, 237, 238, 239, 838, 839, 0, 840, 0, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 0, 0, 253, 254, 255, 256, 0, 257, 258, 259, - 841, 842, 260, 261, 262, 263, 264, 265, 266, 267, + 227, 228, 0, 229, 230, 231, 232, 233, 234, 0, + 235, 236, 237, 238, 239, 240, 241, 242, 846, 847, + 0, 848, 0, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 0, 0, 256, 257, 258, 259, 0, + 260, 261, 262, 849, 850, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, - 278, 279, 280, 281, 282, 283, 843, 285, 844, 287, - 288, 289, 290, 845, 291, 292, 293, 294, 846, 847, - 296, 848, 298, 299, 300, 0, 301, 302, 0, 0, - 849, 304, 305, 0, 0, 306, 307, 308, 309, 310, - 850, 312, 313, 314, 315, 316, 317, 318, 319, 320, - 321, 0, 322, 323, 851, 325, 326, 327, 328, 329, - 330, 0, 331, 332, 333, 334, 335, 336, 337, 338, - 339, 852, 341, 342, 343, 344, 0, 345, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, 356, 0, - 357, 358, 359, 360, 361, 362, 853, 364, 365, 366, - 367, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 376, 377, 378, 379, 854, 380, 381, 382, 383, 384, - 385, 386, 387, 855, 389, 0, 390, 391, 392, 393, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 856, - 404, 0, 405, 406, 0, 407, 408, 409, 410, 411, - 412, 413, 0, 857, 858, 0, 0, 416, 417, 859, - 419, 860, 861, 421, 422, 862, 424, 425, 426, 427, - 428, 0, 0, 429, 430, 431, 432, 433, 863, 0, - 434, 435, 436, 437, 438, 439, 864, 0, 441, 442, - 443, 444, 445, 446, 0, 0, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, - 865, 0, 0, 0, 0, 0, 0, 866, 867, 868, - 0, 0, 0, 0, 869, 0, 870, 0, 0, 0, - 0, 871, 0, 872, 873, 91, 806, 542, 807, 808, - 809, 810, 811, 0, 0, 0, 0, 0, 0, 0, - 0, 92, 93, 94, 95, 96, 97, 98, 99, 1391, - 100, 101, 102, 0, 0, 0, 0, 812, 0, 0, - 103, 104, 0, 105, 106, 107, 108, 109, 110, 111, - 112, 813, 114, 814, 815, 0, 117, 118, 119, 120, - 121, 122, 816, 817, 123, 124, 818, 819, 127, 0, - 128, 129, 130, 131, 820, 0, 821, 0, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 0, 144, - 145, 146, 147, 148, 149, 0, 150, 151, 152, 153, - 822, 823, 824, 825, 826, 827, 828, 155, 156, 157, - 158, 159, 160, 161, 829, 830, 164, 831, 165, 0, - 166, 167, 168, 169, 170, 171, 0, 172, 173, 174, - 175, 176, 0, 0, 177, 178, 668, 180, 181, 0, - 182, 183, 184, 0, 185, 186, 187, 0, 188, 189, - 190, 191, 832, 193, 194, 195, 196, 833, 834, 198, - 0, 199, 200, 835, 202, 0, 203, 0, 204, 205, - 0, 206, 207, 208, 209, 210, 211, 0, 212, 0, - 836, 837, 215, 0, 216, 217, 218, 219, 220, 221, - 222, 223, 224, 225, 226, 0, 227, 228, 229, 230, - 231, 232, 0, 233, 234, 235, 236, 237, 238, 239, - 838, 839, 0, 840, 0, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 0, 0, 253, 254, 255, - 256, 0, 257, 258, 259, 841, 842, 260, 261, 262, - 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, - 283, 843, 285, 844, 287, 288, 289, 290, 845, 291, - 292, 293, 294, 846, 847, 296, 848, 298, 299, 300, - 0, 301, 302, 0, 0, 849, 304, 305, 0, 0, - 306, 307, 308, 309, 310, 850, 312, 313, 314, 315, - 316, 317, 318, 319, 320, 321, 0, 322, 323, 851, - 325, 326, 327, 328, 329, 330, 0, 331, 332, 333, - 334, 335, 336, 337, 338, 339, 852, 341, 342, 343, - 344, 0, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 0, 357, 358, 359, 360, 361, - 362, 853, 364, 365, 366, 367, 368, 369, 370, 371, - 372, 373, 374, 0, 375, 376, 377, 378, 379, 854, - 380, 381, 382, 383, 384, 385, 386, 387, 855, 389, - 0, 390, 391, 392, 393, 394, 395, 396, 397, 398, - 399, 400, 401, 402, 856, 404, 0, 405, 406, 0, - 407, 408, 409, 410, 411, 412, 413, 0, 857, 858, - 0, 0, 416, 417, 859, 419, 860, 861, 421, 422, - 862, 424, 425, 426, 427, 428, 0, 0, 429, 430, - 431, 432, 433, 863, 0, 434, 435, 436, 437, 438, - 439, 864, 0, 441, 442, 443, 444, 445, 446, 0, - 0, 447, 0, 0, 448, 449, 450, 451, 452, 453, - 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 865, 0, 0, 0, 0, - 0, 0, 866, 867, 0, 0, 0, 0, 0, 869, - 0, 870, 0, 0, 0, 0, 871, 0, 872, 873, - 1001, 806, 542, 807, 808, 809, 810, 811, 0, 0, - 0, 0, 0, 0, 0, 0, 92, 93, 94, 95, - 96, 97, 98, 99, 0, 100, 101, 102, 0, 0, - 0, 0, 812, 0, 0, 103, 104, 0, 105, 106, - 107, 1003, 109, 110, 111, 112, 813, 1004, 814, 815, - 0, 117, 118, 119, 120, 121, 122, 816, 817, 123, - 124, 818, 819, 127, 0, 128, 129, 130, 131, 820, - 0, 1005, 0, 134, 135, 136, 137, 138, 139, 1006, - 141, 142, 143, 0, 144, 145, 146, 147, 148, 149, - 0, 1007, 151, 152, 153, 822, 823, 824, 1008, 826, - 827, 828, 155, 156, 157, 158, 159, 160, 161, 829, - 830, 164, 831, 165, 0, 166, 167, 168, 169, 170, - 171, 0, 172, 173, 174, 175, 176, 0, 0, 177, - 178, 668, 180, 181, 0, 182, 183, 184, 0, 185, - 186, 187, 0, 188, 189, 190, 191, 832, 193, 194, - 195, 196, 833, 834, 198, 0, 199, 200, 835, 202, - 0, 203, 0, 204, 1010, 0, 1011, 207, 208, 209, - 1012, 211, 0, 212, 0, 836, 837, 215, 0, 216, - 217, 218, 219, 220, 221, 1013, 223, 224, 225, 226, - 0, 227, 228, 229, 230, 231, 232, 0, 233, 1014, - 235, 236, 237, 238, 239, 838, 839, 0, 840, 0, - 243, 1015, 1016, 246, 1017, 248, 249, 250, 251, 252, - 0, 0, 253, 1018, 255, 1019, 0, 257, 258, 259, - 841, 842, 260, 261, 262, 263, 264, 1020, 266, 267, - 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, - 278, 279, 280, 281, 282, 283, 843, 1021, 844, 287, - 288, 289, 290, 845, 291, 292, 1022, 294, 846, 847, - 296, 848, 298, 299, 300, 0, 301, 302, 0, 0, - 849, 304, 305, 0, 0, 306, 307, 1023, 309, 1024, - 850, 312, 313, 314, 315, 316, 317, 318, 319, 320, - 321, 0, 322, 323, 851, 325, 326, 327, 328, 329, - 330, 0, 331, 332, 333, 334, 335, 336, 337, 338, - 339, 852, 341, 342, 343, 344, 0, 345, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, 356, 0, - 357, 358, 1025, 360, 361, 362, 853, 364, 365, 366, - 367, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 376, 377, 378, 379, 854, 380, 381, 382, 383, 384, - 1026, 386, 387, 855, 389, 0, 390, 391, 392, 393, - 394, 395, 396, 397, 398, 399, 400, 1027, 402, 856, - 404, 0, 405, 406, 0, 407, 1028, 409, 410, 411, - 412, 413, 0, 857, 858, 0, 0, 416, 417, 859, - 419, 860, 861, 421, 422, 1029, 424, 425, 426, 427, - 428, 0, 0, 429, 430, 431, 432, 433, 863, 0, - 434, 435, 436, 437, 438, 439, 864, 0, 441, 1031, - 443, 444, 445, 446, 0, 0, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, - 865, 0, 0, 0, 0, 0, 0, 866, 867, 0, - 0, 0, 0, 0, 869, 0, 870, 1508, 0, 0, - 0, 871, 0, 872, 873, 91, 806, 542, 807, 808, - 809, 810, 811, 0, 0, 0, 0, 0, 0, 0, - 0, 92, 93, 94, 95, 96, 97, 98, 99, 0, - 100, 101, 102, 0, 0, 0, 0, 812, 0, 0, - 103, 104, 0, 105, 106, 107, 108, 109, 110, 111, - 112, 813, 114, 814, 815, 0, 117, 118, 119, 120, - 121, 122, 816, 817, 123, 124, 818, 819, 127, 0, - 128, 129, 130, 131, 820, 0, 821, 0, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 0, 144, - 145, 146, 147, 148, 149, 0, 150, 151, 152, 153, - 822, 823, 824, 825, 826, 827, 828, 155, 156, 157, - 158, 159, 160, 161, 829, 830, 164, 831, 165, 0, - 166, 167, 168, 169, 170, 171, 0, 172, 173, 174, - 175, 176, 0, 0, 177, 178, 668, 180, 181, 0, - 182, 183, 184, 0, 185, 186, 187, 0, 188, 189, - 190, 191, 832, 193, 194, 195, 196, 833, 834, 198, - 0, 199, 200, 835, 202, 0, 203, 0, 204, 205, - 0, 206, 207, 208, 209, 210, 211, 0, 212, 0, - 836, 837, 215, 0, 216, 217, 218, 219, 220, 221, - 222, 223, 224, 225, 226, 0, 227, 228, 229, 230, - 231, 232, 0, 233, 234, 235, 236, 237, 238, 239, - 838, 839, 0, 840, 0, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 0, 0, 253, 254, 255, - 256, 0, 257, 258, 259, 841, 842, 260, 261, 262, - 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, - 283, 843, 285, 844, 287, 288, 289, 290, 845, 291, - 292, 293, 294, 846, 847, 296, 848, 298, 299, 300, - 0, 301, 302, 0, 0, 849, 304, 305, 0, 0, - 306, 307, 308, 309, 310, 850, 312, 313, 314, 315, - 316, 317, 318, 319, 320, 321, 0, 322, 323, 851, - 325, 326, 327, 328, 329, 330, 0, 331, 332, 333, - 334, 335, 336, 337, 338, 339, 852, 341, 342, 343, - 344, 0, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 0, 357, 358, 359, 360, 361, - 362, 853, 364, 365, 366, 367, 368, 369, 370, 371, - 372, 373, 374, 0, 375, 376, 377, 378, 379, 854, - 380, 381, 382, 383, 384, 385, 386, 387, 855, 389, - 0, 390, 391, 392, 393, 394, 395, 396, 397, 398, - 399, 400, 401, 402, 856, 404, 0, 405, 406, 0, - 407, 408, 409, 410, 411, 412, 413, 0, 857, 858, - 0, 0, 416, 417, 859, 419, 860, 861, 421, 422, - 862, 424, 425, 426, 427, 428, 0, 0, 429, 430, - 431, 432, 433, 863, 0, 434, 435, 436, 437, 438, - 439, 864, 0, 441, 442, 443, 444, 445, 446, 0, - 0, 447, 0, 0, 448, 449, 450, 451, 452, 453, - 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 865, 0, 0, 0, 0, - 0, 0, 866, 867, 0, 0, 0, 0, 0, 869, - 0, 870, 1628, 0, 0, 0, 871, 0, 872, 873, - 1001, 806, 542, 807, 808, 809, 810, 811, 0, 0, - 0, 0, 0, 0, 0, 0, 92, 93, 94, 95, - 96, 97, 98, 99, 0, 100, 101, 102, 0, 0, - 0, 0, 812, 0, 0, 103, 104, 0, 105, 106, - 107, 1003, 109, 110, 111, 112, 813, 1004, 814, 815, - 0, 117, 118, 119, 120, 121, 122, 816, 817, 123, - 124, 818, 819, 127, 0, 128, 129, 130, 131, 820, - 0, 1005, 0, 134, 135, 136, 137, 138, 139, 1006, - 141, 142, 143, 0, 144, 145, 146, 147, 148, 149, - 0, 1007, 151, 152, 153, 822, 823, 824, 1008, 826, - 827, 828, 155, 156, 157, 158, 159, 160, 161, 829, - 830, 164, 831, 165, 0, 166, 167, 168, 169, 170, - 171, 0, 172, 173, 174, 175, 176, 0, 0, 177, - 178, 668, 180, 181, 0, 182, 183, 184, 0, 185, - 186, 187, 0, 188, 189, 190, 191, 832, 193, 194, - 195, 196, 833, 834, 198, 0, 199, 200, 835, 202, - 0, 203, 0, 204, 1010, 0, 1011, 207, 208, 209, - 1012, 211, 0, 212, 0, 836, 837, 215, 0, 216, - 217, 218, 219, 220, 221, 1013, 223, 224, 225, 226, - 0, 227, 228, 229, 230, 231, 232, 0, 233, 1014, - 235, 236, 237, 238, 239, 838, 839, 0, 840, 0, - 243, 1015, 1016, 246, 1017, 248, 249, 250, 251, 252, - 0, 0, 253, 1018, 255, 1019, 0, 257, 258, 259, - 841, 842, 260, 261, 262, 263, 264, 1020, 266, 267, - 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, - 278, 279, 280, 281, 282, 283, 843, 1021, 844, 287, - 288, 289, 290, 845, 291, 292, 1022, 294, 846, 847, - 296, 848, 298, 299, 300, 0, 301, 302, 0, 0, - 849, 304, 305, 0, 0, 306, 307, 1023, 309, 1024, - 850, 312, 313, 314, 315, 316, 317, 318, 319, 320, - 321, 0, 322, 323, 851, 325, 326, 327, 328, 329, - 330, 0, 331, 332, 333, 334, 335, 336, 337, 338, - 339, 852, 341, 342, 343, 344, 0, 345, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, 356, 0, - 357, 358, 1025, 360, 361, 362, 853, 364, 365, 366, - 367, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 376, 377, 378, 379, 854, 380, 381, 382, 383, 384, - 1026, 386, 387, 855, 389, 0, 390, 391, 392, 393, - 394, 395, 396, 397, 398, 399, 400, 1027, 402, 856, - 404, 0, 405, 406, 0, 407, 1028, 409, 410, 411, - 412, 413, 0, 857, 858, 0, 0, 416, 417, 859, - 419, 860, 861, 421, 422, 1029, 424, 425, 426, 427, - 428, 0, 0, 429, 430, 431, 432, 433, 863, 0, - 434, 435, 436, 437, 438, 439, 864, 1843, 441, 1031, - 443, 444, 445, 446, 0, 0, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 851, + 288, 852, 290, 291, 292, 293, 853, 294, 295, 296, + 297, 854, 855, 299, 856, 301, 302, 303, 0, 304, + 305, 0, 0, 857, 307, 308, 0, 0, 309, 310, + 311, 312, 313, 858, 315, 316, 317, 318, 319, 320, + 321, 322, 323, 324, 0, 325, 326, 859, 328, 329, + 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, + 339, 0, 340, 341, 342, 860, 344, 345, 346, 347, + 0, 348, 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 0, 361, 362, 363, 364, 365, + 366, 861, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 0, 379, 380, 381, 382, 383, 862, + 384, 385, 386, 387, 388, 389, 390, 391, 863, 393, + 0, 394, 395, 396, 397, 398, 399, 400, 401, 402, + 403, 404, 405, 406, 864, 408, 0, 409, 410, 0, + 411, 412, 413, 414, 415, 416, 417, 0, 865, 866, + 0, 0, 420, 421, 867, 423, 868, 869, 425, 426, + 870, 428, 429, 430, 431, 432, 0, 0, 433, 434, + 435, 436, 437, 871, 0, 438, 439, 440, 441, 442, + 443, 872, 0, 445, 446, 447, 448, 449, 450, 0, + 0, 451, 0, 0, 452, 453, 454, 455, 456, 457, + 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 873, 0, 0, 0, 0, + 0, 0, 1407, 1408, 0, 0, 0, 0, 0, 877, + 0, 878, 0, 0, 0, 0, 879, 0, 880, 881, + 92, 1786, 547, 815, 816, 817, 818, 819, 0, 0, + 0, 0, 0, 0, 0, 0, 93, 94, 95, 96, + 97, 98, 99, 100, 0, 101, 102, 103, 0, 0, + 0, 0, 820, 0, 0, 104, 105, 0, 106, 107, + 108, 109, 110, 111, 112, 113, 821, 115, 822, 823, + 0, 118, 119, 120, 121, 122, 123, 824, 825, 124, + 125, 826, 827, 128, 0, 129, 130, 131, 132, 828, + 0, 829, 0, 135, 136, 137, 138, 139, 140, 141, + 142, 143, 144, 0, 145, 146, 147, 148, 149, 150, + 0, 151, 152, 153, 154, 830, 831, 832, 833, 834, + 835, 836, 156, 157, 158, 159, 160, 161, 162, 837, + 838, 165, 839, 166, 0, 167, 168, 169, 170, 171, + 172, 0, 173, 174, 175, 176, 177, 0, 0, 178, + 179, 675, 181, 182, 0, 183, 184, 185, 0, 186, + 187, 188, 0, 189, 190, 191, 192, 840, 194, 195, + 196, 197, 841, 842, 199, 0, 200, 201, 843, 203, + 0, 204, 0, 205, 206, 0, 207, 208, 209, 210, + 211, 212, 0, 213, 0, 844, 845, 216, 0, 217, + 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 228, 0, 229, 230, 231, 232, 233, 234, 0, 235, + 236, 237, 238, 239, 240, 241, 242, 846, 847, 0, + 848, 0, 246, 247, 248, 249, 250, 251, 252, 253, + 254, 255, 0, 0, 256, 257, 258, 259, 0, 260, + 261, 262, 849, 850, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 851, 288, + 852, 290, 291, 292, 293, 853, 294, 295, 296, 297, + 854, 855, 299, 856, 301, 302, 303, 0, 304, 305, + 0, 0, 857, 307, 308, 0, 0, 309, 310, 311, + 312, 313, 858, 315, 316, 317, 318, 319, 320, 321, + 322, 323, 324, 0, 325, 326, 859, 328, 329, 330, + 331, 332, 333, 0, 334, 335, 336, 337, 338, 339, + 0, 340, 341, 342, 860, 344, 345, 346, 347, 0, + 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, + 358, 359, 360, 0, 361, 362, 363, 364, 365, 366, + 861, 368, 369, 370, 371, 372, 373, 374, 375, 376, + 377, 378, 0, 379, 380, 381, 382, 383, 862, 384, + 385, 386, 387, 388, 389, 390, 391, 863, 393, 0, + 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, + 404, 405, 406, 864, 408, 0, 409, 410, 0, 411, + 412, 413, 414, 415, 416, 417, 0, 865, 866, 0, + 0, 420, 421, 867, 423, 868, 869, 425, 426, 870, + 428, 429, 430, 431, 432, 0, 0, 433, 434, 435, + 436, 437, 871, 0, 438, 439, 440, 441, 442, 443, + 872, 0, 445, 446, 447, 448, 449, 450, 0, 0, + 451, 0, 0, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, - 865, 0, 0, 0, 0, 0, 0, 866, 867, 0, - 0, 0, 0, 0, 869, 0, 870, 0, 0, 0, - 0, 871, 0, 872, 873, 91, 806, 542, 807, 808, - 809, 810, 811, 0, 0, 0, 0, 0, 0, 0, - 0, 92, 93, 94, 95, 96, 97, 98, 99, 0, - 100, 101, 102, 0, 0, 0, 0, 812, 0, 0, - 103, 104, 0, 105, 106, 107, 108, 109, 110, 111, - 112, 813, 114, 814, 815, 0, 117, 118, 119, 120, - 121, 122, 816, 817, 123, 124, 818, 819, 127, 0, - 128, 129, 130, 131, 820, 0, 821, 0, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 0, 144, - 145, 146, 147, 148, 149, 0, 150, 151, 152, 153, - 822, 823, 824, 825, 826, 827, 828, 155, 156, 157, - 158, 159, 160, 161, 829, 830, 164, 831, 165, 0, - 166, 167, 168, 169, 170, 171, 0, 172, 173, 174, - 175, 176, 0, 0, 177, 178, 668, 180, 181, 0, - 182, 183, 184, 0, 185, 186, 187, 0, 188, 189, - 190, 191, 832, 193, 194, 195, 196, 833, 834, 198, - 0, 199, 200, 835, 202, 0, 203, 0, 204, 205, - 1635, 206, 207, 208, 209, 210, 211, 0, 212, 0, - 836, 837, 215, 0, 216, 217, 218, 219, 220, 221, - 222, 223, 224, 225, 226, 0, 227, 228, 229, 230, - 231, 232, 0, 233, 234, 235, 236, 237, 238, 239, - 838, 839, 0, 840, 0, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 0, 0, 253, 254, 255, - 256, 0, 257, 258, 259, 841, 842, 260, 261, 262, + 469, 470, 471, 472, 873, 0, 0, 0, 0, 0, + 0, 874, 875, 0, 0, 0, 0, 0, 877, 0, + 878, 0, 0, 0, 0, 879, 0, 880, 881, 92, + 814, 547, 815, 816, 817, 818, 819, 0, 0, 0, + 0, 0, 0, 0, 0, 93, 94, 95, 96, 97, + 98, 99, 100, 0, 101, 102, 103, 0, 0, 0, + 0, 820, 0, 0, 104, 105, 0, 106, 107, 108, + 109, 110, 111, 112, 113, 821, 115, 822, 823, 0, + 118, 119, 120, 121, 122, 123, 824, 825, 124, 125, + 826, 827, 128, 0, 129, 130, 131, 132, 828, 0, + 829, 0, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 0, 145, 146, 147, 148, 149, 150, 0, + 151, 152, 153, 154, 830, 831, 832, 833, 834, 835, + 836, 156, 157, 158, 159, 160, 161, 162, 837, 838, + 165, 839, 166, 0, 167, 168, 169, 170, 171, 172, + 0, 173, 174, 175, 176, 177, 0, 0, 178, 179, + 675, 181, 182, 0, 183, 184, 185, 0, 186, 187, + 188, 0, 189, 190, 191, 192, 840, 194, 195, 196, + 197, 841, 842, 199, 0, 200, 201, 843, 203, 0, + 204, 0, 205, 206, 0, 207, 208, 209, 210, 211, + 212, 0, 213, 0, 844, 845, 216, 0, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 0, 229, 230, 231, 232, 233, 234, 0, 235, 236, + 237, 238, 239, 240, 241, 242, 846, 847, 0, 848, + 0, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 0, 0, 256, 257, 258, 259, 0, 260, 261, + 262, 849, 850, 263, 264, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 851, 288, 852, + 290, 291, 292, 293, 853, 294, 295, 296, 297, 854, + 855, 299, 856, 301, 302, 303, 0, 304, 305, 0, + 0, 857, 307, 308, 0, 0, 309, 310, 311, 312, + 313, 858, 315, 316, 317, 318, 319, 320, 321, 322, + 323, 324, 0, 325, 326, 859, 328, 329, 330, 331, + 332, 333, 0, 334, 335, 336, 337, 338, 339, 0, + 340, 341, 342, 860, 344, 345, 346, 347, 0, 348, + 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, + 359, 360, 0, 361, 362, 363, 364, 365, 366, 861, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 0, 379, 380, 381, 382, 383, 862, 384, 385, + 386, 387, 388, 389, 390, 391, 863, 393, 0, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 405, 406, 864, 408, 0, 409, 410, 0, 411, 412, + 413, 414, 415, 416, 417, 0, 865, 866, 0, 0, + 420, 421, 867, 423, 868, 869, 425, 426, 870, 428, + 429, 430, 431, 432, 0, 0, 433, 434, 435, 436, + 437, 871, 0, 438, 439, 440, 441, 442, 443, 872, + 0, 445, 446, 447, 448, 449, 450, 0, 0, 451, + 0, 0, 452, 453, 454, 455, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 873, 0, 0, 0, 0, 0, 0, + 874, 875, 0, 0, 0, 0, 0, 877, 0, 2014, + 0, 0, 0, 0, 879, 0, 880, 881, 92, 814, + 547, 815, 816, 817, 818, 819, 0, 0, 0, 0, + 0, 0, 0, 0, 93, 94, 95, 96, 97, 98, + 99, 100, 0, 101, 102, 103, 0, 0, 0, 0, + 820, 0, 0, 104, 105, 0, 106, 107, 108, 109, + 110, 111, 112, 113, 821, 115, 822, 823, 0, 118, + 119, 120, 121, 122, 123, 824, 825, 124, 125, 826, + 827, 128, 0, 129, 130, 131, 132, 828, 0, 829, + 0, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 0, 145, 146, 147, 148, 149, 150, 0, 151, + 152, 2683, 154, 830, 831, 832, 833, 834, 835, 836, + 156, 157, 158, 159, 160, 161, 162, 837, 838, 165, + 839, 166, 0, 167, 168, 169, 170, 171, 172, 0, + 173, 174, 175, 176, 177, 0, 0, 178, 179, 675, + 181, 182, 0, 183, 184, 185, 0, 186, 187, 188, + 0, 189, 190, 191, 192, 840, 194, 195, 196, 197, + 841, 842, 199, 0, 200, 201, 843, 203, 0, 204, + 0, 205, 206, 0, 207, 208, 209, 210, 211, 212, + 0, 213, 0, 2684, 845, 216, 0, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228, 0, + 229, 230, 231, 232, 233, 234, 0, 235, 236, 237, + 238, 239, 240, 241, 242, 846, 847, 0, 848, 0, + 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, + 0, 0, 256, 257, 258, 259, 0, 260, 261, 262, + 849, 850, 263, 264, 265, 266, 267, 268, 269, 270, + 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, + 281, 282, 283, 284, 285, 286, 851, 288, 852, 290, + 291, 292, 293, 853, 294, 295, 296, 297, 854, 855, + 299, 856, 301, 302, 303, 0, 304, 305, 0, 0, + 857, 307, 308, 0, 0, 309, 310, 311, 312, 313, + 858, 315, 316, 317, 318, 319, 320, 321, 322, 323, + 324, 0, 325, 326, 859, 328, 329, 330, 331, 332, + 333, 0, 334, 335, 336, 337, 338, 339, 0, 340, + 341, 342, 860, 344, 345, 346, 347, 0, 348, 349, + 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, + 360, 0, 361, 362, 363, 364, 365, 2685, 861, 368, + 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, + 0, 379, 380, 381, 382, 383, 862, 384, 385, 386, + 387, 388, 389, 390, 391, 863, 393, 0, 394, 395, + 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, + 406, 864, 408, 0, 409, 410, 0, 411, 412, 413, + 414, 415, 416, 417, 0, 865, 866, 0, 0, 420, + 421, 867, 423, 868, 869, 425, 426, 870, 428, 429, + 430, 431, 432, 0, 0, 433, 434, 435, 436, 437, + 871, 0, 438, 439, 440, 441, 442, 443, 872, 0, + 445, 446, 447, 448, 449, 450, 0, 0, 451, 0, + 0, 452, 453, 454, 455, 456, 457, 458, 459, 460, + 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, + 471, 472, 873, 0, 0, 0, 0, 0, 0, 874, + 875, 0, 0, 0, 0, 0, 877, 0, 2687, 0, + 0, 0, 0, 879, 0, 880, 881, 92, 814, 547, + 815, 816, 817, 818, 819, 0, 0, 0, 0, 0, + 0, 0, 0, 93, 94, 95, 96, 97, 98, 99, + 100, 0, 101, 102, 103, 0, 0, 0, 0, 820, + 0, 0, 104, 105, 0, 106, 107, 108, 109, 110, + 111, 112, 2904, 821, 115, 822, 823, 0, 118, 119, + 120, 121, 122, 123, 824, 825, 124, 125, 826, 827, + 128, 0, 129, 130, 131, 132, 828, 0, 829, 0, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 0, 145, 146, 147, 148, 149, 150, 0, 151, 152, + 153, 2905, 830, 831, 832, 833, 834, 835, 836, 156, + 157, 158, 159, 160, 161, 162, 837, 838, 165, 839, + 166, 0, 167, 168, 169, 170, 171, 172, 0, 173, + 174, 175, 176, 177, 0, 0, 178, 179, 675, 181, + 182, 0, 183, 184, 185, 0, 186, 187, 188, 0, + 189, 190, 191, 192, 840, 194, 195, 196, 197, 841, + 842, 199, 0, 200, 201, 843, 203, 0, 204, 0, + 205, 206, 0, 207, 208, 209, 210, 211, 212, 0, + 213, 0, 844, 845, 216, 0, 217, 218, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 228, 0, 229, + 230, 231, 232, 233, 234, 0, 235, 236, 237, 238, + 239, 240, 241, 242, 846, 847, 0, 848, 0, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 0, + 0, 256, 257, 258, 259, 0, 260, 261, 262, 849, + 850, 263, 264, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 851, 288, 852, 290, 291, + 292, 293, 853, 294, 295, 296, 297, 854, 855, 299, + 856, 301, 302, 303, 0, 304, 305, 0, 0, 857, + 307, 308, 0, 0, 309, 310, 311, 312, 313, 858, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 0, 325, 326, 859, 328, 329, 330, 331, 332, 333, + 0, 334, 335, 336, 337, 338, 339, 0, 340, 341, + 342, 860, 344, 345, 346, 347, 0, 348, 349, 350, + 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, + 0, 361, 362, 363, 364, 365, 366, 861, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 0, + 379, 380, 381, 382, 383, 862, 384, 385, 386, 387, + 388, 389, 390, 391, 863, 393, 0, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, + 864, 408, 0, 409, 410, 0, 411, 412, 413, 414, + 415, 416, 417, 0, 865, 866, 0, 0, 420, 421, + 867, 423, 868, 869, 425, 426, 870, 428, 429, 2906, + 431, 432, 0, 0, 433, 434, 435, 436, 437, 871, + 0, 438, 439, 440, 441, 442, 443, 872, 0, 445, + 446, 447, 448, 449, 450, 0, 0, 451, 0, 0, + 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 873, 0, 0, 0, 0, 0, 0, 874, 875, + 0, 0, 0, 0, 0, 877, 0, 878, 0, 0, + 0, 0, 879, 0, 880, 881, 92, 814, 547, 815, + 816, 817, 818, 819, 0, 0, 0, 0, 0, 0, + 0, 0, 93, 94, 95, 96, 97, 98, 99, 100, + 0, 101, 102, 103, 0, 0, 0, 0, 820, 0, + 0, 104, 105, 0, 106, 107, 108, 109, 110, 111, + 112, 113, 821, 115, 822, 823, 0, 118, 119, 120, + 121, 122, 123, 824, 825, 124, 125, 826, 827, 128, + 0, 129, 130, 131, 132, 828, 0, 829, 0, 135, + 136, 137, 138, 139, 140, 141, 142, 143, 144, 0, + 145, 146, 147, 148, 149, 150, 0, 151, 152, 153, + 2905, 830, 831, 832, 833, 834, 835, 836, 156, 157, + 158, 159, 160, 161, 162, 837, 838, 165, 839, 166, + 0, 167, 168, 169, 170, 171, 172, 0, 173, 174, + 175, 176, 177, 0, 0, 178, 179, 675, 181, 182, + 0, 183, 184, 185, 0, 186, 187, 188, 0, 189, + 190, 191, 192, 840, 194, 195, 196, 197, 841, 842, + 199, 0, 200, 201, 843, 203, 0, 204, 0, 205, + 206, 0, 207, 208, 209, 210, 211, 212, 0, 213, + 0, 844, 845, 216, 0, 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 228, 0, 229, 230, + 231, 232, 233, 234, 0, 235, 236, 237, 238, 239, + 240, 241, 242, 846, 847, 0, 848, 0, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, 0, 0, + 256, 257, 258, 259, 0, 260, 261, 262, 849, 850, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, - 283, 843, 285, 844, 287, 288, 289, 290, 845, 291, - 292, 293, 294, 846, 847, 296, 848, 298, 299, 300, - 0, 301, 302, 0, 0, 849, 304, 305, 0, 0, - 306, 307, 308, 309, 310, 850, 312, 313, 314, 315, - 316, 317, 318, 319, 320, 321, 0, 322, 323, 851, - 325, 326, 327, 328, 329, 330, 0, 331, 332, 333, - 334, 335, 336, 337, 338, 339, 852, 341, 342, 343, - 344, 0, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 0, 357, 358, 359, 360, 361, - 362, 853, 364, 365, 366, 367, 368, 369, 370, 371, - 372, 373, 374, 0, 375, 376, 377, 378, 379, 854, - 380, 381, 382, 383, 384, 385, 386, 387, 855, 389, - 0, 390, 391, 392, 393, 394, 395, 396, 397, 398, - 399, 400, 401, 402, 856, 404, 0, 405, 406, 0, - 407, 408, 409, 410, 411, 412, 413, 0, 857, 858, - 0, 0, 416, 417, 859, 419, 860, 861, 421, 422, - 862, 424, 425, 426, 427, 428, 0, 0, 429, 430, - 431, 432, 433, 863, 0, 434, 435, 436, 437, 438, - 439, 864, 0, 441, 442, 443, 444, 445, 446, 0, - 0, 447, 0, 0, 448, 449, 450, 451, 452, 453, - 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 865, 0, 0, 0, 0, - 0, 0, 866, 867, 0, 0, 0, 0, 0, 869, - 0, 870, 0, 0, 0, 0, 871, 0, 872, 873, - 91, 806, 542, 807, 808, 809, 810, 811, 0, 0, - 0, 0, 0, 0, 0, 0, 92, 93, 94, 95, - 96, 97, 98, 99, 0, 100, 101, 102, 0, 0, - 0, 0, 812, 0, 0, 103, 104, 0, 105, 106, - 107, 108, 109, 110, 111, 112, 813, 114, 814, 815, - 0, 117, 118, 119, 120, 121, 122, 816, 817, 123, - 124, 818, 819, 127, 0, 128, 129, 130, 131, 820, - 0, 821, 0, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 0, 144, 145, 146, 147, 148, 149, - 0, 150, 151, 152, 153, 822, 823, 824, 825, 826, - 827, 828, 155, 156, 157, 158, 159, 160, 161, 829, - 830, 164, 831, 165, 0, 166, 167, 168, 169, 170, - 171, 0, 172, 173, 174, 175, 176, 0, 0, 177, - 178, 668, 180, 181, 0, 182, 183, 184, 0, 185, - 186, 187, 0, 188, 189, 190, 191, 832, 193, 194, - 195, 196, 833, 834, 198, 0, 199, 200, 835, 202, - 0, 203, 0, 204, 205, 0, 206, 207, 208, 209, - 210, 211, 0, 212, 0, 836, 837, 215, 0, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 0, 227, 228, 229, 230, 231, 232, 0, 233, 234, - 235, 236, 237, 238, 239, 838, 839, 0, 840, 0, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 0, 0, 253, 254, 255, 256, 0, 257, 258, 259, - 841, 842, 260, 261, 262, 263, 264, 265, 266, 267, - 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, - 278, 279, 280, 281, 282, 283, 843, 285, 844, 287, - 288, 289, 290, 845, 291, 292, 293, 294, 846, 847, - 296, 848, 298, 299, 300, 0, 301, 302, 0, 0, - 849, 304, 305, 0, 0, 306, 307, 308, 309, 310, - 850, 312, 313, 314, 315, 316, 317, 318, 319, 320, - 321, 0, 322, 323, 851, 325, 326, 327, 328, 329, - 330, 0, 331, 332, 333, 334, 335, 336, 337, 338, - 339, 852, 341, 342, 343, 344, 0, 345, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, 356, 0, - 357, 358, 359, 360, 361, 362, 853, 364, 365, 366, - 367, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 376, 377, 378, 379, 854, 380, 381, 382, 383, 384, - 385, 386, 387, 855, 389, 0, 390, 391, 392, 393, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 856, - 404, 0, 405, 406, 0, 407, 408, 409, 410, 411, - 412, 413, 0, 857, 858, 0, 0, 416, 417, 859, - 419, 860, 861, 421, 422, 862, 424, 425, 426, 427, - 428, 0, 0, 429, 430, 431, 432, 433, 863, 0, - 434, 435, 436, 437, 438, 439, 864, 0, 441, 442, - 443, 444, 445, 446, 0, 0, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, - 865, 0, 0, 0, 0, 0, 0, 866, 867, 0, - 0, 0, 0, 0, 869, 0, 870, 0, 0, 0, - 0, 871, 0, 872, 873, 1001, 806, 542, 807, 808, - 809, 810, 811, 0, 0, 0, 0, 0, 0, 0, - 0, 92, 93, 94, 95, 96, 97, 98, 99, 0, - 100, 101, 102, 0, 0, 0, 0, 812, 0, 0, - 103, 104, 0, 105, 106, 107, 1003, 109, 110, 111, - 112, 813, 1004, 814, 815, 0, 117, 118, 119, 120, - 121, 122, 816, 817, 123, 124, 818, 819, 127, 0, - 128, 129, 130, 131, 820, 0, 1005, 0, 134, 135, - 136, 137, 138, 139, 1006, 141, 142, 143, 0, 144, - 145, 146, 147, 148, 149, 0, 1007, 151, 152, 153, - 822, 823, 824, 1008, 826, 827, 828, 155, 156, 157, - 158, 159, 160, 161, 829, 830, 164, 831, 165, 0, - 166, 167, 168, 169, 170, 171, 0, 172, 173, 174, - 175, 176, 0, 0, 177, 178, 668, 180, 181, 0, - 182, 183, 184, 0, 185, 186, 187, 0, 188, 189, - 190, 191, 832, 193, 194, 195, 196, 833, 834, 198, - 0, 199, 200, 835, 202, 0, 203, 0, 204, 1010, - 0, 1011, 207, 208, 209, 1012, 211, 0, 212, 0, - 836, 837, 215, 0, 216, 217, 218, 219, 220, 221, - 1013, 223, 224, 225, 226, 0, 227, 228, 229, 230, - 231, 232, 0, 233, 1014, 235, 236, 237, 238, 239, - 838, 839, 0, 840, 0, 243, 1015, 1016, 246, 1017, - 248, 249, 250, 251, 252, 0, 0, 253, 1018, 255, - 1019, 0, 257, 258, 259, 841, 842, 260, 261, 262, - 263, 264, 1020, 266, 267, 268, 269, 270, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, - 283, 843, 1021, 844, 287, 288, 289, 290, 845, 291, - 292, 1022, 294, 846, 847, 296, 848, 298, 299, 300, - 0, 301, 302, 0, 0, 849, 304, 305, 0, 0, - 306, 307, 1023, 309, 1024, 850, 312, 313, 314, 315, - 316, 317, 318, 319, 320, 321, 0, 322, 323, 851, - 325, 326, 327, 328, 329, 330, 0, 331, 332, 333, - 334, 335, 336, 337, 338, 339, 852, 341, 342, 343, - 344, 0, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 0, 357, 358, 1025, 360, 361, - 362, 853, 364, 365, 366, 367, 368, 369, 370, 371, - 372, 373, 374, 0, 375, 376, 377, 378, 379, 854, - 380, 381, 382, 383, 384, 1026, 386, 387, 855, 389, - 0, 390, 391, 392, 393, 394, 395, 396, 397, 398, - 399, 400, 1027, 402, 856, 404, 0, 405, 406, 0, - 407, 1028, 409, 410, 411, 412, 413, 0, 857, 858, - 0, 0, 416, 417, 859, 419, 860, 861, 421, 422, - 1029, 424, 425, 426, 427, 428, 0, 0, 429, 430, - 431, 432, 433, 863, 0, 434, 435, 436, 437, 438, - 439, 864, 0, 441, 1031, 443, 444, 445, 446, 0, - 0, 447, 0, 0, 448, 449, 450, 451, 452, 453, + 283, 284, 285, 286, 851, 288, 852, 290, 291, 292, + 293, 853, 294, 295, 296, 297, 854, 855, 299, 856, + 301, 302, 303, 0, 304, 305, 0, 0, 857, 307, + 308, 0, 0, 309, 310, 311, 312, 313, 858, 315, + 316, 317, 318, 319, 320, 321, 322, 323, 324, 0, + 325, 326, 859, 328, 329, 330, 331, 332, 333, 0, + 334, 335, 336, 337, 338, 339, 0, 340, 341, 342, + 860, 344, 345, 346, 347, 0, 348, 349, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 0, + 361, 362, 363, 364, 365, 366, 861, 368, 369, 370, + 371, 372, 373, 374, 375, 376, 377, 378, 0, 379, + 380, 381, 382, 383, 862, 384, 385, 386, 387, 388, + 389, 390, 391, 863, 393, 0, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, 404, 405, 406, 864, + 408, 0, 409, 410, 0, 411, 412, 413, 414, 415, + 416, 417, 0, 865, 866, 0, 0, 420, 421, 867, + 423, 868, 869, 425, 426, 870, 428, 429, 2906, 431, + 432, 0, 0, 433, 434, 435, 436, 437, 871, 0, + 438, 439, 440, 441, 442, 443, 872, 0, 445, 446, + 447, 448, 449, 450, 0, 0, 451, 0, 0, 452, + 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, + 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, + 873, 0, 0, 0, 0, 0, 0, 874, 875, 0, + 0, 0, 0, 0, 877, 0, 878, 0, 0, 0, + 0, 879, 0, 880, 881, 92, 814, 547, 815, 816, + 817, 818, 819, 0, 0, 0, 0, 0, 0, 0, + 0, 93, 94, 95, 96, 97, 98, 99, 100, 0, + 101, 102, 103, 0, 0, 0, 0, 820, 0, 0, + 104, 105, 0, 106, 107, 108, 109, 110, 111, 112, + -1731, 821, 115, 822, 823, 0, 118, 119, 120, 121, + 122, 123, 824, 825, 124, 125, 826, 827, 128, 0, + 129, 130, 131, 132, 828, 0, 829, 0, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 0, 145, + 146, 147, 148, 149, 150, 0, 151, 152, 153, 2905, + 830, 831, 832, 833, 834, 835, 836, 156, 157, 158, + 159, 160, 161, 162, 837, 838, 165, 839, 166, 0, + 167, 168, 169, 170, 171, 172, 0, 173, 174, 175, + 176, 177, 0, 0, 178, 179, 675, 181, 182, 0, + 183, 184, 185, 0, 186, 187, 188, 0, 189, 190, + 191, 192, 840, 194, 195, 196, 197, 841, 842, 199, + 0, 200, 201, 843, 203, 0, 204, 0, 205, 206, + 0, 207, 208, 209, 210, -1731, 212, 0, 213, 0, + 844, 845, 216, 0, 217, 218, 219, 220, 221, 222, + 223, -1731, 225, 226, 227, 228, 0, 229, 230, 231, + 232, 233, 234, 0, 235, 236, 237, 238, 239, 240, + 241, 242, 846, 847, 0, 848, 0, 246, 0, 0, + 249, 250, 251, 252, 253, 254, 255, 0, 0, 256, + 257, 258, -1731, 0, 260, 261, 262, 849, 850, 263, + 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + 284, 285, 286, 851, 288, 852, 290, 291, 292, 293, + 0, 294, 295, 0, 297, 854, 855, 299, 856, 301, + 302, 303, 0, 304, 305, 0, 0, 857, 307, 308, + 0, 0, 309, 310, 311, 312, 313, 858, 315, 316, + 317, 318, 319, 320, 321, 322, 323, 324, 0, 325, + 326, 859, 328, 329, 330, 331, 332, 333, 0, 334, + 335, 336, 337, 338, 339, 0, 340, 341, 342, 860, + 344, 345, 346, 347, 0, 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 0, 361, + 362, 363, 364, 365, 366, 861, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 0, 379, 380, + 381, 382, 383, 862, 384, 385, 386, 387, 388, -1731, + 390, 391, 863, 393, 0, 394, 395, 396, 397, 398, + 399, 400, 401, 402, 403, 404, 405, 406, 864, 408, + 0, 409, 410, 0, 411, 412, 413, 414, 415, 416, + 417, 0, 865, 866, 0, 0, 420, 421, 867, 423, + 868, 869, 425, 426, 870, 428, 429, 2906, 431, 432, + 0, 0, 433, 434, 435, 436, 437, 871, 0, 438, + 439, 440, 441, 442, 443, 872, 0, 445, 446, 447, + 448, 449, 450, 0, 0, 451, 0, 0, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 865, 0, 0, 0, 0, - 0, 0, 866, 867, 0, 0, 0, 0, 0, 869, - 0, 870, 0, 0, 0, 0, 871, 0, 872, 873, - 91, 806, 542, 807, 808, 809, 810, 811, 0, 0, - 0, 0, 0, 0, 0, 0, 92, 93, 94, 95, - 96, 97, 98, 99, 0, 100, 101, 102, 0, 0, - 0, 0, 812, 0, 0, 103, 104, 0, 105, 106, - 107, 108, 109, 110, 111, 112, 813, 114, 814, 815, - 0, 117, 118, 119, 120, 121, 122, 816, 817, 123, - 124, 818, 819, 127, 0, 128, 129, 130, 131, 820, - 0, 821, 0, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 0, 144, 145, 146, 147, 148, 149, - 0, 150, 151, 152, 153, 822, 823, 824, 825, 826, - 827, 828, 155, 156, 157, 158, 159, 160, 161, 829, - 830, 164, 831, 165, 0, 166, 167, 168, 169, 170, - 171, 0, 172, 173, 174, 175, 176, 0, 0, 177, - 178, 668, 180, 181, 0, 182, 183, 184, 0, 185, - 186, 187, 0, 188, 189, 190, 191, 832, 193, 194, - 195, 196, 833, 834, 198, 0, 199, 200, 835, 202, - 0, 203, 0, 204, 205, 0, 206, 207, 208, 209, - 210, 211, 0, 212, 0, 836, 837, 215, 0, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 0, 227, 228, 229, 230, 231, 232, 0, 233, 234, - 235, 236, 237, 238, 239, 838, 839, 0, 840, 0, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 0, 0, 253, 254, 255, 256, 0, 257, 258, 259, - 841, 842, 260, 261, 262, 263, 264, 265, 266, 267, - 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, - 278, 279, 280, 281, 282, 283, 843, 285, 844, 287, - 288, 289, 290, 845, 291, 292, 293, 294, 846, 847, - 296, 848, 298, 299, 300, 0, 301, 302, 0, 0, - 849, 304, 305, 0, 0, 306, 307, 308, 309, 310, - 850, 312, 313, 314, 315, 316, 317, 318, 319, 320, - 321, 0, 322, 323, 851, 325, 326, 327, 328, 329, - 330, 0, 331, 332, 333, 334, 335, 336, 337, 338, - 339, 852, 341, 342, 343, 344, 0, 345, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, 356, 0, - 357, 358, 359, 360, 361, 362, 853, 364, 365, 366, - 367, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 376, 377, 378, 379, 854, 380, 381, 382, 383, 384, - 385, 386, 387, 855, 389, 0, 390, 391, 392, 393, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 856, - 404, 0, 405, 406, 0, 407, 408, 409, 410, 411, - 412, 413, 0, 857, 858, 0, 0, 416, 417, 859, - 419, 860, 861, 421, 422, 862, 424, 425, 426, 427, - 428, 0, 0, 429, 430, 431, 432, 433, 863, 0, - 434, 435, 436, 437, 438, 439, 864, 0, 441, 442, - 443, 444, 445, 446, 0, 0, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, + 464, 465, 466, 467, 468, 469, 470, 471, 472, -1731, + 0, 0, 0, 0, 0, 0, 874, 875, 0, 0, + 0, 0, 0, 877, 0, 878, 0, 0, 0, 0, + 879, 0, 880, 881, 92, 814, 547, 815, 816, 817, + 818, 819, 0, 0, 0, 0, 0, 0, 0, 0, + 93, 94, 95, 96, 97, 98, 99, 100, 0, 101, + 102, 103, 0, 0, 0, 0, 0, 0, 0, 104, + 105, 0, 106, 107, 108, 109, 110, 111, 112, 113, + 821, 115, 822, 823, 0, 118, 119, 120, 121, 122, + 123, 824, 825, 124, 125, 826, 827, 128, 0, 129, + 130, 131, 132, 828, 0, 829, 0, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 0, 145, 146, + 147, 148, 149, 150, 0, 151, 152, 153, 154, 830, + 831, 832, 833, 834, 835, 836, 156, 157, 158, 159, + 160, 161, 162, 837, 838, 165, 0, 166, 0, 167, + 168, 169, 170, 171, 172, 0, 173, 174, 175, 176, + 177, 0, 0, 178, 179, 675, 181, 182, 0, 183, + 184, 185, 0, 186, 187, 188, 0, 189, 190, 191, + 192, 840, 194, 195, 196, 197, 841, 842, 199, 0, + 200, 201, 843, 203, 0, 204, 0, 205, 206, 0, + 207, 208, 209, 210, 211, 212, 0, 213, 0, 844, + 845, 216, 0, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 0, 229, 230, 231, 232, + 233, 234, 0, 235, 236, 237, 238, 239, 240, 241, + 242, 846, 847, 0, 848, 0, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 0, 0, 256, 257, + 258, 259, 0, 260, 261, 262, 849, 850, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 851, 288, 852, 290, 291, 292, 293, 0, + 294, 295, 296, 297, 854, 855, 299, 856, 301, 302, + 303, 0, 304, 305, 0, 0, 857, 307, 308, 0, + 0, 309, 310, 311, 312, 313, 858, 315, 316, 317, + 318, 319, 320, 321, 322, 323, 324, 0, 325, 326, + 859, 328, 329, 330, 331, 332, 333, 0, 334, 335, + 336, 337, 338, 339, 0, 340, 341, 342, 860, 344, + 345, 346, 347, 0, 348, 349, 350, 351, 352, 353, + 354, 355, 356, 357, 358, 359, 360, 0, 361, 362, + 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, 378, 0, 379, 380, 381, + 382, 383, 862, 384, 385, 386, 387, 388, 389, 390, + 391, 863, 393, 0, 394, 395, 396, 397, 398, 399, + 400, 401, 402, 403, 404, 405, 406, 864, 408, 0, + 409, 410, 0, 411, 412, 413, 414, 415, 416, 417, + 0, 865, 866, 0, 0, 420, 421, 867, 423, 868, + 869, 425, 426, 870, 428, 429, 430, 431, 432, 0, + 0, 433, 434, 435, 436, 437, 871, 0, 438, 439, + 440, 441, 442, 443, 872, 0, 445, 446, 447, 448, + 449, 450, 0, 0, 451, 0, 0, 452, 453, 454, + 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, + 465, 466, 467, 468, 469, 470, 471, 472, 0, 0, + 0, 0, 0, 0, 0, 1633, 1634, 0, 0, 92, + 814, 547, 815, 816, 1635, 818, 819, 0, 0, 0, + 0, 880, 881, 0, 0, 93, 94, 95, 96, 97, + 98, 99, 100, 0, 101, 102, 103, 0, 0, 0, + 0, 0, 0, 0, 104, 105, 0, 106, 107, 108, + 109, 110, 111, 112, 113, 821, 115, 822, 823, 0, + 118, 119, 120, 121, 122, 123, 824, 825, 124, 125, + 826, 827, 128, 0, 129, 130, 131, 132, 828, 0, + 829, 0, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 0, 145, 146, 147, 148, 149, 150, 0, + 151, 152, 153, 154, 830, 831, 832, 833, 834, 835, + 836, 156, 157, 158, 159, 160, 161, 162, 837, 838, + 165, 0, 166, 0, 167, 168, 169, 170, 171, 172, + 0, 173, 174, 175, 176, 177, 0, 0, 178, 179, + 675, 181, 182, 0, 183, 184, 185, 0, 186, 187, + 188, 0, 189, 190, 191, 192, 840, 194, 195, 196, + 197, 841, 842, 199, 0, 200, 201, 843, 203, 0, + 204, 0, 205, 206, 0, 207, 208, 209, 210, 211, + 212, 0, 213, 0, 844, 845, 216, 0, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 0, 229, 230, 231, 232, 233, 234, 0, 235, 236, + 237, 238, 239, 240, 241, 242, 846, 847, 0, 848, + 0, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 0, 0, 256, 257, 258, 259, 0, 260, 261, + 262, 849, 850, 263, 264, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 851, 288, 852, + 290, 291, 292, 293, 0, 294, 295, 296, 297, 854, + 855, 299, 856, 301, 302, 303, 0, 304, 305, 0, + 0, 306, 307, 308, 0, 0, 309, 310, 311, 312, + 313, 858, 315, 316, 317, 318, 319, 320, 321, 322, + 323, 324, 0, 325, 326, 859, 328, 329, 330, 331, + 332, 333, 0, 334, 335, 336, 337, 338, 339, 0, + 340, 341, 342, 860, 344, 345, 346, 347, 0, 348, + 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, + 359, 360, 0, 361, 362, 363, 364, 365, 366, 1772, + 1773, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 0, 379, 380, 381, 382, 383, 862, 384, 385, + 386, 387, 388, 389, 390, 391, 863, 393, 0, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 405, 406, 864, 408, 0, 409, 410, 0, 411, 412, + 413, 414, 415, 416, 417, 0, 865, 866, 0, 0, + 420, 421, 867, 423, 868, 869, 425, 426, 870, 428, + 429, 430, 431, 432, 0, 0, 433, 434, 435, 436, + 437, 871, 0, 438, 439, 440, 441, 442, 443, 872, + 0, 445, 446, 447, 448, 449, 450, 0, 0, 451, + 0, 0, 452, 453, 454, 455, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 0, 0, 0, 0, 0, 0, 0, + 1774, 1775, 0, 0, 0, 0, 0, 0, 0, 1635, + 0, 0, 0, 0, 0, 0, 880, 881, 92, 814, + 547, 815, 816, 817, 818, 819, 0, 0, 0, 0, + 0, 0, 0, 0, 93, 94, 95, 96, 97, 98, + 99, 100, 0, 101, 102, 103, 0, 0, 0, 0, + 0, 0, 0, 104, 105, 0, 106, 107, 108, 109, + 110, 111, 112, 113, 821, 115, 822, 823, 0, 118, + 119, 120, 121, 122, 123, 824, 825, 124, 125, 826, + 827, 128, 0, 129, 130, 131, 132, 828, 0, 829, + 0, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 0, 145, 146, 147, 148, 149, 150, 0, 151, + 152, 153, 154, 830, 831, 832, 833, 834, 835, 836, + 156, 157, 158, 159, 160, 161, 162, 837, 838, 165, + 0, 166, 0, 167, 168, 169, 170, 171, 172, 0, + 173, 174, 175, 176, 177, 0, 0, 178, 179, 675, + 181, 182, 0, 183, 184, 185, 0, 186, 187, 188, + 0, 189, 190, 191, 192, 840, 194, 195, 196, 197, + 841, 842, 199, 0, 200, 201, 843, 203, 0, 204, + 0, 205, 206, 0, 207, 208, 209, 210, 211, 212, + 0, 213, 0, 844, 845, 216, 0, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228, 0, + 229, 230, 231, 232, 233, 234, 0, 235, 236, 237, + 238, 239, 240, 241, 242, 846, 847, 0, 848, 0, + 246, 0, 248, 249, 250, 251, 252, 253, 254, 255, + 0, 0, 256, 257, 258, 259, 0, 260, 261, 262, + 849, 850, 263, 264, 265, 266, 267, 268, 269, 270, + 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, + 281, 282, 283, 284, 285, 286, 851, 288, 852, 290, + 291, 292, 293, 0, 294, 295, 296, 297, 854, 855, + 299, 856, 301, 302, 303, 0, 304, 305, 0, 0, + 857, 307, 308, 0, 0, 309, 310, 311, 312, 313, + 858, 315, 316, 317, 318, 319, 320, 321, 322, 323, + 324, 0, 325, 326, 859, 328, 329, 330, 331, 332, + 333, 0, 334, 335, 336, 337, 338, 339, 0, 340, + 341, 342, 860, 344, 345, 346, 347, 0, 348, 349, + 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, + 360, 0, 361, 362, 363, 364, 365, 366, 367, 368, + 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, + 0, 379, 380, 381, 382, 383, 862, 384, 385, 386, + 387, 388, 389, 390, 391, 863, 393, 0, 394, 395, + 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, + 406, 864, 408, 0, 409, 410, 0, 411, 412, 413, + 414, 415, 416, 417, 0, 865, 866, 0, 0, 420, + 421, 867, 423, 868, 869, 425, 426, 870, 428, 429, + 430, 431, 432, 0, 0, 433, 434, 435, 436, 437, + 871, 0, 438, 439, 440, 441, 442, 443, 872, 0, + 445, 446, 447, 448, 449, 450, 0, 0, 451, 0, + 0, 452, 453, 454, 455, 456, 457, 458, 459, 460, + 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, + 471, 472, 0, 0, 0, 0, 0, 0, 0, 1633, + 1634, 0, 0, 0, 0, 0, 0, 0, 1635, 0, + 0, 0, 0, 0, 0, 880, 881, 92, 814, 547, + 815, 816, 817, 818, 819, 0, 0, 0, 0, 0, + 0, 0, 0, 93, 94, 95, 96, 97, 98, 99, + 100, 0, 101, 102, 103, 0, 0, 0, 0, 820, + 0, 0, 104, 105, 0, 106, 107, 108, 109, 110, + 111, 112, 0, 821, 115, 822, 823, 0, 118, 119, + 120, 121, 122, 123, 824, 825, 124, 125, 826, 827, + 128, 0, 129, 130, 131, 132, 828, 0, 829, 0, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 0, 145, 146, 147, 148, 149, 150, 0, 151, 152, + 153, 154, 830, 831, 832, 833, 834, 835, 836, 156, + 157, 158, 159, 160, 161, 162, 837, 838, 165, 839, + 166, 0, 167, 168, 169, 170, 171, 172, 0, 173, + 174, 175, 176, 177, 0, 0, 178, 179, 675, 181, + 182, 0, 183, 184, 185, 0, 186, 0, 188, 0, + 189, 190, 191, 192, 840, 194, 195, 196, 197, 841, + 842, 199, 0, 200, 201, 843, 203, 0, 204, 0, + 205, 206, 0, 207, 208, 209, 210, 0, 212, 0, + 213, 0, 844, 845, 216, 0, 217, 218, 219, 220, + 221, 222, 223, 0, 225, 226, 227, 228, 0, 229, + 230, 231, 232, 233, 234, 0, 235, 236, 237, 238, + 239, 240, 241, 242, 846, 847, 0, 848, 0, 246, + 0, 0, 249, 250, 251, 252, 253, 254, 255, 0, + 0, 256, 257, 258, 0, 0, 260, 261, 262, 849, + 850, 263, 264, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 851, 288, 852, 290, 291, + 292, 293, 0, 294, 295, 0, 297, 854, 855, 299, + 856, 301, 302, 303, 0, 304, 305, 0, 0, 857, + 307, 308, 0, 0, 309, 310, 311, 312, 313, 858, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 0, 325, 326, 859, 328, 329, 330, 331, 332, 333, + 0, 334, 335, 336, 337, 338, 339, 0, 340, 341, + 342, 860, 344, 345, 346, 347, 0, 348, 349, 350, + 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, + 0, 361, 362, 363, 364, 365, 366, 861, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 0, + 379, 380, 381, 382, 383, 862, 384, 385, 386, 387, + 388, 0, 390, 391, 863, 393, 0, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, + 864, 408, 0, 409, 410, 0, 411, 412, 413, 414, + 415, 416, 417, 0, 865, 866, 0, 0, 420, 421, + 867, 423, 868, 869, 425, 426, 870, 428, 429, 430, + 431, 432, 0, 0, 433, 434, 435, 436, 437, 871, + 0, 438, 439, 440, 441, 442, 443, 872, 0, 445, + 446, 447, 448, 449, 450, 0, 0, 451, 0, 0, + 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 0, 0, 0, 0, 0, 0, 0, 874, 875, + 498, 0, 0, 0, 0, 877, 0, 878, 0, 0, + 0, 0, 879, 0, 880, 881, 93, 94, 95, 96, + 97, 98, 99, 100, 0, 101, 102, 103, 0, 0, + 0, 0, 0, 2311, 0, 104, 105, 0, 106, 107, + 108, 0, 110, 111, 112, 113, 114, 0, 116, 117, + 0, 118, 119, 120, 121, 122, 123, 0, 0, 124, + 125, 126, 127, 128, 0, 129, 130, 131, 132, 133, + 0, 0, 0, 135, 136, 137, 138, 139, 140, 0, + 142, 143, 144, 0, 145, 146, 147, 148, 149, 150, + 0, -612, 152, 153, 154, 0, 0, 0, 0, 0, + 0, 0, 156, 157, 158, 159, 160, 161, 162, 163, + 164, 165, 0, 166, 0, 167, 168, 169, 170, 171, + 172, 0, 173, 174, 175, 176, 177, 0, 0, 178, + 179, 180, 181, 182, 0, 183, 184, 185, 0, 186, + 187, 188, 0, 189, 190, 191, 192, 193, 194, 195, + 196, 197, 198, 0, 199, 0, 200, 201, 202, 203, + 0, 204, 0, 205, 0, 0, -612, 208, 209, 210, + 0, 212, 0, 213, 0, 214, 215, 216, 0, 217, + 218, 219, 220, 221, 222, 223, 0, 225, 226, 227, + 228, 0, 229, 230, 231, 232, 233, 234, 0, 235, + -612, 237, 238, 239, 240, 241, 242, 243, 244, 0, + 245, 0, 246, 0, 0, 249, -612, 251, 252, 253, + 254, 255, 0, 0, 256, -612, 258, 0, 0, 260, + 261, 262, 0, 0, 263, 264, 265, 266, 267, 500, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, -612, + 289, 290, 291, 292, 293, 0, 294, 295, 0, 297, + 0, 298, 299, 300, 301, 302, 303, 0, 304, 305, + 0, 0, 306, 307, 308, 0, 0, 309, 310, 0, + 312, 0, 314, 315, 316, 317, 318, 319, 320, 321, + 322, 323, 324, 0, 325, 326, 327, 328, 329, 330, + 331, 332, 333, 0, 334, 335, 336, 337, 338, 339, + 0, 340, 341, 342, 343, 344, 345, 346, 347, 0, + 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, + 358, 359, 360, 0, 361, 362, -612, 364, 365, 366, + 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, + 377, 378, 0, 379, 380, 381, 382, 383, 0, 384, + 385, 386, 387, 388, 0, 390, 391, 392, 393, 0, + 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, + 404, 502, 406, 407, 408, 0, 409, 410, 0, 411, + -612, 413, 414, 415, 416, 417, 0, 418, 419, 0, + 0, 420, 421, 422, 423, 424, 0, 425, 426, 427, + 428, 429, 430, 431, 432, 0, 0, 433, 434, 435, + 436, 437, 0, 0, 438, 439, 440, 441, 442, 443, + 444, 0, 445, 0, 447, 448, 449, 450, 0, 0, + 451, 0, 0, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, - 865, 0, 0, 0, 0, 0, 0, 1394, 1395, 0, - 0, 0, 0, 0, 869, 0, 870, 0, 0, 0, - 0, 871, 0, 872, 873, 91, 1768, 542, 807, 808, - 809, 810, 811, 0, 0, 0, 0, 0, 0, 0, - 0, 92, 93, 94, 95, 96, 97, 98, 99, 0, - 100, 101, 102, 0, 0, 0, 0, 812, 0, 0, - 103, 104, 0, 105, 106, 107, 108, 109, 110, 111, - 112, 813, 114, 814, 815, 0, 117, 118, 119, 120, - 121, 122, 816, 817, 123, 124, 818, 819, 127, 0, - 128, 129, 130, 131, 820, 0, 821, 0, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 0, 144, - 145, 146, 147, 148, 149, 0, 150, 151, 152, 153, - 822, 823, 824, 825, 826, 827, 828, 155, 156, 157, - 158, 159, 160, 161, 829, 830, 164, 831, 165, 0, - 166, 167, 168, 169, 170, 171, 0, 172, 173, 174, - 175, 176, 0, 0, 177, 178, 668, 180, 181, 0, - 182, 183, 184, 0, 185, 186, 187, 0, 188, 189, - 190, 191, 832, 193, 194, 195, 196, 833, 834, 198, - 0, 199, 200, 835, 202, 0, 203, 0, 204, 205, - 0, 206, 207, 208, 209, 210, 211, 0, 212, 0, - 836, 837, 215, 0, 216, 217, 218, 219, 220, 221, - 222, 223, 224, 225, 226, 0, 227, 228, 229, 230, - 231, 232, 0, 233, 234, 235, 236, 237, 238, 239, - 838, 839, 0, 840, 0, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 0, 0, 253, 254, 255, - 256, 0, 257, 258, 259, 841, 842, 260, 261, 262, + 469, 470, 471, 472, 0, 0, 92, 0, 579, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 941, 93, 94, 95, 96, 97, 98, 99, 100, + 0, 101, 102, 103, 0, 0, 0, 0, 0, 0, + 0, 104, 105, 0, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 0, 118, 119, 120, + 121, 122, 123, 0, 825, 124, 125, 126, 127, 128, + 0, 129, 130, 131, 132, 828, 0, 829, 0, 135, + 136, 137, 138, 139, 140, 141, 142, 143, 144, 0, + 145, 146, 147, 148, 149, 150, 0, 151, 152, 153, + 154, 830, 831, 832, 833, 834, 835, 836, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 0, 166, + 0, 167, 168, 169, 170, 171, 172, 0, 173, 174, + 175, 176, 177, 0, 0, 178, 179, 180, 181, 182, + 0, 183, 184, 185, 0, 186, 187, 188, 0, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 841, 0, + 199, 0, 200, 201, 202, 203, 0, 204, 0, 205, + 206, 0, 207, 208, 209, 210, 211, 212, 0, 213, + 0, 214, 215, 216, 0, 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 228, 0, 229, 230, + 231, 232, 233, 234, 0, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 0, 245, 0, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, 2060, 0, + 256, 257, 258, 259, 0, 260, 261, 262, 849, 850, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, - 283, 843, 285, 844, 287, 288, 289, 290, 845, 291, - 292, 293, 294, 846, 847, 296, 848, 298, 299, 300, - 0, 301, 302, 0, 0, 849, 304, 305, 0, 0, - 306, 307, 308, 309, 310, 850, 312, 313, 314, 315, - 316, 317, 318, 319, 320, 321, 0, 322, 323, 851, - 325, 326, 327, 328, 329, 330, 0, 331, 332, 333, - 334, 335, 336, 337, 338, 339, 852, 341, 342, 343, - 344, 0, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 0, 357, 358, 359, 360, 361, - 362, 853, 364, 365, 366, 367, 368, 369, 370, 371, - 372, 373, 374, 0, 375, 376, 377, 378, 379, 854, - 380, 381, 382, 383, 384, 385, 386, 387, 855, 389, - 0, 390, 391, 392, 393, 394, 395, 396, 397, 398, - 399, 400, 401, 402, 856, 404, 0, 405, 406, 0, - 407, 408, 409, 410, 411, 412, 413, 0, 857, 858, - 0, 0, 416, 417, 859, 419, 860, 861, 421, 422, - 862, 424, 425, 426, 427, 428, 0, 0, 429, 430, - 431, 432, 433, 863, 0, 434, 435, 436, 437, 438, - 439, 864, 0, 441, 442, 443, 444, 445, 446, 0, - 0, 447, 0, 0, 448, 449, 450, 451, 452, 453, - 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 865, 0, 0, 0, 0, - 0, 0, 866, 867, 0, 0, 0, 0, 0, 869, - 0, 870, 0, 0, 0, 0, 871, 0, 872, 873, - 91, 806, 542, 807, 808, 809, 810, 811, 0, 0, - 0, 0, 0, 0, 0, 0, 92, 93, 94, 95, - 96, 97, 98, 99, 0, 100, 101, 102, 0, 0, - 0, 0, 812, 0, 0, 103, 104, 0, 105, 106, - 107, 108, 109, 110, 111, 112, 813, 114, 814, 815, - 0, 117, 118, 119, 120, 121, 122, 816, 817, 123, - 124, 818, 819, 127, 0, 128, 129, 130, 131, 820, - 0, 821, 0, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 0, 144, 145, 146, 147, 148, 149, - 0, 150, 151, 152, 153, 822, 823, 824, 825, 826, - 827, 828, 155, 156, 157, 158, 159, 160, 161, 829, - 830, 164, 831, 165, 0, 166, 167, 168, 169, 170, - 171, 0, 172, 173, 174, 175, 176, 0, 0, 177, - 178, 668, 180, 181, 0, 182, 183, 184, 0, 185, - 186, 187, 0, 188, 189, 190, 191, 832, 193, 194, - 195, 196, 833, 834, 198, 0, 199, 200, 835, 202, - 0, 203, 0, 204, 205, 0, 206, 207, 208, 209, - 210, 211, 0, 212, 0, 836, 837, 215, 0, 216, + 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, + 293, 0, 294, 295, 296, 297, 0, 855, 299, 300, + 301, 302, 303, 0, 304, 305, 0, 580, 306, 307, + 308, 0, 0, 309, 310, 311, 312, 313, 858, 315, + 316, 317, 318, 319, 320, 321, 322, 323, 324, 0, + 325, 326, 859, 328, 329, 330, 331, 332, 333, 0, + 334, 335, 336, 337, 338, 339, 0, 340, 341, 342, + 343, 344, 345, 346, 347, 0, 348, 349, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 0, + 361, 362, 363, 364, 365, 366, 367, 2061, 369, 370, + 371, 372, 373, 374, 375, 376, 377, 378, 26, 379, + 380, 381, 382, 383, 862, 384, 385, 386, 387, 388, + 389, 390, 391, 392, 393, 0, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, 404, 405, 406, 864, + 408, 0, 409, 410, 31, 411, 412, 413, 414, 415, + 416, 417, 0, 418, 419, 0, 0, 420, 421, 867, + 423, 868, 0, 425, 426, 870, 428, 429, 430, 431, + 432, 0, 0, 433, 434, 435, 436, 437, 871, 0, + 438, 439, 440, 441, 442, 575, 444, 0, 445, 446, + 447, 448, 449, 450, 0, 0, 451, 0, 34, 452, + 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, + 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, + 0, 92, 35, 579, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2062, 93, 94, 95, + 96, 97, 98, 99, 100, 0, 101, 102, 103, 0, + 0, 0, 0, 0, 0, 0, 104, 105, 0, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 0, 118, 119, 120, 121, 122, 123, 0, 825, + 124, 125, 126, 127, 128, 0, 129, 130, 131, 132, + 828, 0, 829, 0, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 0, 145, 146, 147, 148, 149, + 150, 0, 151, 152, 153, 154, 830, 831, 832, 833, + 834, 835, 836, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 0, 166, 0, 167, 168, 169, 170, + 171, 172, 0, 173, 174, 175, 176, 177, 0, 0, + 178, 179, 180, 181, 182, 0, 183, 184, 185, 0, + 186, 187, 188, 0, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 841, 0, 199, 0, 200, 201, 202, + 203, 0, 204, 0, 205, 206, 0, 207, 208, 209, + 210, 211, 212, 0, 213, 0, 214, 215, 216, 0, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 0, 227, 228, 229, 230, 231, 232, 0, 233, 234, - 235, 236, 237, 238, 239, 838, 839, 0, 840, 0, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 0, 0, 253, 254, 255, 256, 0, 257, 258, 259, - 841, 842, 260, 261, 262, 263, 264, 265, 266, 267, + 227, 228, 0, 229, 230, 231, 232, 233, 234, 0, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 0, 245, 0, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 2060, 0, 256, 257, 258, 259, 0, + 260, 261, 262, 849, 850, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, - 278, 279, 280, 281, 282, 283, 843, 285, 844, 287, - 288, 289, 290, 845, 291, 292, 293, 294, 846, 847, - 296, 848, 298, 299, 300, 0, 301, 302, 0, 0, - 849, 304, 305, 0, 0, 306, 307, 308, 309, 310, - 850, 312, 313, 314, 315, 316, 317, 318, 319, 320, - 321, 0, 322, 323, 851, 325, 326, 327, 328, 329, - 330, 0, 331, 332, 333, 334, 335, 336, 337, 338, - 339, 852, 341, 342, 343, 344, 0, 345, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, 356, 0, - 357, 358, 359, 360, 361, 362, 853, 364, 365, 366, - 367, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 376, 377, 378, 379, 854, 380, 381, 382, 383, 384, - 385, 386, 387, 855, 389, 0, 390, 391, 392, 393, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 856, - 404, 0, 405, 406, 0, 407, 408, 409, 410, 411, - 412, 413, 0, 857, 858, 0, 0, 416, 417, 859, - 419, 860, 861, 421, 422, 862, 424, 425, 426, 427, - 428, 0, 0, 429, 430, 431, 432, 433, 863, 0, - 434, 435, 436, 437, 438, 439, 864, 0, 441, 442, - 443, 444, 445, 446, 0, 0, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, - 865, 0, 0, 0, 0, 0, 0, 866, 867, 0, - 0, 0, 0, 0, 869, 0, 1994, 0, 0, 0, - 0, 871, 0, 872, 873, 91, 806, 542, 807, 808, - 809, 810, 811, 0, 0, 0, 0, 0, 0, 0, - 0, 92, 93, 94, 95, 96, 97, 98, 99, 0, - 100, 101, 102, 0, 0, 0, 0, 812, 0, 0, - 103, 104, 0, 105, 106, 107, 108, 109, 110, 111, - 112, 813, 114, 814, 815, 0, 117, 118, 119, 120, - 121, 122, 816, 817, 123, 124, 818, 819, 127, 0, - 128, 129, 130, 131, 820, 0, 821, 0, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 0, 144, - 145, 146, 147, 148, 149, 0, 150, 151, 2654, 153, - 822, 823, 824, 825, 826, 827, 828, 155, 156, 157, - 158, 159, 160, 161, 829, 830, 164, 831, 165, 0, - 166, 167, 168, 169, 170, 171, 0, 172, 173, 174, - 175, 176, 0, 0, 177, 178, 668, 180, 181, 0, - 182, 183, 184, 0, 185, 186, 187, 0, 188, 189, - 190, 191, 832, 193, 194, 195, 196, 833, 834, 198, - 0, 199, 200, 835, 202, 0, 203, 0, 204, 205, - 0, 206, 207, 208, 209, 210, 211, 0, 212, 0, - 2655, 837, 215, 0, 216, 217, 218, 219, 220, 221, - 222, 223, 224, 225, 226, 0, 227, 228, 229, 230, - 231, 232, 0, 233, 234, 235, 236, 237, 238, 239, - 838, 839, 0, 840, 0, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 0, 0, 253, 254, 255, - 256, 0, 257, 258, 259, 841, 842, 260, 261, 262, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, 293, 0, 294, 295, 296, + 297, 0, 855, 299, 300, 301, 302, 303, 0, 304, + 305, 0, 580, 306, 307, 308, 0, 0, 309, 310, + 311, 312, 313, 858, 315, 316, 317, 318, 319, 320, + 321, 322, 323, 324, 0, 325, 326, 859, 328, 329, + 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, + 339, 0, 340, 341, 342, 343, 344, 345, 346, 347, + 0, 348, 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 0, 361, 362, 363, 364, 365, + 366, 367, 2061, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 0, 379, 380, 381, 382, 383, 862, + 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, + 0, 394, 395, 396, 397, 398, 399, 400, 401, 402, + 403, 404, 405, 406, 864, 408, 0, 409, 410, 0, + 411, 412, 413, 414, 415, 416, 417, 0, 418, 419, + 0, 0, 420, 421, 867, 423, 868, 0, 425, 426, + 870, 428, 429, 430, 431, 432, 0, 0, 433, 434, + 435, 436, 437, 871, 0, 438, 439, 440, 441, 442, + 443, 444, 0, 445, 446, 447, 448, 449, 450, 0, + 0, 451, 0, 0, 452, 453, 454, 455, 456, 457, + 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 0, 92, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2062, 93, 94, 95, 96, 97, 98, 99, 100, + 0, 101, 102, 103, 0, 0, 0, 0, 0, 0, + 0, 104, 105, 0, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 0, 118, 119, 120, + 121, 122, 123, 0, 825, 124, 125, 126, 127, 128, + 0, 129, 130, 131, 132, 828, 0, 829, 0, 135, + 136, 137, 138, 139, 140, 141, 142, 143, 144, 0, + 145, 146, 147, 148, 149, 150, 0, 151, 152, 153, + 154, 830, 831, 832, 833, 834, 835, 836, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 0, 166, + 0, 167, 168, 169, 170, 171, 172, 0, 173, 174, + 175, 176, 177, 0, 0, 178, 179, 180, 181, 182, + 0, 183, 184, 185, 0, 186, 187, 188, 0, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 841, 0, + 199, 0, 200, 201, 202, 203, 0, 204, 0, 205, + 206, 0, 207, 208, 209, 210, 211, 212, 0, 213, + 0, 214, 215, 216, 0, 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 228, 0, 229, 230, + 231, 232, 233, 234, 0, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 0, 245, 0, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, 0, 0, + 256, 257, 258, 259, 0, 260, 261, 262, 849, 850, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, - 283, 843, 285, 844, 287, 288, 289, 290, 845, 291, - 292, 293, 294, 846, 847, 296, 848, 298, 299, 300, - 0, 301, 302, 0, 0, 849, 304, 305, 0, 0, - 306, 307, 308, 309, 310, 850, 312, 313, 314, 315, - 316, 317, 318, 319, 320, 321, 0, 322, 323, 851, - 325, 326, 327, 328, 329, 330, 0, 331, 332, 333, - 334, 335, 336, 337, 338, 339, 852, 341, 342, 343, - 344, 0, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 0, 357, 358, 359, 360, 361, - 2656, 853, 364, 365, 366, 367, 368, 369, 370, 371, - 372, 373, 374, 0, 375, 376, 377, 378, 379, 854, - 380, 381, 382, 383, 384, 385, 386, 387, 855, 389, - 0, 390, 391, 392, 393, 394, 395, 396, 397, 398, - 399, 400, 401, 402, 856, 404, 0, 405, 406, 0, - 407, 408, 409, 410, 411, 412, 413, 0, 857, 858, - 0, 0, 416, 417, 859, 419, 860, 861, 421, 422, - 862, 424, 425, 426, 427, 428, 0, 0, 429, 430, - 431, 432, 433, 863, 0, 434, 435, 436, 437, 438, - 439, 864, 0, 441, 442, 443, 444, 445, 446, 0, - 0, 447, 0, 0, 448, 449, 450, 451, 452, 453, - 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 865, 0, 0, 0, 0, - 0, 0, 866, 867, 0, 0, 0, 0, 0, 869, - 0, 2657, 0, 0, 0, 0, 871, 0, 872, 873, - 91, 806, 542, 807, 808, 809, 810, 811, 0, 0, - 0, 0, 0, 0, 0, 0, 92, 93, 94, 95, - 96, 97, 98, 99, 0, 100, 101, 102, 0, 0, - 0, 0, 812, 0, 0, 103, 104, 0, 105, 106, - 107, 108, 109, 110, 111, 2869, 813, 114, 814, 815, - 0, 117, 118, 119, 120, 121, 122, 816, 817, 123, - 124, 818, 819, 127, 0, 128, 129, 130, 131, 820, - 0, 821, 0, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 0, 144, 145, 146, 147, 148, 149, - 0, 150, 151, 152, 2870, 822, 823, 824, 825, 826, - 827, 828, 155, 156, 157, 158, 159, 160, 161, 829, - 830, 164, 831, 165, 0, 166, 167, 168, 169, 170, - 171, 0, 172, 173, 174, 175, 176, 0, 0, 177, - 178, 668, 180, 181, 0, 182, 183, 184, 0, 185, - 186, 187, 0, 188, 189, 190, 191, 832, 193, 194, - 195, 196, 833, 834, 198, 0, 199, 200, 835, 202, - 0, 203, 0, 204, 205, 0, 206, 207, 208, 209, - 210, 211, 0, 212, 0, 836, 837, 215, 0, 216, + 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, + 293, 0, 294, 295, 296, 297, 0, 855, 299, 300, + 301, 302, 303, 0, 304, 305, 0, 0, 306, 307, + 308, 0, 0, 309, 310, 311, 312, 313, 858, 315, + 316, 317, 318, 319, 320, 321, 322, 323, 324, 0, + 325, 326, 859, 328, 329, 330, 331, 332, 333, 0, + 334, 335, 336, 337, 338, 339, 0, 340, 341, 342, + 343, 344, 345, 346, 347, 0, 348, 349, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 0, + 361, 362, 363, 364, 365, 366, 367, 2061, 369, 370, + 371, 372, 373, 374, 375, 376, 377, 378, 0, 379, + 380, 381, 382, 383, 862, 384, 385, 386, 387, 388, + 389, 390, 391, 392, 393, 0, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, 404, 405, 406, 864, + 408, 0, 409, 410, 0, 411, 412, 413, 414, 415, + 416, 417, 0, 418, 419, 0, 0, 420, 421, 867, + 423, 868, 0, 425, 426, 870, 428, 429, 430, 431, + 432, 0, 0, 433, 434, 435, 436, 437, 871, 0, + 438, 439, 440, 441, 442, 443, 444, 0, 445, 446, + 447, 448, 449, 450, 0, 0, 451, 0, 0, 452, + 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, + 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, + 0, 92, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 36, 93, 94, 95, + 96, 97, 98, 99, 100, 0, 101, 102, 103, 0, + 0, 0, 0, 0, 0, 0, 104, 105, 0, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 0, 118, 119, 120, 121, 122, 123, 0, 825, + 124, 125, 126, 127, 128, 0, 129, 130, 131, 132, + 828, 0, 829, 0, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 0, 145, 146, 147, 148, 149, + 150, 0, 151, 152, 153, 154, 830, 831, 832, 833, + 834, 835, 836, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 0, 166, 0, 167, 168, 169, 170, + 171, 172, 0, 173, 174, 175, 176, 177, 0, 0, + 178, 179, 180, 181, 182, 0, 183, 184, 185, 0, + 186, 187, 188, 0, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 841, 0, 199, 0, 200, 201, 202, + 203, 0, 204, 0, 205, 206, 0, 207, 208, 209, + 210, 211, 212, 0, 213, 0, 214, 215, 216, 0, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 0, 227, 228, 229, 230, 231, 232, 0, 233, 234, - 235, 236, 237, 238, 239, 838, 839, 0, 840, 0, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 0, 0, 253, 254, 255, 256, 0, 257, 258, 259, - 841, 842, 260, 261, 262, 263, 264, 265, 266, 267, + 227, 228, 0, 229, 230, 231, 232, 233, 234, 0, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 0, 245, 0, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 0, 0, 256, 257, 258, 259, 0, + 260, 261, 262, 849, 850, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, - 278, 279, 280, 281, 282, 283, 843, 285, 844, 287, - 288, 289, 290, 845, 291, 292, 293, 294, 846, 847, - 296, 848, 298, 299, 300, 0, 301, 302, 0, 0, - 849, 304, 305, 0, 0, 306, 307, 308, 309, 310, - 850, 312, 313, 314, 315, 316, 317, 318, 319, 320, - 321, 0, 322, 323, 851, 325, 326, 327, 328, 329, - 330, 0, 331, 332, 333, 334, 335, 336, 337, 338, - 339, 852, 341, 342, 343, 344, 0, 345, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, 356, 0, - 357, 358, 359, 360, 361, 362, 853, 364, 365, 366, - 367, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 376, 377, 378, 379, 854, 380, 381, 382, 383, 384, - 385, 386, 387, 855, 389, 0, 390, 391, 392, 393, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 856, - 404, 0, 405, 406, 0, 407, 408, 409, 410, 411, - 412, 413, 0, 857, 858, 0, 0, 416, 417, 859, - 419, 860, 861, 421, 422, 862, 424, 425, 2871, 427, - 428, 0, 0, 429, 430, 431, 432, 433, 863, 0, - 434, 435, 436, 437, 438, 439, 864, 0, 441, 442, - 443, 444, 445, 446, 0, 0, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, - 865, 0, 0, 0, 0, 0, 0, 866, 867, 0, - 0, 0, 0, 0, 869, 0, 870, 0, 0, 0, - 0, 871, 0, 872, 873, 91, 806, 542, 807, 808, - 809, 810, 811, 0, 0, 0, 0, 0, 0, 0, - 0, 92, 93, 94, 95, 96, 97, 98, 99, 0, - 100, 101, 102, 0, 0, 0, 0, 812, 0, 0, - 103, 104, 0, 105, 106, 107, 108, 109, 110, 111, - 112, 813, 114, 814, 815, 0, 117, 118, 119, 120, - 121, 122, 816, 817, 123, 124, 818, 819, 127, 0, - 128, 129, 130, 131, 820, 0, 821, 0, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 0, 144, - 145, 146, 147, 148, 149, 0, 150, 151, 152, 2870, - 822, 823, 824, 825, 826, 827, 828, 155, 156, 157, - 158, 159, 160, 161, 829, 830, 164, 831, 165, 0, - 166, 167, 168, 169, 170, 171, 0, 172, 173, 174, - 175, 176, 0, 0, 177, 178, 668, 180, 181, 0, - 182, 183, 184, 0, 185, 186, 187, 0, 188, 189, - 190, 191, 832, 193, 194, 195, 196, 833, 834, 198, - 0, 199, 200, 835, 202, 0, 203, 0, 204, 205, - 0, 206, 207, 208, 209, 210, 211, 0, 212, 0, - 836, 837, 215, 0, 216, 217, 218, 219, 220, 221, - 222, 223, 224, 225, 226, 0, 227, 228, 229, 230, - 231, 232, 0, 233, 234, 235, 236, 237, 238, 239, - 838, 839, 0, 840, 0, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 0, 0, 253, 254, 255, - 256, 0, 257, 258, 259, 841, 842, 260, 261, 262, - 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, 293, 0, 294, 295, 296, + 297, 0, 855, 299, 300, 301, 302, 303, 0, 304, + 305, 0, 0, 306, 307, 308, 0, 0, 309, 310, + 311, 312, 313, 858, 315, 316, 317, 318, 319, 320, + 321, 322, 323, 324, 0, 325, 326, 859, 328, 329, + 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, + 339, 0, 340, 341, 342, 343, 344, 345, 346, 347, + 0, 348, 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 0, 361, 362, 363, 364, 365, + 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 0, 379, 380, 381, 382, 383, 862, + 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, + 0, 394, 395, 396, 397, 398, 399, 400, 401, 402, + 403, 404, 405, 406, 864, 408, 0, 409, 410, 0, + 411, 412, 413, 414, 415, 416, 417, 0, 418, 419, + 0, 0, 420, 421, 867, 423, 868, 0, 425, 426, + 870, 428, 429, 430, 431, 432, 0, 0, 433, 434, + 435, 436, 437, 871, 0, 438, 439, 440, 441, 442, + 443, 444, 0, 445, 446, 447, 448, 449, 450, 0, + 0, 451, 0, 0, 452, 453, 454, 455, 456, 457, + 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 0, 742, 1232, 547, 0, + 0, 0, 818, 0, 0, 0, 0, 0, 0, 0, + 0, 2702, 93, 94, 95, 96, 97, 98, 99, 100, + 0, 101, 102, 103, 0, 0, 0, 0, 0, 0, + 0, 104, 105, 0, 106, 107, 108, 0, 110, 111, + 112, 743, 744, 0, 745, 746, 0, 118, 119, 120, + 121, 122, 123, 0, 0, 124, 125, 747, 748, 128, + 0, 129, 130, 131, 132, 749, 0, 0, 0, 135, + 136, 137, 138, 139, 140, 0, 142, 143, 144, 0, + 145, 146, 147, 148, 149, 150, 0, 0, 152, 153, + 154, 0, 0, 0, 0, 0, 0, 0, 156, 157, + 158, 159, 160, 161, 162, 750, 751, 165, 0, 166, + 0, 167, 168, 169, 170, 171, 172, 0, 173, 174, + 175, 176, 177, 0, 0, 178, 179, 180, 181, 182, + 0, 183, 184, 185, 0, 186, 187, 188, 0, 189, + 190, 191, 192, 752, 194, 195, 196, 197, 753, 1233, + 199, 0, 200, 201, 754, 203, 0, 204, 0, 205, + 0, 0, 0, 208, 209, 210, 0, 212, 0, 213, + 0, 755, 756, 216, 0, 217, 218, 219, 220, 221, + 222, 223, 0, 225, 226, 227, 228, 0, 229, 230, + 231, 232, 233, 234, 0, 235, 0, 757, 238, 239, + 240, 241, 242, 758, 759, 0, 760, 0, 246, 0, + 0, 249, 0, 251, 252, 253, 254, 255, 0, 0, + 256, 0, 258, 0, 0, 260, 261, 262, 0, 0, + 263, 264, 265, 266, 267, 761, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, - 283, 843, 285, 844, 287, 288, 289, 290, 845, 291, - 292, 293, 294, 846, 847, 296, 848, 298, 299, 300, - 0, 301, 302, 0, 0, 849, 304, 305, 0, 0, - 306, 307, 308, 309, 310, 850, 312, 313, 314, 315, - 316, 317, 318, 319, 320, 321, 0, 322, 323, 851, - 325, 326, 327, 328, 329, 330, 0, 331, 332, 333, - 334, 335, 336, 337, 338, 339, 852, 341, 342, 343, - 344, 0, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 0, 357, 358, 359, 360, 361, - 362, 853, 364, 365, 366, 367, 368, 369, 370, 371, - 372, 373, 374, 0, 375, 376, 377, 378, 379, 854, - 380, 381, 382, 383, 384, 385, 386, 387, 855, 389, - 0, 390, 391, 392, 393, 394, 395, 396, 397, 398, - 399, 400, 401, 402, 856, 404, 0, 405, 406, 0, - 407, 408, 409, 410, 411, 412, 413, 0, 857, 858, - 0, 0, 416, 417, 859, 419, 860, 861, 421, 422, - 862, 424, 425, 2871, 427, 428, 0, 0, 429, 430, - 431, 432, 433, 863, 0, 434, 435, 436, 437, 438, - 439, 864, 0, 441, 442, 443, 444, 445, 446, 0, - 0, 447, 0, 0, 448, 449, 450, 451, 452, 453, - 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 865, 0, 0, 0, 0, - 0, 0, 866, 867, 0, 0, 0, 0, 0, 869, - 0, 870, 0, 0, 0, 0, 871, 0, 872, 873, - 91, 806, 542, 807, 808, 809, 810, 811, 0, 0, - 0, 0, 0, 0, 0, 0, 92, 93, 94, 95, - 96, 97, 98, 99, 0, 100, 101, 102, 0, 0, - 0, 0, 812, 0, 0, 103, 104, 0, 105, 106, - 107, 108, 109, 110, 111, -1713, 813, 114, 814, 815, - 0, 117, 118, 119, 120, 121, 122, 816, 817, 123, - 124, 818, 819, 127, 0, 128, 129, 130, 131, 820, - 0, 821, 0, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 0, 144, 145, 146, 147, 148, 149, - 0, 150, 151, 152, 2870, 822, 823, 824, 825, 826, - 827, 828, 155, 156, 157, 158, 159, 160, 161, 829, - 830, 164, 831, 165, 0, 166, 167, 168, 169, 170, - 171, 0, 172, 173, 174, 175, 176, 0, 0, 177, - 178, 668, 180, 181, 0, 182, 183, 184, 0, 185, - 186, 187, 0, 188, 189, 190, 191, 832, 193, 194, - 195, 196, 833, 834, 198, 0, 199, 200, 835, 202, - 0, 203, 0, 204, 205, 0, 206, 207, 208, 209, - -1713, 211, 0, 212, 0, 836, 837, 215, 0, 216, - 217, 218, 219, 220, 221, -1713, 223, 224, 225, 226, - 0, 227, 228, 229, 230, 231, 232, 0, 233, 234, - 235, 236, 237, 238, 239, 838, 839, 0, 840, 0, - 243, 0, 0, 246, 247, 248, 249, 250, 251, 252, - 0, 0, 253, 254, 255, -1713, 0, 257, 258, 259, - 841, 842, 260, 261, 262, 263, 264, 265, 266, 267, - 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, - 278, 279, 280, 281, 282, 283, 843, 285, 844, 287, - 288, 289, 290, 0, 291, 292, 0, 294, 846, 847, - 296, 848, 298, 299, 300, 0, 301, 302, 0, 0, - 849, 304, 305, 0, 0, 306, 307, 308, 309, 310, - 850, 312, 313, 314, 315, 316, 317, 318, 319, 320, - 321, 0, 322, 323, 851, 325, 326, 327, 328, 329, - 330, 0, 331, 332, 333, 334, 335, 336, 337, 338, - 339, 852, 341, 342, 343, 344, 0, 345, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, 356, 0, - 357, 358, 359, 360, 361, 362, 853, 364, 365, 366, - 367, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 376, 377, 378, 379, 854, 380, 381, 382, 383, 384, - -1713, 386, 387, 855, 389, 0, 390, 391, 392, 393, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 856, - 404, 0, 405, 406, 0, 407, 408, 409, 410, 411, - 412, 413, 0, 857, 858, 0, 0, 416, 417, 859, - 419, 860, 861, 421, 422, 862, 424, 425, 2871, 427, - 428, 0, 0, 429, 430, 431, 432, 433, 863, 0, - 434, 435, 436, 437, 438, 439, 864, 0, 441, 442, - 443, 444, 445, 446, 0, 0, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, - -1713, 0, 0, 0, 0, 0, 0, 866, 867, 0, - 0, 0, 0, 0, 869, 0, 870, 0, 0, 0, - 0, 871, 0, 872, 873, 91, 806, 542, 807, 808, - 809, 810, 811, 0, 0, 0, 0, 0, 0, 0, - 0, 92, 93, 94, 95, 96, 97, 98, 99, 0, - 100, 101, 102, 0, 0, 0, 0, 0, 0, 0, - 103, 104, 0, 105, 106, 107, 108, 109, 110, 111, - 112, 813, 114, 814, 815, 0, 117, 118, 119, 120, - 121, 122, 816, 817, 123, 124, 818, 819, 127, 0, - 128, 129, 130, 131, 820, 0, 821, 0, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 0, 144, - 145, 146, 147, 148, 149, 0, 150, 151, 152, 153, - 822, 823, 824, 825, 826, 827, 828, 155, 156, 157, - 158, 159, 160, 161, 829, 830, 164, 0, 165, 0, - 166, 167, 168, 169, 170, 171, 0, 172, 173, 174, - 175, 176, 0, 0, 177, 178, 668, 180, 181, 0, - 182, 183, 184, 0, 185, 186, 187, 0, 188, 189, - 190, 191, 832, 193, 194, 195, 196, 833, 834, 198, - 0, 199, 200, 835, 202, 0, 203, 0, 204, 205, - 0, 206, 207, 208, 209, 210, 211, 0, 212, 0, - 836, 837, 215, 0, 216, 217, 218, 219, 220, 221, - 222, 223, 224, 225, 226, 0, 227, 228, 229, 230, - 231, 232, 0, 233, 234, 235, 236, 237, 238, 239, - 838, 839, 0, 840, 0, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 0, 0, 253, 254, 255, - 256, 0, 257, 258, 259, 841, 842, 260, 261, 262, - 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 283, 284, 285, 286, 762, 0, 763, 290, 291, 292, + 764, 0, 294, 295, 0, 297, 0, 765, 299, 766, + 301, 302, 303, 0, 304, 305, 1234, 0, 306, 307, + 308, 0, 0, 309, 767, 0, 312, 0, 768, 315, + 316, 317, 318, 319, 320, 321, 322, 323, 324, 0, + 325, 326, 769, 328, 329, 770, 331, 332, 333, 0, + 334, 335, 336, 337, 338, 339, 0, 340, 341, 342, + 771, 344, 345, 346, 347, 0, 348, 349, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 0, + 361, 362, 0, 364, 365, 366, 772, 368, 369, 370, + 371, 372, 373, 374, 375, 376, 377, 378, 0, 379, + 380, 381, 382, 383, 0, 384, 773, 386, 387, 388, + 0, 390, 391, 774, 393, 0, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, 404, 775, 406, 776, + 408, 0, 409, 410, 0, 411, 0, 413, 414, 415, + 416, 417, 0, 777, 778, 0, 0, 420, 421, 779, + 423, 780, 1235, 425, 426, 781, 428, 429, 430, 431, + 432, 0, 0, 433, 434, 435, 436, 437, 0, 0, + 438, 439, 440, 441, 442, 1125, 783, 0, 445, 0, + 447, 448, 449, 450, 0, 0, 451, 0, 0, 452, + 453, 454, 455, 456, 457, 784, 785, 786, 787, 788, + 789, 790, 791, 792, 793, 794, 469, 470, 471, 472, + 0, 742, 0, 0, 0, 0, 0, 1236, 1237, 1940, + 0, 0, 0, 0, 0, 0, 1941, 93, 94, 95, + 96, 97, 98, 99, 100, 0, 101, 102, 103, 3, + 4, 0, 0, 0, 0, 0, 104, 105, 0, 106, + 107, 108, 0, 110, 111, 112, 743, 744, 0, 745, + 746, 0, 118, 119, 120, 121, 122, 123, 0, 0, + 124, 125, 747, 748, 128, 0, 129, 130, 131, 132, + 749, 0, 0, 0, 135, 136, 137, 138, 139, 140, + 0, 142, 143, 144, 0, 145, 146, 147, 148, 149, + 150, 0, 0, 152, 153, 154, 0, 0, 0, 0, + 0, 0, 0, 156, 157, 158, 159, 160, 161, 162, + 750, 751, 165, 0, 166, 0, 167, 168, 169, 170, + 171, 172, 0, 173, 174, 175, 176, 177, 0, 0, + 178, 179, 180, 181, 182, 0, 183, 184, 185, 0, + 186, 187, 188, 0, 189, 190, 191, 192, 752, 194, + 195, 196, 197, 753, 0, 199, 0, 200, 201, 754, + 203, 0, 204, 0, 205, 0, 0, 0, 208, 209, + 210, 0, 212, 0, 213, 0, 755, 756, 216, 0, + 217, 218, 219, 220, 221, 222, 223, 0, 225, 226, + 227, 228, 0, 229, 230, 231, 232, 233, 234, 0, + 235, 0, 757, 238, 239, 240, 241, 242, 758, 759, + 0, 760, 0, 246, 0, 0, 249, 0, 251, 252, + 253, 254, 255, 0, 0, 256, 0, 258, 0, 0, + 260, 261, 262, 0, 0, 263, 264, 265, 266, 267, + 761, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 762, + 0, 763, 290, 291, 292, 764, 0, 294, 295, 0, + 297, 0, 765, 299, 766, 301, 302, 303, 0, 304, + 305, 0, 0, 306, 307, 308, 0, 0, 309, 767, + 0, 312, 0, 768, 315, 316, 317, 318, 319, 320, + 321, 322, 323, 324, 0, 325, 326, 769, 328, 329, + 770, 331, 332, 333, 0, 334, 335, 336, 337, 338, + 339, 0, 340, 341, 342, 771, 344, 345, 346, 347, + 0, 348, 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 0, 361, 362, 0, 364, 365, + 366, 772, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 26, 379, 380, 381, 382, 383, 0, + 384, 773, 386, 387, 388, 0, 390, 391, 774, 393, + 0, 394, 395, 396, 397, 398, 399, 400, 401, 402, + 403, 404, 775, 406, 776, 408, 0, 409, 410, 31, + 411, 0, 413, 414, 415, 416, 417, 0, 777, 778, + 0, 0, 420, 421, 779, 423, 780, 0, 425, 426, + 781, 428, 429, 430, 431, 432, 0, 0, 433, 434, + 435, 436, 437, 0, 0, 438, 439, 440, 441, 442, + 782, 783, 0, 445, 0, 447, 448, 449, 450, 0, + 0, 451, 0, 34, 452, 453, 454, 455, 456, 457, + 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, + 794, 469, 470, 471, 472, 0, 498, 35, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 36, 93, 94, 95, 96, 97, 98, 99, 100, + 613, 101, 102, 103, 0, 0, 0, 0, 0, 0, + 0, 104, 105, 0, 106, 107, 108, 0, 110, 111, + 112, 113, 114, 0, 116, 117, 0, 118, 119, 120, + 121, 122, 123, 0, 0, 124, 125, 126, 127, 128, + 0, 129, 130, 131, 132, 133, 0, 0, 0, 135, + 136, 137, 138, 139, 140, 0, 142, 143, 144, 0, + 145, 146, 147, 148, 149, 150, 0, 0, 152, 153, + 154, 0, 0, 0, 0, 0, 0, 0, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 0, 166, + 0, 167, 168, 169, 170, 171, 172, 0, 173, 174, + 175, 176, 177, 0, 0, 178, 179, 180, 181, 182, + 0, 183, 184, 185, 0, 186, 187, 188, 0, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 198, 0, + 199, 0, 200, 201, 202, 203, 0, 204, 0, 205, + 0, 0, 0, 208, 209, 210, 0, 212, 0, 213, + 0, 214, 215, 216, 0, 217, 218, 219, 220, 221, + 222, 223, 0, 225, 226, 227, 228, 0, 229, 230, + 231, 232, 233, 234, 0, 235, 0, 237, 238, 239, + 240, 241, 242, 243, 244, 0, 245, 0, 246, 0, + 0, 249, 0, 251, 252, 253, 254, 255, 0, 0, + 256, 0, 258, 0, 0, 260, 261, 262, 0, 0, + 263, 264, 265, 266, 267, 500, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, - 283, 843, 285, 844, 287, 288, 289, 290, 0, 291, - 292, 293, 294, 846, 847, 296, 848, 298, 299, 300, - 0, 301, 302, 0, 0, 849, 304, 305, 0, 0, - 306, 307, 308, 309, 310, 850, 312, 313, 314, 315, - 316, 317, 318, 319, 320, 321, 0, 322, 323, 851, - 325, 326, 327, 328, 329, 330, 0, 331, 332, 333, - 334, 335, 336, 337, 338, 339, 852, 341, 342, 343, - 344, 0, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 0, 357, 358, 359, 360, 361, - 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, - 372, 373, 374, 0, 375, 376, 377, 378, 379, 854, - 380, 381, 382, 383, 384, 385, 386, 387, 855, 389, - 0, 390, 391, 392, 393, 394, 395, 396, 397, 398, - 399, 400, 401, 402, 856, 404, 0, 405, 406, 0, - 407, 408, 409, 410, 411, 412, 413, 0, 857, 858, - 0, 0, 416, 417, 859, 419, 860, 861, 421, 422, - 862, 424, 425, 426, 427, 428, 0, 0, 429, 430, - 431, 432, 433, 863, 0, 434, 435, 436, 437, 438, - 439, 864, 0, 441, 442, 443, 444, 445, 446, 0, - 0, 447, 0, 0, 448, 449, 450, 451, 452, 453, - 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 0, 0, 0, 0, 0, - 0, 0, 1620, 1621, 0, 0, 91, 806, 542, 807, - 808, 1622, 810, 811, 0, 0, 0, 0, 872, 873, - 0, 0, 92, 93, 94, 95, 96, 97, 98, 99, - 0, 100, 101, 102, 0, 0, 0, 0, 0, 0, - 0, 103, 104, 0, 105, 106, 107, 108, 109, 110, - 111, 112, 813, 114, 814, 815, 0, 117, 118, 119, - 120, 121, 122, 816, 817, 123, 124, 818, 819, 127, - 0, 128, 129, 130, 131, 820, 0, 821, 0, 134, - 135, 136, 137, 138, 139, 140, 141, 142, 143, 0, - 144, 145, 146, 147, 148, 149, 0, 150, 151, 152, - 153, 822, 823, 824, 825, 826, 827, 828, 155, 156, - 157, 158, 159, 160, 161, 829, 830, 164, 0, 165, - 0, 166, 167, 168, 169, 170, 171, 0, 172, 173, - 174, 175, 176, 0, 0, 177, 178, 668, 180, 181, - 0, 182, 183, 184, 0, 185, 186, 187, 0, 188, - 189, 190, 191, 832, 193, 194, 195, 196, 833, 834, - 198, 0, 199, 200, 835, 202, 0, 203, 0, 204, - 205, 0, 206, 207, 208, 209, 210, 211, 0, 212, - 0, 836, 837, 215, 0, 216, 217, 218, 219, 220, - 221, 222, 223, 224, 225, 226, 0, 227, 228, 229, - 230, 231, 232, 0, 233, 234, 235, 236, 237, 238, - 239, 838, 839, 0, 840, 0, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 0, 0, 253, 254, - 255, 256, 0, 257, 258, 259, 841, 842, 260, 261, - 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, - 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, - 282, 283, 843, 285, 844, 287, 288, 289, 290, 0, - 291, 292, 293, 294, 846, 847, 296, 848, 298, 299, - 300, 0, 301, 302, 0, 0, 303, 304, 305, 0, - 0, 306, 307, 308, 309, 310, 850, 312, 313, 314, - 315, 316, 317, 318, 319, 320, 321, 0, 322, 323, - 851, 325, 326, 327, 328, 329, 330, 0, 331, 332, - 333, 334, 335, 336, 337, 338, 339, 852, 341, 342, - 343, 344, 0, 345, 346, 347, 348, 349, 350, 351, - 352, 353, 354, 355, 356, 0, 357, 358, 359, 360, - 361, 362, 1757, 1758, 365, 366, 367, 368, 369, 370, - 371, 372, 373, 374, 0, 375, 376, 377, 378, 379, - 854, 380, 381, 382, 383, 384, 385, 386, 387, 855, - 389, 0, 390, 391, 392, 393, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 856, 404, 0, 405, 406, - 0, 407, 408, 409, 410, 411, 412, 413, 0, 857, - 858, 0, 0, 416, 417, 859, 419, 860, 861, 421, - 422, 862, 424, 425, 426, 427, 428, 0, 0, 429, - 430, 431, 432, 433, 863, 0, 434, 435, 436, 437, - 438, 439, 864, 0, 441, 442, 443, 444, 445, 446, - 0, 0, 447, 0, 0, 448, 449, 450, 451, 452, + 283, 284, 285, 286, 287, 0, 289, 290, 291, 292, + 293, 0, 294, 295, 0, 297, 0, 298, 299, 300, + 301, 302, 303, 0, 304, 305, 0, 0, 306, 307, + 308, 0, 0, 309, 310, 0, 312, 0, 314, 315, + 316, 317, 318, 319, 320, 321, 322, 323, 324, 0, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 0, + 334, 335, 336, 337, 338, 339, 0, 340, 341, 342, + 343, 344, 345, 346, 347, 0, 348, 349, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 0, + 361, 362, 0, 364, 365, 366, 367, 368, 369, 370, + 371, 372, 373, 374, 375, 376, 377, 378, 26, 379, + 380, 381, 382, 383, 0, 384, 385, 386, 387, 388, + 0, 390, 391, 392, 393, 0, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, 404, 502, 406, 407, + 408, 0, 409, 410, 31, 411, 0, 413, 414, 415, + 416, 417, 0, 614, 419, 0, 0, 615, 421, 422, + 423, 424, 0, 425, 426, 427, 428, 429, 430, 431, + 432, 0, 0, 433, 434, 435, 436, 437, 0, 0, + 438, 439, 440, 441, 442, 575, 444, 0, 445, 0, + 447, 448, 449, 450, 0, 0, 451, 0, 34, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, - 463, 464, 465, 466, 467, 468, 0, 0, 0, 0, - 0, 0, 0, 1759, 1760, 0, 0, 0, 0, 0, - 0, 0, 1622, 0, 0, 0, 0, 0, 0, 872, - 873, 91, 806, 542, 807, 808, 809, 810, 811, 0, - 0, 0, 0, 0, 0, 0, 0, 92, 93, 94, - 95, 96, 97, 98, 99, 0, 100, 101, 102, 0, - 0, 0, 0, 0, 0, 0, 103, 104, 0, 105, - 106, 107, 108, 109, 110, 111, 112, 813, 114, 814, - 815, 0, 117, 118, 119, 120, 121, 122, 816, 817, - 123, 124, 818, 819, 127, 0, 128, 129, 130, 131, - 820, 0, 821, 0, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 0, 144, 145, 146, 147, 148, - 149, 0, 150, 151, 152, 153, 822, 823, 824, 825, - 826, 827, 828, 155, 156, 157, 158, 159, 160, 161, - 829, 830, 164, 0, 165, 0, 166, 167, 168, 169, - 170, 171, 0, 172, 173, 174, 175, 176, 0, 0, - 177, 178, 668, 180, 181, 0, 182, 183, 184, 0, - 185, 186, 187, 0, 188, 189, 190, 191, 832, 193, - 194, 195, 196, 833, 834, 198, 0, 199, 200, 835, - 202, 0, 203, 0, 204, 205, 0, 206, 207, 208, - 209, 210, 211, 0, 212, 0, 836, 837, 215, 0, - 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 0, 227, 228, 229, 230, 231, 232, 0, 233, - 234, 235, 236, 237, 238, 239, 838, 839, 0, 840, - 0, 243, 0, 245, 246, 247, 248, 249, 250, 251, - 252, 0, 0, 253, 254, 255, 256, 0, 257, 258, - 259, 841, 842, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 843, 285, 844, - 287, 288, 289, 290, 0, 291, 292, 293, 294, 846, - 847, 296, 848, 298, 299, 300, 0, 301, 302, 0, - 0, 849, 304, 305, 0, 0, 306, 307, 308, 309, - 310, 850, 312, 313, 314, 315, 316, 317, 318, 319, - 320, 321, 0, 322, 323, 851, 325, 326, 327, 328, - 329, 330, 0, 331, 332, 333, 334, 335, 336, 337, - 338, 339, 852, 341, 342, 343, 344, 0, 345, 346, - 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 370, 371, 372, 373, 374, 0, - 375, 376, 377, 378, 379, 854, 380, 381, 382, 383, - 384, 385, 386, 387, 855, 389, 0, 390, 391, 392, - 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, - 856, 404, 0, 405, 406, 0, 407, 408, 409, 410, - 411, 412, 413, 0, 857, 858, 0, 0, 416, 417, - 859, 419, 860, 861, 421, 422, 862, 424, 425, 426, - 427, 428, 0, 0, 429, 430, 431, 432, 433, 863, - 0, 434, 435, 436, 437, 438, 439, 864, 0, 441, - 442, 443, 444, 445, 446, 0, 0, 447, 0, 0, - 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, + 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, + 0, 498, 35, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 36, 93, 94, 95, + 96, 97, 98, 99, 100, 0, 101, 102, 103, 0, + 0, 0, 0, 0, 0, 0, 104, 105, 0, 106, + 107, 108, 0, 110, 111, 112, 113, 114, 0, 116, + 117, 0, 118, 119, 120, 121, 122, 123, 0, 0, + 124, 125, 126, 127, 128, 0, 129, 130, 131, 132, + 133, 0, 0, 0, 135, 136, 137, 138, 139, 140, + 0, 142, 143, 144, 0, 145, 146, 147, 148, 149, + 150, 0, 0, 152, 153, 154, 0, 0, 0, 0, + 0, 0, 0, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 0, 166, 0, 167, 168, 169, 170, + 171, 172, 0, 173, 174, 175, 176, 177, 0, 0, + 178, 179, 180, 181, 182, 0, 183, 184, 185, 0, + 186, 187, 188, 0, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 0, 199, 0, 200, 201, 202, + 203, 0, 204, 0, 205, 0, 0, 0, 208, 209, + 210, 0, 212, 0, 213, 0, 214, 215, 216, 0, + 217, 218, 219, 220, 221, 222, 223, 0, 225, 226, + 227, 228, 0, 229, 230, 231, 232, 233, 234, 0, + 235, 0, 237, 238, 239, 240, 241, 242, 243, 244, + 0, 245, 0, 246, 0, 0, 249, 0, 251, 252, + 253, 254, 255, 0, 0, 256, 0, 258, 0, 0, + 260, 261, 262, 0, 0, 263, 264, 265, 266, 267, + 500, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 0, 289, 290, 291, 292, 293, 0, 294, 295, 0, + 297, 0, 298, 299, 300, 301, 302, 303, 0, 304, + 305, 0, 0, 306, 307, 308, 0, 0, 309, 310, + 0, 312, 0, 314, 315, 316, 317, 318, 319, 320, + 321, 322, 323, 324, 0, 325, 326, 327, 328, 329, + 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, + 339, 0, 340, 341, 342, 343, 344, 345, 346, 347, + 0, 348, 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 0, 361, 362, 0, 364, 365, + 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 26, 379, 380, 381, 382, 383, 0, + 384, 385, 386, 387, 388, 0, 390, 391, 392, 393, + 0, 394, 395, 396, 397, 398, 399, 400, 401, 402, + 403, 404, 502, 406, 407, 408, 0, 409, 410, 31, + 411, 0, 413, 414, 415, 416, 417, 0, 418, 419, + 0, 0, 420, 421, 422, 423, 424, 0, 425, 426, + 427, 428, 429, 430, 431, 432, 0, 0, 433, 434, + 435, 436, 437, 0, 0, 438, 439, 440, 441, 442, + 575, 444, 0, 445, 0, 447, 448, 449, 450, 0, + 0, 451, 0, 34, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 0, 0, 0, 0, 0, 0, 0, 1620, 1621, - 0, 0, 0, 0, 0, 0, 0, 1622, 0, 0, - 0, 0, 0, 0, 872, 873, 91, 806, 542, 807, - 808, 809, 810, 811, 0, 0, 0, 0, 0, 0, - 0, 0, 92, 93, 94, 95, 96, 97, 98, 99, - 0, 100, 101, 102, 0, 0, 0, 0, 812, 0, - 0, 103, 104, 0, 105, 106, 107, 108, 109, 110, - 111, 0, 813, 114, 814, 815, 0, 117, 118, 119, - 120, 121, 122, 816, 817, 123, 124, 818, 819, 127, - 0, 128, 129, 130, 131, 820, 0, 821, 0, 134, - 135, 136, 137, 138, 139, 140, 141, 142, 143, 0, - 144, 145, 146, 147, 148, 149, 0, 150, 151, 152, - 153, 822, 823, 824, 825, 826, 827, 828, 155, 156, - 157, 158, 159, 160, 161, 829, 830, 164, 831, 165, - 0, 166, 167, 168, 169, 170, 171, 0, 172, 173, - 174, 175, 176, 0, 0, 177, 178, 668, 180, 181, - 0, 182, 183, 184, 0, 185, 0, 187, 0, 188, - 189, 190, 191, 832, 193, 194, 195, 196, 833, 834, - 198, 0, 199, 200, 835, 202, 0, 203, 0, 204, - 205, 0, 206, 207, 208, 209, 0, 211, 0, 212, - 0, 836, 837, 215, 0, 216, 217, 218, 219, 220, - 221, 0, 223, 224, 225, 226, 0, 227, 228, 229, - 230, 231, 232, 0, 233, 234, 235, 236, 237, 238, - 239, 838, 839, 0, 840, 0, 243, 0, 0, 246, - 247, 248, 249, 250, 251, 252, 0, 0, 253, 254, - 255, 0, 0, 257, 258, 259, 841, 842, 260, 261, - 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, - 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, - 282, 283, 843, 285, 844, 287, 288, 289, 290, 0, - 291, 292, 0, 294, 846, 847, 296, 848, 298, 299, - 300, 0, 301, 302, 0, 0, 849, 304, 305, 0, - 0, 306, 307, 308, 309, 310, 850, 312, 313, 314, - 315, 316, 317, 318, 319, 320, 321, 0, 322, 323, - 851, 325, 326, 327, 328, 329, 330, 0, 331, 332, - 333, 334, 335, 336, 337, 338, 339, 852, 341, 342, - 343, 344, 0, 345, 346, 347, 348, 349, 350, 351, - 352, 353, 354, 355, 356, 0, 357, 358, 359, 360, - 361, 362, 853, 364, 365, 366, 367, 368, 369, 370, - 371, 372, 373, 374, 0, 375, 376, 377, 378, 379, - 854, 380, 381, 382, 383, 384, 0, 386, 387, 855, - 389, 0, 390, 391, 392, 393, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 856, 404, 0, 405, 406, - 0, 407, 408, 409, 410, 411, 412, 413, 0, 857, - 858, 0, 0, 416, 417, 859, 419, 860, 861, 421, - 422, 862, 424, 425, 426, 427, 428, 0, 0, 429, - 430, 431, 432, 433, 863, 0, 434, 435, 436, 437, - 438, 439, 864, 0, 441, 442, 443, 444, 445, 446, - 0, 0, 447, 0, 0, 448, 449, 450, 451, 452, + 468, 469, 470, 471, 472, 0, 498, 35, 579, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 36, 93, 94, 95, 96, 97, 98, 99, 100, + 0, 101, 102, 103, 0, 0, 0, 0, 0, 0, + 0, 104, 105, 0, 106, 107, 108, 0, 110, 111, + 112, 113, 114, 0, 116, 117, 0, 118, 119, 120, + 121, 122, 123, 0, 0, 124, 125, 126, 127, 128, + 0, 129, 130, 131, 132, 133, 0, 0, 0, 135, + 136, 137, 138, 139, 140, 0, 142, 143, 144, 0, + 145, 146, 147, 148, 149, 150, 0, 0, 152, 153, + 154, 0, 0, 0, 0, 0, 0, 0, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 0, 166, + 0, 167, 168, 169, 170, 171, 172, 0, 173, 174, + 175, 176, 177, 0, 0, 178, 179, 180, 181, 182, + 0, 183, 184, 185, 0, 186, 187, 188, 0, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 198, 0, + 199, 0, 200, 201, 202, 203, 0, 204, 0, 205, + 0, 0, 0, 208, 209, 210, 0, 212, 0, 213, + 0, 214, 215, 216, 0, 217, 218, 219, 220, 221, + 222, 223, 0, 225, 226, 227, 228, 0, 229, 230, + 231, 232, 233, 234, 0, 235, 0, 237, 238, 239, + 240, 241, 242, 243, 244, 0, 245, 0, 246, 0, + 0, 249, 0, 251, 252, 253, 254, 255, 0, 0, + 256, 0, 258, 0, 0, 260, 261, 262, 0, 0, + 263, 264, 265, 266, 267, 500, 269, 270, 271, 272, + 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, 0, 289, 290, 291, 292, + 293, 0, 294, 295, 0, 297, 0, 298, 299, 300, + 301, 302, 303, 0, 304, 305, 0, 0, 306, 307, + 308, 0, 0, 309, 310, 0, 312, 0, 314, 315, + 316, 317, 318, 319, 320, 321, 322, 323, 324, 0, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 0, + 334, 335, 336, 337, 338, 339, 0, 340, 341, 342, + 343, 344, 345, 346, 347, 0, 348, 349, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 0, + 361, 362, 0, 364, 365, 366, 367, 368, 369, 370, + 371, 372, 373, 374, 375, 376, 377, 378, 0, 379, + 380, 381, 382, 383, 0, 384, 385, 386, 387, 388, + 0, 390, 391, 392, 393, 0, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, 404, 502, 406, 407, + 408, 0, 409, 410, 0, 411, 0, 413, 414, 415, + 416, 417, 0, 418, 419, 0, 0, 420, 421, 422, + 423, 424, 0, 425, 426, 427, 428, 429, 430, 431, + 432, 0, 0, 433, 434, 435, 436, 437, 0, 0, + 438, 439, 440, 441, 442, 443, 444, 0, 445, 0, + 447, 448, 449, 450, 0, 0, 451, 0, 0, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, - 463, 464, 465, 466, 467, 468, 0, 0, 0, 0, - 0, 0, 0, 866, 867, 494, 0, 0, 0, 0, - 869, 0, 870, 0, 0, 0, 0, 871, 0, 872, - 873, 92, 93, 94, 95, 96, 97, 98, 99, 0, - 100, 101, 102, 0, 0, 0, 0, 0, 2286, 0, - 103, 104, 0, 105, 106, 107, 0, 109, 110, 111, - 112, 113, 0, 115, 116, 0, 117, 118, 119, 120, - 121, 122, 0, 0, 123, 124, 125, 126, 127, 0, - 128, 129, 130, 131, 132, 0, 0, 0, 134, 135, - 136, 137, 138, 139, 0, 141, 142, 143, 0, 144, - 145, 146, 147, 148, 149, 0, -600, 151, 152, 153, - 0, 0, 0, 0, 0, 0, 0, 155, 156, 157, - 158, 159, 160, 161, 162, 163, 164, 0, 165, 0, - 166, 167, 168, 169, 170, 171, 0, 172, 173, 174, - 175, 176, 0, 0, 177, 178, 179, 180, 181, 0, - 182, 183, 184, 0, 185, 186, 187, 0, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 0, 198, - 0, 199, 200, 201, 202, 0, 203, 0, 204, 0, - 0, -600, 207, 208, 209, 0, 211, 0, 212, 0, - 213, 214, 215, 0, 216, 217, 218, 219, 220, 221, - 0, 223, 224, 225, 226, 0, 227, 228, 229, 230, - 231, 232, 0, 233, -600, 235, 236, 237, 238, 239, - 240, 241, 0, 242, 0, 243, 0, 0, 246, -600, - 248, 249, 250, 251, 252, 0, 0, 253, -600, 255, - 0, 0, 257, 258, 259, 0, 0, 260, 261, 262, - 263, 264, 496, 266, 267, 268, 269, 270, 271, 272, + 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, + 0, 498, 0, 579, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 921, 93, 94, 95, + 96, 97, 98, 99, 100, 0, 101, 102, 103, 0, + 0, 0, 0, 0, 0, 0, 104, 105, 0, 106, + 107, 108, 0, 110, 111, 112, 113, 114, 0, 116, + 117, 0, 118, 119, 120, 121, 122, 123, 0, 0, + 124, 125, 126, 127, 128, 0, 129, 130, 131, 132, + 133, 0, 0, 0, 135, 136, 137, 138, 139, 140, + 0, 142, 143, 144, 0, 145, 146, 147, 148, 149, + 150, 0, 0, 152, 153, 154, 0, 0, 0, 0, + 0, 0, 0, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 0, 166, 0, 167, 168, 169, 170, + 171, 172, 0, 173, 174, 175, 176, 177, 0, 0, + 178, 179, 180, 181, 182, 0, 183, 184, 185, 0, + 186, 187, 188, 0, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 0, 199, 0, 200, 201, 202, + 203, 0, 204, 0, 205, 0, 0, 0, 208, 209, + 210, 0, 212, 0, 213, 0, 214, 215, 216, 0, + 217, 218, 219, 220, 221, 222, 223, 0, 225, 226, + 227, 228, 0, 229, 230, 231, 232, 233, 234, 0, + 235, 0, 237, 238, 239, 240, 241, 242, 243, 244, + 0, 245, 0, 246, 0, 0, 249, 0, 251, 252, + 253, 254, 255, 0, 0, 256, 0, 258, 0, 0, + 260, 261, 262, 0, 0, 263, 264, 265, 266, 267, + 500, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 0, 289, 290, 291, 292, 293, 0, 294, 295, 0, + 297, 0, 298, 299, 300, 301, 302, 303, 0, 304, + 305, 0, 0, 306, 307, 308, 0, 0, 309, 310, + 0, 312, 0, 314, 315, 316, 317, 318, 319, 320, + 321, 322, 323, 324, 0, 325, 326, 327, 328, 329, + 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, + 339, 0, 340, 341, 342, 343, 344, 345, 346, 347, + 0, 348, 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 0, 361, 362, 0, 364, 365, + 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 0, 379, 380, 381, 382, 383, 0, + 384, 385, 386, 387, 388, 0, 390, 391, 392, 393, + 0, 394, 395, 396, 397, 398, 399, 400, 401, 402, + 403, 404, 502, 406, 407, 408, 0, 409, 410, 0, + 411, 0, 413, 414, 415, 416, 417, 0, 418, 419, + 0, 0, 420, 421, 422, 423, 424, 0, 425, 426, + 427, 428, 429, 430, 431, 432, 0, 0, 433, 434, + 435, 436, 437, 0, 0, 438, 439, 440, 441, 442, + 443, 444, 0, 445, 0, 447, 448, 449, 450, 0, + 0, 451, 0, 0, 452, 453, 454, 455, 456, 457, + 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 0, 498, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2539, 93, 94, 95, 96, 97, 98, 99, 100, + 0, 101, 102, 103, 0, 0, 0, 0, 0, 0, + 0, 104, 105, 0, 106, 107, 108, 0, 110, 111, + 112, 113, 114, 0, 116, 117, 0, 118, 119, 120, + 121, 122, 123, 0, 0, 124, 125, 126, 127, 128, + 0, 129, 130, 131, 132, 133, 0, 0, 0, 135, + 136, 137, 138, 139, 140, 0, 142, 143, 144, 0, + 145, 146, 147, 148, 149, 150, 0, 0, 152, 153, + 154, 0, 0, 0, 0, 0, 0, 0, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 0, 166, + 0, 167, 168, 169, 170, 171, 172, 0, 173, 174, + 175, 176, 177, 0, 0, 178, 179, 180, 181, 182, + 0, 183, 184, 185, 0, 186, 187, 188, 0, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 198, 0, + 199, 0, 200, 201, 202, 203, 0, 204, 0, 205, + 0, 0, 0, 208, 209, 210, 0, 212, 0, 213, + 0, 214, 215, 216, 0, 217, 218, 219, 220, 221, + 222, 223, 0, 225, 226, 227, 228, 0, 229, 230, + 231, 232, 233, 234, 0, 235, 0, 237, 238, 239, + 240, 241, 242, 243, 244, 0, 245, 0, 246, 0, + 0, 249, 0, 251, 252, 253, 254, 255, 0, 0, + 256, 0, 258, 0, 0, 260, 261, 262, 0, 0, + 263, 264, 265, 266, 267, 500, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, - 283, 284, -600, 286, 287, 288, 289, 290, 0, 291, - 292, 0, 294, 0, 295, 296, 297, 298, 299, 300, - 0, 301, 302, 0, 0, 303, 304, 305, 0, 0, - 306, 307, 0, 309, 0, 311, 312, 313, 314, 315, - 316, 317, 318, 319, 320, 321, 0, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 0, 331, 332, 333, - 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, - 344, 0, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 0, 357, 358, -600, 360, 361, - 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, - 372, 373, 374, 0, 375, 376, 377, 378, 379, 0, - 380, 381, 382, 383, 384, 0, 386, 387, 388, 389, - 0, 390, 391, 392, 393, 394, 395, 396, 397, 398, - 399, 400, 498, 402, 403, 404, 0, 405, 406, 0, - 407, -600, 409, 410, 411, 412, 413, 0, 414, 415, - 0, 0, 416, 417, 418, 419, 420, 0, 421, 422, - 423, 424, 425, 426, 427, 428, 0, 0, 429, 430, - 431, 432, 433, 0, 0, 434, 435, 436, 437, 438, - 439, 440, 0, 441, 0, 443, 444, 445, 446, 0, - 0, 447, 0, 0, 448, 449, 450, 451, 452, 453, - 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 0, 0, 91, 0, 572, + 283, 284, 285, 286, 287, 0, 289, 290, 291, 292, + 293, 0, 294, 295, 0, 297, 0, 298, 299, 300, + 301, 302, 303, 0, 304, 305, 0, 0, 306, 307, + 308, 0, 0, 309, 310, 0, 312, 0, 314, 315, + 316, 317, 318, 319, 320, 321, 322, 323, 324, 0, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 0, + 334, 335, 336, 337, 338, 339, 0, 340, 341, 342, + 343, 344, 345, 346, 347, 0, 348, 349, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 0, + 361, 362, 0, 364, 365, 366, 367, 368, 369, 370, + 371, 372, 373, 374, 375, 376, 377, 378, 0, 379, + 380, 381, 382, 383, 0, 384, 385, 386, 387, 388, + 0, 390, 391, 392, 393, 0, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, 404, 502, 406, 407, + 408, 0, 409, 410, 0, 411, 0, 413, 414, 415, + 416, 417, 0, 418, 419, 0, 0, 420, 421, 422, + 423, 424, 0, 425, 426, 427, 428, 429, 430, 431, + 432, 0, 0, 433, 434, 435, 436, 437, 0, 0, + 438, 439, 440, 441, 442, 443, 444, 0, 445, 0, + 447, 448, 449, 450, 0, 0, 451, 0, 0, 452, + 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, + 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, + 0, 498, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1655, 93, 94, 95, + 96, 97, 98, 99, 100, 0, 101, 102, 103, 0, + 0, 0, 0, 0, 0, 0, 104, 105, 0, 106, + 107, 108, 0, 110, 111, 112, 113, 114, 0, 116, + 117, 0, 118, 119, 120, 121, 122, 123, 0, 0, + 124, 125, 126, 127, 128, 0, 129, 130, 131, 132, + 133, 0, 0, 0, 135, 136, 137, 138, 139, 140, + 0, 142, 143, 144, 0, 145, 146, 147, 148, 149, + 150, 0, 0, 152, 153, 154, 0, 0, 0, 0, + 0, 0, 0, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 0, 166, 0, 167, 168, 169, 170, + 171, 172, 0, 173, 174, 175, 176, 177, 0, 0, + 178, 179, 180, 181, 182, 0, 183, 184, 185, 0, + 186, 187, 188, 0, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 0, 199, 0, 200, 201, 202, + 203, 0, 204, 0, 205, 0, 0, 0, 208, 209, + 210, 0, 212, 0, 213, 0, 214, 215, 216, 0, + 217, 218, 219, 220, 221, 222, 223, 0, 225, 226, + 227, 228, 0, 229, 230, 231, 232, 233, 234, 0, + 235, 0, 237, 238, 239, 240, 241, 242, 243, 244, + 0, 245, 0, 246, 0, 0, 249, 0, 251, 252, + 253, 254, 255, 0, 0, 256, 0, 258, 0, 0, + 260, 261, 262, 0, 0, 263, 264, 265, 266, 267, + 500, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 0, 289, 290, 291, 292, 293, 0, 294, 295, 0, + 297, 0, 298, 299, 300, 301, 302, 303, 0, 304, + 305, 0, 0, 306, 307, 308, 0, 0, 309, 310, + 0, 312, 0, 314, 315, 316, 317, 318, 319, 320, + 321, 322, 323, 324, 0, 325, 326, 327, 328, 329, + 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, + 339, 0, 340, 341, 342, 343, 344, 345, 346, 347, + 0, 348, 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 0, 361, 362, 0, 364, 365, + 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 0, 379, 380, 381, 382, 383, 0, + 384, 385, 386, 387, 388, 0, 390, 391, 392, 393, + 0, 394, 395, 396, 397, 398, 399, 400, 401, 402, + 403, 404, 502, 406, 407, 408, 0, 409, 410, 0, + 411, 0, 413, 414, 415, 416, 417, 0, 418, 419, + 0, 0, 420, 421, 422, 423, 424, 0, 425, 426, + 427, 428, 429, 430, 431, 432, 0, 0, 433, 434, + 435, 436, 437, 0, 0, 438, 439, 440, 441, 442, + 443, 444, 0, 445, 0, 447, 448, 449, 450, 0, + 0, 451, 0, 0, 452, 453, 454, 455, 456, 457, + 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 0, 498, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 933, 92, 93, 94, 95, 96, 97, 98, - 99, 0, 100, 101, 102, 0, 0, 0, 0, 0, - 0, 0, 103, 104, 0, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 0, 117, 118, - 119, 120, 121, 122, 0, 817, 123, 124, 125, 126, - 127, 0, 128, 129, 130, 131, 820, 0, 821, 0, - 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, - 0, 144, 145, 146, 147, 148, 149, 0, 150, 151, - 152, 153, 822, 823, 824, 825, 826, 827, 828, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 164, 0, - 165, 0, 166, 167, 168, 169, 170, 171, 0, 172, - 173, 174, 175, 176, 0, 0, 177, 178, 179, 180, - 181, 0, 182, 183, 184, 0, 185, 186, 187, 0, - 188, 189, 190, 191, 192, 193, 194, 195, 196, 833, - 0, 198, 0, 199, 200, 201, 202, 0, 203, 0, - 204, 205, 0, 206, 207, 208, 209, 210, 211, 0, - 212, 0, 213, 214, 215, 0, 216, 217, 218, 219, - 220, 221, 222, 223, 224, 225, 226, 0, 227, 228, - 229, 230, 231, 232, 0, 233, 234, 235, 236, 237, - 238, 239, 240, 241, 0, 242, 0, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 2040, 0, 253, - 254, 255, 256, 0, 257, 258, 259, 841, 842, 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, - 0, 291, 292, 293, 294, 0, 847, 296, 297, 298, - 299, 300, 0, 301, 302, 0, 573, 303, 304, 305, - 0, 0, 306, 307, 308, 309, 310, 850, 312, 313, - 314, 315, 316, 317, 318, 319, 320, 321, 0, 322, - 323, 851, 325, 326, 327, 328, 329, 330, 0, 331, - 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, - 342, 343, 344, 0, 345, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 0, 357, 358, 359, - 360, 361, 362, 363, 2041, 365, 366, 367, 368, 369, - 370, 371, 372, 373, 374, 25, 375, 376, 377, 378, - 379, 854, 380, 381, 382, 383, 384, 385, 386, 387, - 388, 389, 0, 390, 391, 392, 393, 394, 395, 396, - 397, 398, 399, 400, 401, 402, 856, 404, 0, 405, - 406, 30, 407, 408, 409, 410, 411, 412, 413, 0, - 414, 415, 0, 0, 416, 417, 859, 419, 860, 0, - 421, 422, 862, 424, 425, 426, 427, 428, 0, 0, - 429, 430, 431, 432, 433, 863, 0, 434, 435, 436, - 437, 438, 568, 440, 0, 441, 442, 443, 444, 445, - 446, 0, 0, 447, 0, 33, 448, 449, 450, 451, - 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 466, 467, 468, 0, 91, 34, - 572, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2042, 92, 93, 94, 95, 96, 97, - 98, 99, 0, 100, 101, 102, 0, 0, 0, 0, - 0, 0, 0, 103, 104, 0, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, 0, 117, - 118, 119, 120, 121, 122, 0, 817, 123, 124, 125, - 126, 127, 0, 128, 129, 130, 131, 820, 0, 821, - 0, 134, 135, 136, 137, 138, 139, 140, 141, 142, - 143, 0, 144, 145, 146, 147, 148, 149, 0, 150, - 151, 152, 153, 822, 823, 824, 825, 826, 827, 828, - 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, - 0, 165, 0, 166, 167, 168, 169, 170, 171, 0, - 172, 173, 174, 175, 176, 0, 0, 177, 178, 179, - 180, 181, 0, 182, 183, 184, 0, 185, 186, 187, - 0, 188, 189, 190, 191, 192, 193, 194, 195, 196, - 833, 0, 198, 0, 199, 200, 201, 202, 0, 203, - 0, 204, 205, 0, 206, 207, 208, 209, 210, 211, - 0, 212, 0, 213, 214, 215, 0, 216, 217, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 0, 227, - 228, 229, 230, 231, 232, 0, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 0, 242, 0, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 2040, 0, - 253, 254, 255, 256, 0, 257, 258, 259, 841, 842, - 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, + 0, 1760, 93, 94, 95, 96, 97, 98, 99, 100, + 0, 101, 102, 103, 0, 0, 0, 0, 0, 0, + 0, 104, 105, 0, 106, 107, 108, 0, 110, 111, + 112, 113, 114, 0, 116, 117, 0, 118, 119, 120, + 121, 122, 123, 0, 0, 124, 125, 126, 127, 128, + 0, 129, 130, 131, 132, 133, 0, 0, 0, 135, + 136, 137, 138, 139, 140, 0, 142, 143, 144, 0, + 145, 146, 147, 148, 149, 150, 0, 0, 152, 153, + 154, 0, 0, 0, 0, 0, 0, 0, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 0, 166, + 0, 167, 168, 169, 170, 171, 172, 0, 173, 174, + 175, 176, 177, 0, 0, 178, 179, 180, 181, 182, + 0, 183, 184, 185, 0, 186, 187, 188, 0, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 198, 0, + 199, 0, 200, 201, 202, 203, 0, 204, 0, 205, + 0, 0, 0, 208, 209, 210, 0, 212, 0, 213, + 0, 214, 215, 216, 0, 217, 218, 219, 220, 221, + 222, 223, 0, 225, 226, 227, 228, 0, 229, 230, + 231, 232, 233, 234, 0, 235, 0, 237, 238, 239, + 240, 241, 242, 243, 244, 0, 245, 0, 246, 0, + 0, 249, 0, 251, 252, 253, 254, 255, 0, 0, + 256, 0, 258, 0, 0, 260, 261, 262, 0, 0, + 263, 264, 265, 266, 267, 500, 269, 270, 271, 272, + 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, 0, 289, 290, 291, 292, + 293, 0, 294, 295, 0, 297, 0, 298, 299, 300, + 301, 302, 303, 0, 304, 305, 0, 0, 306, 307, + 308, 0, 0, 309, 310, 0, 312, 0, 314, 315, + 316, 317, 318, 319, 320, 321, 322, 323, 324, 0, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 0, + 334, 335, 336, 337, 338, 339, 0, 340, 341, 342, + 343, 344, 345, 346, 347, 0, 348, 349, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 0, + 361, 362, 0, 364, 365, 366, 367, 368, 369, 370, + 371, 372, 373, 374, 375, 376, 377, 378, 0, 379, + 380, 381, 382, 383, 0, 384, 385, 386, 387, 388, + 0, 390, 391, 392, 393, 0, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, 404, 502, 406, 407, + 408, 0, 409, 410, 0, 411, 0, 413, 414, 415, + 416, 417, 0, 418, 419, 0, 0, 420, 421, 422, + 423, 424, 0, 425, 426, 427, 428, 429, 430, 431, + 432, 0, 0, 433, 434, 435, 436, 437, 0, 0, + 438, 439, 440, 441, 442, 443, 444, 0, 445, 0, + 447, 448, 449, 450, 0, 0, 451, 0, 0, 452, + 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, + 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, + 0, 0, 0, 0, 2397, 1232, 547, 0, 0, 1615, + 818, 0, 0, 0, 0, 0, 2295, 1616, 1617, 1618, + 93, 94, 95, 96, 97, 98, 99, 100, 1052, 101, + 102, 103, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 104, + 105, 1060, 106, 107, 108, 2398, 110, 111, 112, 0, + 663, 2399, 665, 666, 1061, 118, 119, 120, 121, 122, + 123, 1062, 1063, 124, 125, 667, 668, 128, 1064, 129, + 130, 131, 132, 0, 1065, 2400, 1066, 135, 136, 137, + 138, 139, 140, 2401, 142, 143, 144, 1067, 145, 146, + 147, 148, 149, 150, 1068, 2402, 152, 153, 154, 1069, + 1070, 1071, 2403, 1072, 1073, 1074, 156, 157, 158, 159, + 160, 161, 162, 673, 674, 165, 1075, 166, 1076, 167, + 168, 169, 170, 171, 172, 1077, 173, 174, 175, 176, + 177, 1078, 1079, 178, 179, 675, 181, 182, 1080, 183, + 184, 185, 1081, 186, 187, 188, 1082, 189, 190, 191, + 192, 0, 194, 195, 196, 197, 0, 1083, 199, 1084, + 200, 201, 676, 203, 1085, 204, 1086, 205, 2404, 1087, + 2405, 208, 209, 210, 2406, 212, 1088, 213, 1089, 0, + 0, 216, 1090, 217, 218, 219, 220, 221, 222, 223, + 2407, 225, 226, 227, 228, 1091, 229, 230, 231, 232, + 233, 234, 1092, 235, 2408, 0, 238, 239, 240, 241, + 242, 683, 684, 1093, 685, 1094, 246, 2409, 2410, 249, + 2411, 251, 252, 253, 254, 255, 1095, 1096, 256, 2412, + 258, 2413, 1097, 260, 261, 262, 1098, 1099, 263, 264, + 265, 266, 267, 2414, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 692, 2415, 694, 290, 291, 292, 2416, 1100, + 294, 295, 2417, 297, 1101, 0, 299, 696, 301, 302, + 303, 1102, 304, 305, 1103, 1104, 2418, 307, 308, 1105, + 1106, 309, 0, 2419, 312, 2420, 0, 315, 316, 317, + 318, 319, 320, 321, 322, 323, 324, 1107, 325, 326, + 0, 328, 329, 0, 331, 332, 333, 1108, 334, 335, + 336, 337, 338, 339, 1109, 340, 341, 342, 699, 344, + 345, 346, 347, 1110, 348, 349, 350, 351, 352, 353, + 354, 355, 356, 357, 358, 359, 360, 1111, 361, 362, + 2421, 364, 365, 366, 701, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, 378, 1112, 379, 380, 381, + 382, 383, 1113, 384, 2422, 386, 387, 388, 2423, 390, + 391, 704, 393, 1114, 394, 395, 396, 397, 398, 399, + 400, 401, 402, 403, 404, 2424, 406, 0, 408, 1115, + 409, 410, 1116, 411, 2425, 413, 414, 415, 416, 417, + 1117, 707, 708, 1118, 1119, 420, 421, 0, 423, 0, + 1120, 425, 426, 2426, 428, 429, 430, 431, 432, 1121, + 1122, 433, 434, 435, 436, 437, 1123, 1124, 438, 439, + 440, 441, 442, 0, 710, 1126, 445, 2427, 447, 448, + 449, 450, 1127, 1128, 451, 1129, 1130, 452, 453, 454, + 455, 456, 457, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 469, 470, 471, 472, 0, 498, + 0, 1619, 1620, 1621, 1615, 2428, 2429, 1624, 1625, 1626, + 1627, 0, 1616, 1617, 1618, 93, 94, 95, 96, 97, + 98, 99, 100, 0, 101, 102, 103, 0, 0, 0, + 0, 0, 0, 0, 104, 105, 0, 106, 107, 108, + 0, 110, 111, 112, 113, 114, 0, 116, 117, 0, + 118, 119, 120, 121, 122, 123, 0, 0, 124, 125, + 126, 127, 128, 0, 129, 130, 131, 132, 133, 0, + 0, 0, 135, 136, 137, 138, 139, 140, 0, 142, + 143, 144, 0, 145, 146, 147, 148, 149, 150, 0, + 0, 152, 153, 154, 0, 0, 0, 0, 0, 0, + 0, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 0, 166, 0, 167, 168, 169, 170, 171, 172, + 0, 173, 174, 175, 176, 177, 0, 0, 178, 179, + 180, 181, 182, 0, 183, 184, 185, 0, 186, 187, + 188, 0, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 0, 199, 0, 200, 201, 202, 203, 0, + 204, 0, 205, 0, 0, 0, 208, 209, 210, 0, + 212, 0, 213, 0, 214, 215, 216, 0, 217, 218, + 219, 220, 221, 222, 223, 0, 225, 226, 227, 228, + 0, 229, 230, 231, 232, 233, 234, 0, 235, 0, + 237, 238, 239, 240, 241, 242, 243, 244, 0, 245, + 0, 246, 0, 0, 249, 0, 251, 252, 253, 254, + 255, 0, 0, 256, 0, 258, 0, 0, 260, 261, + 262, 0, 0, 263, 264, 265, 266, 267, 500, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 0, 291, 292, 293, 294, 0, 847, 296, 297, - 298, 299, 300, 0, 301, 302, 0, 573, 303, 304, - 305, 0, 0, 306, 307, 308, 309, 310, 850, 312, - 313, 314, 315, 316, 317, 318, 319, 320, 321, 0, - 322, 323, 851, 325, 326, 327, 328, 329, 330, 0, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 0, 345, 346, 347, 348, 349, - 350, 351, 352, 353, 354, 355, 356, 0, 357, 358, - 359, 360, 361, 362, 363, 2041, 365, 366, 367, 368, - 369, 370, 371, 372, 373, 374, 0, 375, 376, 377, - 378, 379, 854, 380, 381, 382, 383, 384, 385, 386, - 387, 388, 389, 0, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 856, 404, 0, - 405, 406, 0, 407, 408, 409, 410, 411, 412, 413, - 0, 414, 415, 0, 0, 416, 417, 859, 419, 860, - 0, 421, 422, 862, 424, 425, 426, 427, 428, 0, - 0, 429, 430, 431, 432, 433, 863, 0, 434, 435, - 436, 437, 438, 439, 440, 0, 441, 442, 443, 444, - 445, 446, 0, 0, 447, 0, 0, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 0, 91, + 280, 281, 282, 283, 284, 285, 286, 287, 0, 289, + 290, 291, 292, 293, 0, 294, 295, 0, 297, 0, + 298, 299, 300, 301, 302, 303, 0, 304, 305, 0, + 0, 306, 307, 308, 0, 0, 309, 310, 0, 312, + 0, 314, 315, 316, 317, 318, 319, 320, 321, 322, + 323, 324, 0, 325, 326, 327, 328, 329, 330, 331, + 332, 333, 0, 334, 335, 336, 337, 338, 339, 0, + 340, 341, 342, 343, 344, 345, 346, 347, 0, 348, + 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, + 359, 360, 0, 361, 362, 0, 364, 365, 366, 367, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 0, 379, 380, 381, 382, 383, 0, 384, 385, + 386, 387, 388, 0, 390, 391, 392, 393, 0, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 502, 406, 407, 408, 0, 409, 410, 0, 411, 0, + 413, 414, 415, 416, 417, 0, 418, 419, 0, 0, + 420, 421, 422, 423, 424, 0, 425, 426, 427, 428, + 429, 430, 431, 432, 0, 0, 433, 434, 435, 436, + 437, 0, 0, 438, 439, 440, 441, 442, 443, 444, + 0, 445, 0, 447, 448, 449, 450, 0, 0, 451, + 0, 0, 452, 453, 454, 455, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 0, 0, 0, 1619, 1620, 1621, 0, + 1622, 1623, 1624, 1625, 1626, 1627, 1308, 0, 0, 1309, + 0, 0, 0, 0, 1310, 1311, 1312, 0, 0, 0, + 0, 0, 0, 0, 1308, 0, 0, 1309, 0, 0, + 0, 1313, 1310, 1311, 1312, 0, 0, 0, 0, 1315, + 0, 0, 0, 0, 0, 0, 1316, 0, 0, 1313, + 0, 0, 0, 1308, 0, 0, 1309, 1315, 0, 0, + 0, 1310, 1311, 1312, 1316, 0, 0, 0, 0, 0, + 0, 1317, 1308, 0, 0, 1309, 0, 0, 1313, 0, + 1310, 1311, 1312, 0, 0, 0, 1315, 0, 0, 1317, + 0, 0, 0, 1316, 0, 0, 0, 1313, 0, 0, + 0, 0, 0, 0, 0, 1315, 0, 0, 0, 0, + 0, 0, 1316, 0, 0, 0, 0, 0, 1317, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2042, 92, 93, 94, 95, 96, - 97, 98, 99, 0, 100, 101, 102, 0, 0, 0, - 0, 0, 0, 0, 103, 104, 0, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, 0, - 117, 118, 119, 120, 121, 122, 0, 817, 123, 124, - 125, 126, 127, 0, 128, 129, 130, 131, 820, 0, - 821, 0, 134, 135, 136, 137, 138, 139, 140, 141, - 142, 143, 0, 144, 145, 146, 147, 148, 149, 0, - 150, 151, 152, 153, 822, 823, 824, 825, 826, 827, - 828, 155, 156, 157, 158, 159, 160, 161, 162, 163, - 164, 0, 165, 0, 166, 167, 168, 169, 170, 171, - 0, 172, 173, 174, 175, 176, 0, 0, 177, 178, - 179, 180, 181, 0, 182, 183, 184, 0, 185, 186, - 187, 0, 188, 189, 190, 191, 192, 193, 194, 195, - 196, 833, 0, 198, 0, 199, 200, 201, 202, 0, - 203, 0, 204, 205, 0, 206, 207, 208, 209, 210, - 211, 0, 212, 0, 213, 214, 215, 0, 216, 217, - 218, 219, 220, 221, 222, 223, 224, 225, 226, 0, - 227, 228, 229, 230, 231, 232, 0, 233, 234, 235, - 236, 237, 238, 239, 240, 241, 0, 242, 0, 243, - 244, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 0, 253, 254, 255, 256, 0, 257, 258, 259, 841, - 842, 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, 0, 291, 292, 293, 294, 0, 847, 296, - 297, 298, 299, 300, 0, 301, 302, 0, 0, 303, - 304, 305, 0, 0, 306, 307, 308, 309, 310, 850, - 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, - 0, 322, 323, 851, 325, 326, 327, 328, 329, 330, - 0, 331, 332, 333, 334, 335, 336, 337, 338, 339, - 340, 341, 342, 343, 344, 0, 345, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, 356, 0, 357, - 358, 359, 360, 361, 362, 363, 2041, 365, 366, 367, - 368, 369, 370, 371, 372, 373, 374, 0, 375, 376, - 377, 378, 379, 854, 380, 381, 382, 383, 384, 385, - 386, 387, 388, 389, 0, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 401, 402, 856, 404, - 0, 405, 406, 0, 407, 408, 409, 410, 411, 412, - 413, 0, 414, 415, 0, 0, 416, 417, 859, 419, - 860, 0, 421, 422, 862, 424, 425, 426, 427, 428, - 0, 0, 429, 430, 431, 432, 433, 863, 0, 434, - 435, 436, 437, 438, 439, 440, 0, 441, 442, 443, - 444, 445, 446, 0, 0, 447, 0, 0, 448, 449, - 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 0, - 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 35, 92, 93, 94, 95, - 96, 97, 98, 99, 0, 100, 101, 102, 0, 0, - 0, 0, 0, 0, 0, 103, 104, 0, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 0, 117, 118, 119, 120, 121, 122, 0, 817, 123, - 124, 125, 126, 127, 0, 128, 129, 130, 131, 820, - 0, 821, 0, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 0, 144, 145, 146, 147, 148, 149, - 0, 150, 151, 152, 153, 822, 823, 824, 825, 826, - 827, 828, 155, 156, 157, 158, 159, 160, 161, 162, - 163, 164, 0, 165, 0, 166, 167, 168, 169, 170, - 171, 0, 172, 173, 174, 175, 176, 0, 0, 177, - 178, 179, 180, 181, 0, 182, 183, 184, 0, 185, - 186, 187, 0, 188, 189, 190, 191, 192, 193, 194, - 195, 196, 833, 0, 198, 0, 199, 200, 201, 202, - 0, 203, 0, 204, 205, 0, 206, 207, 208, 209, - 210, 211, 0, 212, 0, 213, 214, 215, 0, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 0, 227, 228, 229, 230, 231, 232, 0, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 0, 242, 0, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 0, 0, 253, 254, 255, 256, 0, 257, 258, 259, - 841, 842, 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, 0, 291, 292, 293, 294, 0, 847, - 296, 297, 298, 299, 300, 0, 301, 302, 0, 0, - 303, 304, 305, 0, 0, 306, 307, 308, 309, 310, - 850, 312, 313, 314, 315, 316, 317, 318, 319, 320, - 321, 0, 322, 323, 851, 325, 326, 327, 328, 329, - 330, 0, 331, 332, 333, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 0, 345, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, 356, 0, - 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, - 367, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 376, 377, 378, 379, 854, 380, 381, 382, 383, 384, - 385, 386, 387, 388, 389, 0, 390, 391, 392, 393, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 856, - 404, 0, 405, 406, 0, 407, 408, 409, 410, 411, - 412, 413, 0, 414, 415, 0, 0, 416, 417, 859, - 419, 860, 0, 421, 422, 862, 424, 425, 426, 427, - 428, 0, 0, 429, 430, 431, 432, 433, 863, 0, - 434, 435, 436, 437, 438, 439, 440, 0, 441, 442, - 443, 444, 445, 446, 0, 0, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, - 0, 735, 1223, 542, 0, 0, 0, 810, 0, 0, - 0, 0, 0, 0, 0, 0, 2671, 92, 93, 94, - 95, 96, 97, 98, 99, 0, 100, 101, 102, 0, - 0, 0, 0, 0, 0, 0, 103, 104, 0, 105, - 106, 107, 0, 109, 110, 111, 736, 737, 0, 738, - 739, 0, 117, 118, 119, 120, 121, 122, 0, 0, - 123, 124, 740, 741, 127, 0, 128, 129, 130, 131, - 742, 0, 0, 0, 134, 135, 136, 137, 138, 139, - 0, 141, 142, 143, 0, 144, 145, 146, 147, 148, - 149, 0, 0, 151, 152, 153, 0, 0, 0, 0, - 0, 0, 0, 155, 156, 157, 158, 159, 160, 161, - 743, 744, 164, 0, 165, 0, 166, 167, 168, 169, - 170, 171, 0, 172, 173, 174, 175, 176, 0, 0, - 177, 178, 179, 180, 181, 0, 182, 183, 184, 0, - 185, 186, 187, 0, 188, 189, 190, 191, 745, 193, - 194, 195, 196, 746, 1224, 198, 0, 199, 200, 747, - 202, 0, 203, 0, 204, 0, 0, 0, 207, 208, - 209, 0, 211, 0, 212, 0, 748, 749, 215, 0, - 216, 217, 218, 219, 220, 221, 0, 223, 224, 225, - 226, 0, 227, 228, 229, 230, 231, 232, 0, 233, - 0, 750, 236, 237, 238, 239, 751, 752, 0, 753, - 0, 243, 0, 0, 246, 0, 248, 249, 250, 251, - 252, 0, 0, 253, 0, 255, 0, 0, 257, 258, - 259, 0, 0, 260, 261, 262, 263, 264, 754, 266, - 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 755, 0, 756, - 287, 288, 289, 757, 0, 291, 292, 0, 294, 0, - 758, 296, 759, 298, 299, 300, 0, 301, 302, 1225, - 0, 303, 304, 305, 0, 0, 306, 760, 0, 309, - 0, 761, 312, 313, 314, 315, 316, 317, 318, 319, - 320, 321, 0, 322, 323, 762, 325, 326, 763, 328, - 329, 330, 0, 331, 332, 333, 334, 335, 336, 337, - 338, 339, 764, 341, 342, 343, 344, 0, 345, 346, - 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 0, 360, 361, 362, 765, 364, 365, - 366, 367, 368, 369, 370, 371, 372, 373, 374, 0, - 375, 376, 377, 378, 379, 0, 380, 766, 382, 383, - 384, 0, 386, 387, 767, 389, 0, 390, 391, 392, - 393, 394, 395, 396, 397, 398, 399, 400, 768, 402, - 769, 404, 0, 405, 406, 0, 407, 0, 409, 410, - 411, 412, 413, 0, 770, 771, 0, 0, 416, 417, - 772, 419, 773, 1226, 421, 422, 774, 424, 425, 426, - 427, 428, 0, 0, 429, 430, 431, 432, 433, 0, - 0, 434, 435, 436, 437, 438, 1116, 776, 0, 441, - 0, 443, 444, 445, 446, 0, 0, 447, 0, 0, - 448, 449, 450, 451, 452, 453, 777, 778, 779, 780, - 781, 782, 783, 784, 785, 786, 787, 465, 466, 467, - 468, 0, 735, 0, 0, 0, 0, 0, 1227, 1228, - 1920, 0, 0, 0, 0, 0, 0, 1921, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 3, 4, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 736, 737, 0, - 738, 739, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 740, 741, 127, 0, 128, 129, 130, - 131, 742, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 743, 744, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 745, - 193, 194, 195, 196, 746, 0, 198, 0, 199, 200, - 747, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 748, 749, 215, - 0, 216, 217, 218, 219, 220, 221, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 750, 236, 237, 238, 239, 751, 752, 0, - 753, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 754, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 755, 0, - 756, 287, 288, 289, 757, 0, 291, 292, 0, 294, - 0, 758, 296, 759, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 760, 0, - 309, 0, 761, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 762, 325, 326, 763, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 764, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 765, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 25, 375, 376, 377, 378, 379, 0, 380, 766, 382, - 383, 384, 0, 386, 387, 767, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 768, - 402, 769, 404, 0, 405, 406, 30, 407, 0, 409, - 410, 411, 412, 413, 0, 770, 771, 0, 0, 416, - 417, 772, 419, 773, 0, 421, 422, 774, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 775, 776, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 33, 448, 449, 450, 451, 452, 453, 777, 778, 779, - 780, 781, 782, 783, 784, 785, 786, 787, 465, 466, - 467, 468, 0, 494, 34, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 35, 92, - 93, 94, 95, 96, 97, 98, 99, 606, 100, 101, - 102, 0, 0, 0, 0, 0, 0, 0, 103, 104, - 0, 105, 106, 107, 0, 109, 110, 111, 112, 113, - 0, 115, 116, 0, 117, 118, 119, 120, 121, 122, - 0, 0, 123, 124, 125, 126, 127, 0, 128, 129, - 130, 131, 132, 0, 0, 0, 134, 135, 136, 137, - 138, 139, 0, 141, 142, 143, 0, 144, 145, 146, - 147, 148, 149, 0, 0, 151, 152, 153, 0, 0, - 0, 0, 0, 0, 0, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 0, 165, 0, 166, 167, - 168, 169, 170, 171, 0, 172, 173, 174, 175, 176, - 0, 0, 177, 178, 179, 180, 181, 0, 182, 183, - 184, 0, 185, 186, 187, 0, 188, 189, 190, 191, - 192, 193, 194, 195, 196, 197, 0, 198, 0, 199, - 200, 201, 202, 0, 203, 0, 204, 0, 0, 0, - 207, 208, 209, 0, 211, 0, 212, 0, 213, 214, - 215, 0, 216, 217, 218, 219, 220, 221, 0, 223, - 224, 225, 226, 0, 227, 228, 229, 230, 231, 232, - 0, 233, 0, 235, 236, 237, 238, 239, 240, 241, - 0, 242, 0, 243, 0, 0, 246, 0, 248, 249, - 250, 251, 252, 0, 0, 253, 0, 255, 0, 0, - 257, 258, 259, 0, 0, 260, 261, 262, 263, 264, - 496, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 0, 286, 287, 288, 289, 290, 0, 291, 292, 0, - 294, 0, 295, 296, 297, 298, 299, 300, 0, 301, - 302, 0, 0, 303, 304, 305, 0, 0, 306, 307, - 0, 309, 0, 311, 312, 313, 314, 315, 316, 317, - 318, 319, 320, 321, 0, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 0, 331, 332, 333, 334, 335, - 336, 337, 338, 339, 340, 341, 342, 343, 344, 0, - 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, 0, 357, 358, 0, 360, 361, 362, 363, - 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, - 374, 25, 375, 376, 377, 378, 379, 0, 380, 381, - 382, 383, 384, 0, 386, 387, 388, 389, 0, 390, - 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, - 498, 402, 403, 404, 0, 405, 406, 30, 407, 0, - 409, 410, 411, 412, 413, 0, 607, 415, 0, 0, - 608, 417, 418, 419, 420, 0, 421, 422, 423, 424, - 425, 426, 427, 428, 0, 0, 429, 430, 431, 432, - 433, 0, 0, 434, 435, 436, 437, 438, 568, 440, - 0, 441, 0, 443, 444, 445, 446, 0, 0, 447, - 0, 33, 448, 449, 450, 451, 452, 453, 454, 455, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 0, 494, 34, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, - 92, 93, 94, 95, 96, 97, 98, 99, 0, 100, - 101, 102, 0, 0, 0, 0, 0, 0, 0, 103, - 104, 0, 105, 106, 107, 0, 109, 110, 111, 112, - 113, 0, 115, 116, 0, 117, 118, 119, 120, 121, - 122, 0, 0, 123, 124, 125, 126, 127, 0, 128, - 129, 130, 131, 132, 0, 0, 0, 134, 135, 136, - 137, 138, 139, 0, 141, 142, 143, 0, 144, 145, - 146, 147, 148, 149, 0, 0, 151, 152, 153, 0, - 0, 0, 0, 0, 0, 0, 155, 156, 157, 158, - 159, 160, 161, 162, 163, 164, 0, 165, 0, 166, - 167, 168, 169, 170, 171, 0, 172, 173, 174, 175, - 176, 0, 0, 177, 178, 179, 180, 181, 0, 182, - 183, 184, 0, 185, 186, 187, 0, 188, 189, 190, - 191, 192, 193, 194, 195, 196, 197, 0, 198, 0, - 199, 200, 201, 202, 0, 203, 0, 204, 0, 0, - 0, 207, 208, 209, 0, 211, 0, 212, 0, 213, - 214, 215, 0, 216, 217, 218, 219, 220, 221, 0, - 223, 224, 225, 226, 0, 227, 228, 229, 230, 231, - 232, 0, 233, 0, 235, 236, 237, 238, 239, 240, - 241, 0, 242, 0, 243, 0, 0, 246, 0, 248, - 249, 250, 251, 252, 0, 0, 253, 0, 255, 0, - 0, 257, 258, 259, 0, 0, 260, 261, 262, 263, - 264, 496, 266, 267, 268, 269, 270, 271, 272, 273, - 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 0, 286, 287, 288, 289, 290, 0, 291, 292, - 0, 294, 0, 295, 296, 297, 298, 299, 300, 0, - 301, 302, 0, 0, 303, 304, 305, 0, 0, 306, - 307, 0, 309, 0, 311, 312, 313, 314, 315, 316, - 317, 318, 319, 320, 321, 0, 322, 323, 324, 325, - 326, 327, 328, 329, 330, 0, 331, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 0, 345, 346, 347, 348, 349, 350, 351, 352, 353, - 354, 355, 356, 0, 357, 358, 0, 360, 361, 362, - 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, - 373, 374, 25, 375, 376, 377, 378, 379, 0, 380, - 381, 382, 383, 384, 0, 386, 387, 388, 389, 0, - 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, - 400, 498, 402, 403, 404, 0, 405, 406, 30, 407, - 0, 409, 410, 411, 412, 413, 0, 414, 415, 0, - 0, 416, 417, 418, 419, 420, 0, 421, 422, 423, - 424, 425, 426, 427, 428, 0, 0, 429, 430, 431, - 432, 433, 0, 0, 434, 435, 436, 437, 438, 568, - 440, 0, 441, 0, 443, 444, 445, 446, 0, 0, - 447, 0, 33, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, - 465, 466, 467, 468, 0, 494, 34, 572, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1317, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 35, 92, 93, 94, 95, 96, 97, 98, 99, 0, - 100, 101, 102, 0, 0, 0, 0, 0, 0, 0, - 103, 104, 0, 105, 106, 107, 0, 109, 110, 111, - 112, 113, 0, 115, 116, 0, 117, 118, 119, 120, - 121, 122, 0, 0, 123, 124, 125, 126, 127, 0, - 128, 129, 130, 131, 132, 0, 0, 0, 134, 135, - 136, 137, 138, 139, 0, 141, 142, 143, 0, 144, - 145, 146, 147, 148, 149, 0, 0, 151, 152, 153, - 0, 0, 0, 0, 0, 0, 0, 155, 156, 157, - 158, 159, 160, 161, 162, 163, 164, 0, 165, 0, - 166, 167, 168, 169, 170, 171, 0, 172, 173, 174, - 175, 176, 0, 0, 177, 178, 179, 180, 181, 0, - 182, 183, 184, 0, 185, 186, 187, 0, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 0, 198, - 0, 199, 200, 201, 202, 0, 203, 0, 204, 0, - 0, 0, 207, 208, 209, 0, 211, 0, 212, 0, - 213, 214, 215, 0, 216, 217, 218, 219, 220, 221, - 0, 223, 224, 225, 226, 0, 227, 228, 229, 230, - 231, 232, 0, 233, 0, 235, 236, 237, 238, 239, - 240, 241, 0, 242, 0, 243, 0, 0, 246, 0, - 248, 249, 250, 251, 252, 0, 0, 253, 0, 255, - 0, 0, 257, 258, 259, 0, 0, 260, 261, 262, - 263, 264, 496, 266, 267, 268, 269, 270, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, - 283, 284, 0, 286, 287, 288, 289, 290, 0, 291, - 292, 0, 294, 0, 295, 296, 297, 298, 299, 300, - 0, 301, 302, 0, 0, 303, 304, 305, 0, 0, - 306, 307, 0, 309, 0, 311, 312, 313, 314, 315, - 316, 317, 318, 319, 320, 321, 0, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 0, 331, 332, 333, - 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, - 344, 0, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 0, 357, 358, 0, 360, 361, - 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, - 372, 373, 374, 0, 375, 376, 377, 378, 379, 0, - 380, 381, 382, 383, 384, 0, 386, 387, 388, 389, - 0, 390, 391, 392, 393, 394, 395, 396, 397, 398, - 399, 400, 498, 402, 403, 404, 0, 405, 406, 0, - 407, 0, 409, 410, 411, 412, 413, 0, 414, 415, - 0, 0, 416, 417, 418, 419, 420, 0, 421, 422, - 423, 424, 425, 426, 427, 428, 0, 0, 429, 430, - 431, 432, 433, 0, 0, 434, 435, 436, 437, 438, - 439, 440, 0, 441, 0, 443, 444, 445, 446, 0, - 0, 447, 0, 0, 448, 449, 450, 451, 452, 453, - 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 0, 494, 0, 572, 0, + 0, 0, 0, 0, 0, 1308, 0, 0, 1309, 0, + 0, 0, 0, 1310, 1311, 1312, 0, 0, 0, 0, + 0, 1318, 0, 1308, 0, 0, 1309, 0, 0, 0, + 1313, 1310, 1311, 1312, 0, 0, 0, 1319, 1315, 1318, + 0, 0, 1320, 0, 0, 1316, 0, 0, 1313, 0, + 0, 0, 0, 0, 0, 1319, 1315, 0, 0, 0, + 1320, 0, 0, 1316, 1321, 1322, 0, 0, 1318, 0, + 1317, 0, 0, 0, 0, 0, 0, 0, 1323, 0, + 0, 0, 1321, 1322, 1319, 0, 0, 1318, 1317, 1320, + 0, 0, 0, 0, 0, 0, 1323, 0, 0, 0, + 0, 0, 0, 1319, 0, 0, 0, 0, 1320, 0, + 0, 1321, 1322, 0, 0, 0, 1324, 0, 0, 1325, + 0, 0, 0, 0, 0, 1323, 0, 0, 0, 0, + 1321, 1322, 0, 1326, 1324, 0, 1327, 1325, 0, 0, + 0, 0, 0, 0, 1323, 0, 0, 0, 0, 0, + 0, 1326, 0, 0, 1327, 0, 0, 0, 0, 0, + 0, 0, 0, 1324, 0, 0, 1325, 0, 0, 0, + 1318, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1326, 0, 1324, 1327, 0, 1325, 1319, 0, 1318, 0, + 0, 1320, 0, 0, 0, 0, 0, 0, 0, 1326, + 0, 0, 1327, 0, 1319, 0, 0, 0, 0, 1320, + 0, 0, 0, 1321, 1322, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1328, 0, 1323, 0, 0, + 0, 1321, 1322, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1328, 0, 1323, 0, 0, 1308, 0, + 0, 1309, 0, 0, 0, 0, 1310, 1311, 1312, 0, + 0, 0, 0, 0, 0, 1324, 0, 0, 1325, 0, + 0, 0, 1328, 1313, 0, 0, 0, 0, 0, 0, + 0, 1315, 1326, 1324, 0, 1327, 1325, 0, 1316, 0, + 0, 1328, 0, 0, 0, 0, 0, 0, 0, 0, + 1326, 0, 0, 1327, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1317, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1329, 0, 0, 1330, 1331, + 1332, 0, 1333, 1334, 1335, 1336, 1337, 1338, 0, 0, + 0, 0, 2361, 1329, 0, 0, 1330, 1331, 1332, 0, + 1333, 1334, 1335, 1336, 1337, 1338, 0, 0, 0, 0, + 2487, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1329, 0, 1328, 1330, 1331, 1332, 0, 1333, + 1334, 1335, 1336, 1337, 1338, 0, 0, 0, 0, 2509, + 0, 1329, 1328, 0, 1330, 1331, 1332, 0, 1333, 1334, + 1335, 1336, 1337, 1338, 0, 0, 0, 0, 2654, 0, + 0, 0, 0, 1318, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1319, + 0, 0, 0, 0, 1320, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 913, 92, 93, 94, 95, 96, 97, 98, 99, - 0, 100, 101, 102, 0, 0, 0, 0, 0, 0, - 0, 103, 104, 0, 105, 106, 107, 0, 109, 110, - 111, 112, 113, 0, 115, 116, 0, 117, 118, 119, - 120, 121, 122, 0, 0, 123, 124, 125, 126, 127, - 0, 128, 129, 130, 131, 132, 0, 0, 0, 134, - 135, 136, 137, 138, 139, 0, 141, 142, 143, 0, - 144, 145, 146, 147, 148, 149, 0, 0, 151, 152, - 153, 0, 0, 0, 0, 0, 0, 0, 155, 156, - 157, 158, 159, 160, 161, 162, 163, 164, 0, 165, - 0, 166, 167, 168, 169, 170, 171, 0, 172, 173, - 174, 175, 176, 0, 0, 177, 178, 179, 180, 181, - 0, 182, 183, 184, 0, 185, 186, 187, 0, 188, - 189, 190, 191, 192, 193, 194, 195, 196, 197, 0, - 198, 0, 199, 200, 201, 202, 0, 203, 0, 204, - 0, 0, 0, 207, 208, 209, 0, 211, 0, 212, - 0, 213, 214, 215, 0, 216, 217, 218, 219, 220, - 221, 0, 223, 224, 225, 226, 0, 227, 228, 229, - 230, 231, 232, 0, 233, 0, 235, 236, 237, 238, - 239, 240, 241, 0, 242, 0, 243, 0, 0, 246, - 0, 248, 249, 250, 251, 252, 0, 0, 253, 0, - 255, 0, 0, 257, 258, 259, 0, 0, 260, 261, - 262, 263, 264, 496, 266, 267, 268, 269, 270, 271, - 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, - 282, 283, 284, 0, 286, 287, 288, 289, 290, 0, - 291, 292, 0, 294, 0, 295, 296, 297, 298, 299, - 300, 0, 301, 302, 0, 0, 303, 304, 305, 0, - 0, 306, 307, 0, 309, 0, 311, 312, 313, 314, - 315, 316, 317, 318, 319, 320, 321, 0, 322, 323, - 324, 325, 326, 327, 328, 329, 330, 0, 331, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 0, 345, 346, 347, 348, 349, 350, 351, - 352, 353, 354, 355, 356, 0, 357, 358, 0, 360, - 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, - 371, 372, 373, 374, 0, 375, 376, 377, 378, 379, - 0, 380, 381, 382, 383, 384, 0, 386, 387, 388, - 389, 0, 390, 391, 392, 393, 394, 395, 396, 397, - 398, 399, 400, 498, 402, 403, 404, 0, 405, 406, - 0, 407, 0, 409, 410, 411, 412, 413, 0, 414, - 415, 0, 0, 416, 417, 418, 419, 420, 0, 421, - 422, 423, 424, 425, 426, 427, 428, 0, 0, 429, - 430, 431, 432, 433, 0, 0, 434, 435, 436, 437, - 438, 439, 440, 0, 441, 0, 443, 444, 445, 446, - 0, 0, 447, 0, 0, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, - 463, 464, 465, 466, 467, 468, 0, 494, 0, 0, + 0, 0, 0, 0, 0, 0, 1321, 1322, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2511, 92, 93, 94, 95, 96, 97, 98, - 99, 0, 100, 101, 102, 0, 0, 0, 0, 0, - 0, 0, 103, 104, 0, 105, 106, 107, 0, 109, - 110, 111, 112, 113, 0, 115, 116, 0, 117, 118, - 119, 120, 121, 122, 0, 0, 123, 124, 125, 126, - 127, 0, 128, 129, 130, 131, 132, 0, 0, 0, - 134, 135, 136, 137, 138, 139, 0, 141, 142, 143, - 0, 144, 145, 146, 147, 148, 149, 0, 0, 151, - 152, 153, 0, 0, 0, 0, 0, 0, 0, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 164, 0, - 165, 0, 166, 167, 168, 169, 170, 171, 0, 172, - 173, 174, 175, 176, 0, 0, 177, 178, 179, 180, - 181, 0, 182, 183, 184, 0, 185, 186, 187, 0, - 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, - 0, 198, 0, 199, 200, 201, 202, 0, 203, 0, - 204, 0, 0, 0, 207, 208, 209, 0, 211, 0, - 212, 0, 213, 214, 215, 0, 216, 217, 218, 219, - 220, 221, 0, 223, 224, 225, 226, 0, 227, 228, - 229, 230, 231, 232, 0, 233, 0, 235, 236, 237, - 238, 239, 240, 241, 0, 242, 0, 243, 0, 0, - 246, 0, 248, 249, 250, 251, 252, 0, 0, 253, - 0, 255, 0, 0, 257, 258, 259, 0, 0, 260, - 261, 262, 263, 264, 496, 266, 267, 268, 269, 270, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, - 281, 282, 283, 284, 0, 286, 287, 288, 289, 290, - 0, 291, 292, 0, 294, 0, 295, 296, 297, 298, - 299, 300, 0, 301, 302, 0, 0, 303, 304, 305, - 0, 0, 306, 307, 0, 309, 0, 311, 312, 313, - 314, 315, 316, 317, 318, 319, 320, 321, 0, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 0, 331, - 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, - 342, 343, 344, 0, 345, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 0, 357, 358, 0, - 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, - 370, 371, 372, 373, 374, 0, 375, 376, 377, 378, - 379, 0, 380, 381, 382, 383, 384, 0, 386, 387, - 388, 389, 0, 390, 391, 392, 393, 394, 395, 396, - 397, 398, 399, 400, 498, 402, 403, 404, 0, 405, - 406, 0, 407, 0, 409, 410, 411, 412, 413, 0, - 414, 415, 0, 0, 416, 417, 418, 419, 420, 0, - 421, 422, 423, 424, 425, 426, 427, 428, 0, 0, - 429, 430, 431, 432, 433, 0, 0, 434, 435, 436, - 437, 438, 439, 440, 0, 441, 0, 443, 444, 445, - 446, 0, 0, 447, 0, 0, 448, 449, 450, 451, - 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 466, 467, 468, 0, 494, 0, + 1323, 0, 0, 0, 1329, 0, 0, 1330, 1331, 1332, + 0, 1333, 1334, 1335, 1336, 1337, 1338, 0, 0, 0, + 0, 2875, 1329, 0, 0, 1330, 1331, 1332, 0, 1333, + 1334, 1335, 1336, 1337, 1338, 0, 0, 0, 1324, 2887, + 0, 1325, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1326, 0, 0, 1327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1642, 92, 93, 94, 95, 96, 97, - 98, 99, 0, 100, 101, 102, 0, 0, 0, 0, - 0, 0, 0, 103, 104, 0, 105, 106, 107, 0, - 109, 110, 111, 112, 113, 0, 115, 116, 0, 117, - 118, 119, 120, 121, 122, 0, 0, 123, 124, 125, - 126, 127, 0, 128, 129, 130, 131, 132, 0, 0, - 0, 134, 135, 136, 137, 138, 139, 0, 141, 142, - 143, 0, 144, 145, 146, 147, 148, 149, 0, 0, - 151, 152, 153, 0, 0, 0, 0, 0, 0, 0, - 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, - 0, 165, 0, 166, 167, 168, 169, 170, 171, 0, - 172, 173, 174, 175, 176, 0, 0, 177, 178, 179, - 180, 181, 0, 182, 183, 184, 0, 185, 186, 187, - 0, 188, 189, 190, 191, 192, 193, 194, 195, 196, - 197, 0, 198, 0, 199, 200, 201, 202, 0, 203, - 0, 204, 0, 0, 0, 207, 208, 209, 0, 211, - 0, 212, 0, 213, 214, 215, 0, 216, 217, 218, - 219, 220, 221, 0, 223, 224, 225, 226, 0, 227, - 228, 229, 230, 231, 232, 0, 233, 0, 235, 236, - 237, 238, 239, 240, 241, 0, 242, 0, 243, 0, - 0, 246, 0, 248, 249, 250, 251, 252, 0, 0, - 253, 0, 255, 0, 0, 257, 258, 259, 0, 0, - 260, 261, 262, 263, 264, 496, 266, 267, 268, 269, - 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 0, 286, 287, 288, 289, - 290, 0, 291, 292, 0, 294, 0, 295, 296, 297, - 298, 299, 300, 0, 301, 302, 0, 0, 303, 304, - 305, 0, 0, 306, 307, 0, 309, 0, 311, 312, - 313, 314, 315, 316, 317, 318, 319, 320, 321, 0, - 322, 323, 324, 325, 326, 327, 328, 329, 330, 0, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 0, 345, 346, 347, 348, 349, - 350, 351, 352, 353, 354, 355, 356, 0, 357, 358, - 0, 360, 361, 362, 363, 364, 365, 366, 367, 368, - 369, 370, 371, 372, 373, 374, 0, 375, 376, 377, - 378, 379, 0, 380, 381, 382, 383, 384, 0, 386, - 387, 388, 389, 0, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 498, 402, 403, 404, 0, - 405, 406, 0, 407, 0, 409, 410, 411, 412, 413, - 0, 414, 415, 0, 0, 416, 417, 418, 419, 420, - 0, 421, 422, 423, 424, 425, 426, 427, 428, 0, - 0, 429, 430, 431, 432, 433, 0, 0, 434, 435, - 436, 437, 438, 439, 440, 0, 441, 0, 443, 444, - 445, 446, 0, 0, 447, 0, 0, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 0, 494, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1747, 92, 93, 94, 95, 96, - 97, 98, 99, 0, 100, 101, 102, 0, 0, 0, - 0, 0, 0, 0, 103, 104, 0, 105, 106, 107, - 0, 109, 110, 111, 112, 113, 0, 115, 116, 0, - 117, 118, 119, 120, 121, 122, 0, 0, 123, 124, - 125, 126, 127, 0, 128, 129, 130, 131, 132, 0, - 0, 0, 134, 135, 136, 137, 138, 139, 0, 141, - 142, 143, 0, 144, 145, 146, 147, 148, 149, 0, - 0, 151, 152, 153, 0, 0, 0, 0, 0, 0, - 0, 155, 156, 157, 158, 159, 160, 161, 162, 163, - 164, 0, 165, 0, 166, 167, 168, 169, 170, 171, - 0, 172, 173, 174, 175, 176, 0, 0, 177, 178, - 179, 180, 181, 0, 182, 183, 184, 0, 185, 186, - 187, 0, 188, 189, 190, 191, 192, 193, 194, 195, - 196, 197, 0, 198, 0, 199, 200, 201, 202, 0, - 203, 0, 204, 0, 0, 0, 207, 208, 209, 0, - 211, 0, 212, 0, 213, 214, 215, 0, 216, 217, - 218, 219, 220, 221, 0, 223, 224, 225, 226, 0, - 227, 228, 229, 230, 231, 232, 0, 233, 0, 235, - 236, 237, 238, 239, 240, 241, 0, 242, 0, 243, - 0, 0, 246, 0, 248, 249, 250, 251, 252, 0, - 0, 253, 0, 255, 0, 0, 257, 258, 259, 0, - 0, 260, 261, 262, 263, 264, 496, 266, 267, 268, - 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 0, 286, 287, 288, - 289, 290, 0, 291, 292, 0, 294, 0, 295, 296, - 297, 298, 299, 300, 0, 301, 302, 0, 0, 303, - 304, 305, 0, 0, 306, 307, 0, 309, 0, 311, - 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, - 0, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 0, 331, 332, 333, 334, 335, 336, 337, 338, 339, - 340, 341, 342, 343, 344, 0, 345, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, 356, 0, 357, - 358, 0, 360, 361, 362, 363, 364, 365, 366, 367, - 368, 369, 370, 371, 372, 373, 374, 0, 375, 376, - 377, 378, 379, 0, 380, 381, 382, 383, 384, 0, - 386, 387, 388, 389, 0, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 498, 402, 403, 404, - 0, 405, 406, 0, 407, 0, 409, 410, 411, 412, - 413, 0, 414, 415, 0, 0, 416, 417, 418, 419, - 420, 0, 421, 422, 423, 424, 425, 426, 427, 428, - 0, 0, 429, 430, 431, 432, 433, 0, 0, 434, - 435, 436, 437, 438, 439, 440, 0, 441, 0, 443, - 444, 445, 446, 0, 0, 447, 0, 0, 448, 449, - 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 0, - 0, 0, 0, 2372, 1223, 542, 0, 0, 1602, 810, - 0, 0, 0, 0, 0, 2270, 1603, 1604, 1605, 92, - 93, 94, 95, 96, 97, 98, 99, 1044, 100, 101, - 102, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 103, 104, - 1052, 105, 106, 107, 2373, 109, 110, 111, 0, 656, - 2374, 658, 659, 1053, 117, 118, 119, 120, 121, 122, - 1054, 1055, 123, 124, 660, 661, 127, 1056, 128, 129, - 130, 131, 0, 1057, 2375, 1058, 134, 135, 136, 137, - 138, 139, 2376, 141, 142, 143, 1059, 144, 145, 146, - 147, 148, 149, 1060, 2377, 151, 152, 153, 1061, 1062, - 1063, 2378, 1064, 1065, 1066, 155, 156, 157, 158, 159, - 160, 161, 666, 667, 164, 1067, 165, 1068, 166, 167, - 168, 169, 170, 171, 1069, 172, 173, 174, 175, 176, - 1070, 1071, 177, 178, 668, 180, 181, 1072, 182, 183, - 184, 1073, 185, 186, 187, 1074, 188, 189, 190, 191, - 0, 193, 194, 195, 196, 0, 1075, 198, 1076, 199, - 200, 669, 202, 1077, 203, 1078, 204, 2379, 1079, 2380, - 207, 208, 209, 2381, 211, 1080, 212, 1081, 0, 0, - 215, 1082, 216, 217, 218, 219, 220, 221, 2382, 223, - 224, 225, 226, 1083, 227, 228, 229, 230, 231, 232, - 1084, 233, 2383, 0, 236, 237, 238, 239, 676, 677, - 1085, 678, 1086, 243, 2384, 2385, 246, 2386, 248, 249, - 250, 251, 252, 1087, 1088, 253, 2387, 255, 2388, 1089, - 257, 258, 259, 1090, 1091, 260, 261, 262, 263, 264, - 2389, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 685, - 2390, 687, 287, 288, 289, 2391, 1092, 291, 292, 2392, - 294, 1093, 0, 296, 689, 298, 299, 300, 1094, 301, - 302, 1095, 1096, 2393, 304, 305, 1097, 1098, 306, 0, - 2394, 309, 2395, 0, 312, 313, 314, 315, 316, 317, - 318, 319, 320, 321, 1099, 322, 323, 0, 325, 326, - 0, 328, 329, 330, 1100, 331, 332, 333, 334, 335, - 336, 337, 338, 339, 692, 341, 342, 343, 344, 1101, - 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, 1102, 357, 358, 2396, 360, 361, 362, 694, - 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, - 374, 1103, 375, 376, 377, 378, 379, 1104, 380, 2397, - 382, 383, 384, 2398, 386, 387, 697, 389, 1105, 390, - 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, - 2399, 402, 0, 404, 1106, 405, 406, 1107, 407, 2400, - 409, 410, 411, 412, 413, 1108, 700, 701, 1109, 1110, - 416, 417, 0, 419, 0, 1111, 421, 422, 2401, 424, - 425, 426, 427, 428, 1112, 1113, 429, 430, 431, 432, - 433, 1114, 1115, 434, 435, 436, 437, 438, 0, 703, - 1117, 441, 2402, 443, 444, 445, 446, 1118, 1119, 447, - 1120, 1121, 448, 449, 450, 451, 452, 453, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 465, - 466, 467, 468, 0, 494, 0, 1606, 1607, 1608, 1602, - 2403, 2404, 1611, 1612, 1613, 1614, 0, 1603, 1604, 1605, - 92, 93, 94, 95, 96, 97, 98, 99, 0, 100, - 101, 102, 0, 0, 0, 0, 0, 0, 0, 103, - 104, 0, 105, 106, 107, 0, 109, 110, 111, 112, - 113, 0, 115, 116, 0, 117, 118, 119, 120, 121, - 122, 0, 0, 123, 124, 125, 126, 127, 0, 128, - 129, 130, 131, 132, 0, 0, 0, 134, 135, 136, - 137, 138, 139, 0, 141, 142, 143, 0, 144, 145, - 146, 147, 148, 149, 0, 0, 151, 152, 153, 0, - 0, 0, 0, 0, 0, 0, 155, 156, 157, 158, - 159, 160, 161, 162, 163, 164, 0, 165, 0, 166, - 167, 168, 169, 170, 171, 0, 172, 173, 174, 175, - 176, 0, 0, 177, 178, 179, 180, 181, 0, 182, - 183, 184, 0, 185, 186, 187, 0, 188, 189, 190, - 191, 192, 193, 194, 195, 196, 197, 0, 198, 0, - 199, 200, 201, 202, 0, 203, 0, 204, 0, 0, - 0, 207, 208, 209, 0, 211, 0, 212, 0, 213, - 214, 215, 0, 216, 217, 218, 219, 220, 221, 0, - 223, 224, 225, 226, 0, 227, 228, 229, 230, 231, - 232, 0, 233, 0, 235, 236, 237, 238, 239, 240, - 241, 0, 242, 0, 243, 0, 0, 246, 0, 248, - 249, 250, 251, 252, 0, 0, 253, 0, 255, 0, - 0, 257, 258, 259, 0, 0, 260, 261, 262, 263, - 264, 496, 266, 267, 268, 269, 270, 271, 272, 273, - 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 0, 286, 287, 288, 289, 290, 0, 291, 292, - 0, 294, 0, 295, 296, 297, 298, 299, 300, 0, - 301, 302, 0, 0, 303, 304, 305, 0, 0, 306, - 307, 0, 309, 0, 311, 312, 313, 314, 315, 316, - 317, 318, 319, 320, 321, 0, 322, 323, 324, 325, - 326, 327, 328, 329, 330, 0, 331, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 0, 345, 346, 347, 348, 349, 350, 351, 352, 353, - 354, 355, 356, 0, 357, 358, 0, 360, 361, 362, - 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, - 373, 374, 0, 375, 376, 377, 378, 379, 0, 380, - 381, 382, 383, 384, 0, 386, 387, 388, 389, 0, - 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, - 400, 498, 402, 403, 404, 0, 405, 406, 0, 407, - 0, 409, 410, 411, 412, 413, 0, 414, 415, 0, - 0, 416, 417, 418, 419, 420, 0, 421, 422, 423, - 424, 425, 426, 427, 428, 0, 0, 429, 430, 431, - 432, 433, 0, 0, 434, 435, 436, 437, 438, 439, - 440, 502, 441, 0, 443, 444, 445, 446, 0, 0, - 447, 0, 0, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, - 465, 466, 467, 468, 0, 0, 0, 1606, 1607, 1608, - 0, 1609, 1610, 1611, 1612, 1613, 1614, 1299, 0, 0, - 1300, 0, 0, 0, 503, 1301, 1302, 1303, 0, 0, - 0, 0, 0, 0, 0, 1299, 0, 0, 1300, 0, - 504, 0, 1304, 1301, 1302, 1303, 0, 0, 0, 0, - 1306, 0, 0, 1299, 0, 0, 1300, 1307, 0, 0, - 1304, 1301, 1302, 1303, 0, 0, 0, 0, 1306, 0, - 0, 0, 0, 0, 0, 1307, 0, 0, 1304, 0, - 0, 0, 1308, 0, 0, 0, 1306, 0, 0, 0, - 0, 0, 0, 1307, 505, 0, 0, 0, 0, 0, - 1308, 0, 0, 506, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 507, 0, 0, 1308, 0, - 508, 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, 509, 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, 1309, 0, 0, 0, 0, 0, 0, 510, - 0, 0, 0, 511, 0, 0, 0, 1310, 0, 0, - 1309, 0, 1311, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1310, 0, 0, 1309, 0, - 1311, 0, 0, 1312, 1313, 0, 0, 0, 0, 0, - 0, 0, 0, 1310, 0, 0, 0, 1314, 1311, 0, - 0, 1312, 1313, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1314, 512, 0, 0, 1312, - 1313, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 513, 0, 0, 1314, 0, 1315, 0, 0, 1316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1317, 1315, 0, 1318, 1316, 0, 0, 0, - 0, 514, 0, 0, 515, 0, 0, 0, 0, 0, - 1317, 1315, 516, 1318, 1316, 517, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1317, 0, - 0, 1318, 0, 0, 518, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 519, 0, 0, - 0, 0, 0, 0, 520, 0, 0, 0, 0, 0, - 0, 0, 0, 521, 0, 0, 0, 0, 0, 522, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1319, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 523, 0, 0, 0, 0, 0, - 1319, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1319, 0, + 0, 0, 0, 0, 0, 0, 0, 1328, 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, 1320, 0, 0, 1321, 1322, 1323, 0, 1324, - 1325, 1326, 1327, 1328, 1329, 0, 0, 0, 0, 2840, - 1320, 0, 0, 1321, 1322, 1323, 0, 1324, 1325, 1326, - 1327, 1328, 1329, 0, 0, 0, 0, 2852, 1320, 1043, - 0, 1321, 1322, 1323, 0, 1324, 1325, 1326, 1327, 1328, - 1329, 0, 0, 1478, 0, 92, 93, 94, 95, 96, - 97, 98, 99, 1044, 100, 101, 102, 1045, 1046, 1047, - 1048, 1049, 1050, 1051, 103, 104, 1052, 105, 106, 107, - 0, 109, 110, 111, 736, 737, 0, 738, 739, 1053, - 117, 118, 119, 120, 121, 122, 1054, 1055, 123, 124, - 740, 741, 127, 1056, 128, 129, 130, 131, 742, 1057, - 0, 1058, 134, 135, 136, 137, 138, 139, 0, 141, - 142, 143, 1059, 144, 145, 146, 147, 148, 149, 1060, - 0, 151, 152, 153, 1061, 1062, 1063, 0, 1064, 1065, - 1066, 155, 156, 157, 158, 159, 160, 161, 743, 744, - 164, 1067, 165, 1068, 166, 167, 168, 169, 170, 171, - 1069, 172, 173, 174, 175, 176, 1070, 1071, 177, 178, - 179, 180, 181, 1072, 182, 183, 184, 1073, 185, 186, - 187, 1074, 188, 189, 190, 191, 745, 193, 194, 195, - 196, 746, 1075, 198, 1076, 199, 200, 747, 202, 1077, - 203, 1078, 204, 0, 1079, 0, 207, 208, 209, 0, - 211, 1080, 212, 1081, 748, 749, 215, 1082, 216, 217, - 218, 219, 220, 221, 0, 223, 224, 225, 226, 1083, - 227, 228, 229, 230, 231, 232, 1084, 233, 0, 750, - 236, 237, 238, 239, 751, 752, 1085, 753, 1086, 243, - 0, 0, 246, 0, 248, 249, 250, 251, 252, 1087, - 1088, 253, 0, 255, 0, 1089, 257, 258, 259, 1090, - 1091, 260, 261, 262, 263, 264, 754, 266, 267, 268, - 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 280, 281, 282, 283, 755, 0, 756, 287, 288, - 289, 757, 1092, 291, 292, 0, 294, 1093, 758, 296, - 759, 298, 299, 300, 1094, 301, 302, 1095, 1096, 303, - 304, 305, 1097, 1098, 306, 760, 0, 309, 0, 761, - 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, - 1099, 322, 323, 762, 325, 326, 763, 328, 329, 330, - 1100, 331, 332, 333, 334, 335, 336, 337, 338, 339, - 764, 341, 342, 343, 344, 1101, 345, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, 356, 1102, 357, - 358, 0, 360, 361, 362, 765, 364, 365, 366, 367, - 368, 369, 370, 371, 372, 373, 374, 1103, 375, 376, - 377, 378, 379, 1104, 380, 766, 382, 383, 384, 0, - 386, 387, 767, 389, 1105, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 768, 402, 769, 404, - 1106, 405, 406, 1107, 407, 0, 409, 410, 411, 412, - 413, 1108, 770, 771, 1109, 1110, 416, 417, 772, 419, - 773, 1111, 421, 422, 774, 424, 425, 426, 427, 428, - 1112, 1113, 429, 430, 431, 432, 433, 1114, 1115, 434, - 435, 436, 437, 438, 1116, 776, 1117, 441, 0, 443, - 444, 445, 446, 1118, 1119, 447, 1120, 1121, 448, 449, - 450, 451, 452, 453, 777, 778, 779, 780, 781, 782, - 783, 784, 785, 786, 787, 465, 466, 467, 468, 494, - 0, 0, 0, 0, 0, 0, 0, 0, 1726, 0, - 0, 0, 0, 0, 0, 92, 93, 94, 95, 96, - 97, 98, 99, 0, 100, 101, 102, 0, 0, 0, - 0, 0, 0, 0, 103, 104, 0, 105, 106, 107, - 0, 109, 110, 111, 112, 113, 0, 115, 116, 0, - 117, 118, 119, 120, 121, 122, 0, 0, 123, 124, - 125, 126, 127, 0, 128, 129, 130, 131, 132, 0, - 0, 0, 134, 135, 136, 137, 138, 139, 0, 141, - 142, 143, 0, 144, 145, 146, 147, 148, 149, 0, - 0, 151, 152, 153, 0, 0, 0, 0, 0, 0, - 0, 155, 156, 157, 158, 159, 160, 161, 162, 163, - 164, 0, 165, 0, 166, 167, 168, 169, 170, 171, - 0, 172, 173, 174, 175, 176, 0, 0, 177, 178, - 179, 180, 181, 0, 182, 183, 184, 0, 185, 186, - 187, 0, 188, 189, 190, 191, 192, 193, 194, 195, - 196, 197, 0, 198, 0, 199, 200, 201, 202, 0, - 203, 0, 204, 0, 0, 0, 207, 208, 209, 0, - 211, 0, 212, 0, 213, 214, 215, 0, 216, 217, - 218, 219, 220, 221, 0, 223, 224, 225, 226, 0, - 227, 228, 229, 230, 231, 232, 0, 233, 0, 235, - 236, 237, 238, 239, 240, 241, 0, 242, 0, 243, - 0, 0, 246, 0, 248, 249, 250, 251, 252, 0, - 0, 253, 0, 255, 0, 0, 257, 258, 259, 0, - 0, 260, 261, 262, 263, 264, 496, 266, 267, 268, - 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 0, 286, 287, 288, - 289, 290, 0, 291, 292, 0, 294, 0, 295, 296, - 297, 298, 299, 300, 0, 301, 302, 0, 0, 303, - 304, 305, 0, 0, 306, 307, 0, 309, 0, 311, - 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, - 0, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 0, 331, 332, 333, 334, 335, 336, 337, 338, 339, - 340, 341, 342, 343, 344, 0, 345, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, 356, 0, 357, - 358, 0, 360, 361, 362, 363, 364, 365, 366, 367, - 368, 369, 370, 371, 372, 373, 374, 0, 375, 376, - 377, 378, 379, 0, 380, 381, 382, 383, 384, 0, - 386, 387, 388, 389, 0, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 498, 402, 403, 404, - 0, 405, 406, 0, 407, 0, 409, 410, 411, 412, - 413, 0, 414, 415, 0, 0, 416, 417, 418, 419, - 420, 0, 421, 422, 423, 424, 425, 426, 427, 428, - 0, 0, 429, 430, 431, 432, 433, 0, 0, 434, - 435, 436, 437, 438, 439, 440, 0, 441, 0, 443, - 444, 445, 446, 0, 0, 447, 0, 0, 448, 449, - 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 735, - 1223, 542, 0, 0, 0, 810, 0, 0, 2201, 0, - 0, 0, 0, 0, 0, 92, 93, 94, 95, 96, - 97, 98, 99, 0, 100, 101, 102, 0, 0, 0, - 0, 0, 0, 0, 103, 104, 0, 105, 106, 107, - 0, 109, 110, 111, 736, 737, 0, 738, 739, 0, - 117, 118, 119, 120, 121, 122, 0, 0, 123, 124, - 740, 741, 127, 0, 128, 129, 130, 131, 742, 0, - 0, 0, 134, 135, 136, 137, 138, 139, 0, 141, - 142, 143, 0, 144, 145, 146, 147, 148, 149, 0, - 0, 151, 152, 153, 0, 0, 0, 0, 0, 0, - 0, 155, 156, 157, 158, 159, 160, 161, 743, 744, - 164, 1358, 165, 0, 166, 167, 168, 169, 170, 171, - 0, 172, 173, 174, 175, 176, 0, 0, 177, 178, - 179, 180, 181, 0, 182, 183, 184, 0, 185, 186, - 187, 0, 188, 189, 190, 191, 745, 193, 194, 195, - 196, 746, 1224, 198, 0, 199, 200, 747, 202, 0, - 203, 0, 204, 0, 0, 0, 207, 208, 209, 0, - 211, 0, 212, 0, 748, 749, 215, 0, 216, 217, - 218, 219, 220, 221, 0, 223, 224, 225, 226, 0, - 227, 228, 229, 230, 231, 232, 0, 233, 0, 750, - 236, 237, 238, 239, 751, 752, 0, 753, 0, 243, - 0, 0, 246, 0, 248, 249, 250, 251, 252, 0, - 0, 253, 0, 255, 0, 0, 257, 258, 259, 0, - 0, 260, 261, 262, 263, 264, 754, 266, 267, 268, - 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 280, 281, 282, 283, 755, 0, 756, 287, 288, - 289, 757, 0, 291, 292, 0, 294, 0, 758, 296, - 759, 298, 299, 300, 0, 301, 302, 1225, 0, 303, - 304, 305, 0, 0, 306, 760, 0, 309, 0, 761, - 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, - 0, 322, 323, 762, 325, 326, 763, 328, 329, 330, - 0, 331, 332, 333, 334, 335, 336, 337, 338, 339, - 764, 341, 342, 343, 344, 0, 345, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, 356, 0, 357, - 358, 0, 360, 361, 362, 765, 364, 365, 366, 367, - 368, 369, 370, 371, 372, 373, 374, 0, 375, 376, - 377, 378, 379, 0, 380, 766, 382, 383, 384, 0, - 386, 387, 767, 389, 0, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 768, 402, 769, 404, - 0, 405, 406, 0, 407, 0, 409, 410, 411, 412, - 413, 0, 770, 771, 0, 0, 416, 417, 772, 419, - 773, 1226, 421, 422, 774, 424, 425, 426, 427, 428, - 0, 0, 429, 430, 431, 432, 433, 0, 0, 434, - 435, 436, 437, 438, 1116, 776, 0, 441, 0, 443, - 444, 445, 446, 0, 0, 447, 0, 0, 448, 449, - 450, 451, 452, 453, 777, 778, 779, 780, 781, 782, - 783, 784, 785, 786, 787, 465, 466, 467, 468, 735, - 1223, 542, 0, 0, 0, 810, 1227, 1228, 0, 0, - 0, 0, 0, 0, 0, 92, 93, 94, 95, 96, - 97, 98, 99, 0, 100, 101, 102, 0, 0, 0, - 0, 0, 0, 0, 103, 104, 0, 105, 106, 107, - 0, 109, 110, 111, 736, 737, 0, 738, 739, 0, - 117, 118, 119, 120, 121, 122, 0, 0, 123, 124, - 740, 741, 127, 0, 128, 129, 130, 131, 742, 0, - 0, 0, 134, 135, 136, 137, 138, 139, 0, 141, - 142, 143, 0, 144, 145, 146, 147, 148, 149, 0, - 0, 151, 152, 153, 0, 0, 0, 0, 0, 0, - 0, 155, 156, 157, 158, 159, 160, 161, 743, 744, - 164, 1360, 165, 0, 166, 167, 168, 169, 170, 171, - 0, 172, 173, 174, 175, 176, 0, 0, 177, 178, - 179, 180, 181, 0, 182, 183, 184, 0, 185, 186, - 187, 0, 188, 189, 190, 191, 745, 193, 194, 195, - 196, 746, 1224, 198, 0, 199, 200, 747, 202, 0, - 203, 0, 204, 0, 0, 0, 207, 208, 209, 0, - 211, 0, 212, 0, 748, 749, 215, 0, 216, 217, - 218, 219, 220, 221, 0, 223, 224, 225, 226, 0, - 227, 228, 229, 230, 231, 232, 0, 233, 0, 750, - 236, 237, 238, 239, 751, 752, 0, 753, 0, 243, - 0, 0, 246, 0, 248, 249, 250, 251, 252, 0, - 0, 253, 0, 255, 0, 0, 257, 258, 259, 0, - 0, 260, 261, 262, 263, 264, 754, 266, 267, 268, - 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 280, 281, 282, 283, 755, 0, 756, 287, 288, - 289, 757, 0, 291, 292, 0, 294, 0, 758, 296, - 759, 298, 299, 300, 0, 301, 302, 1225, 0, 303, - 304, 305, 0, 0, 306, 760, 0, 309, 0, 761, - 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, - 0, 322, 323, 762, 325, 326, 763, 328, 329, 330, - 0, 331, 332, 333, 334, 335, 336, 337, 338, 339, - 764, 341, 342, 343, 344, 0, 345, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, 356, 0, 357, - 358, 0, 360, 361, 362, 765, 364, 365, 366, 367, - 368, 369, 370, 371, 372, 373, 374, 0, 375, 376, - 377, 378, 379, 0, 380, 766, 382, 383, 384, 0, - 386, 387, 767, 389, 0, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 768, 402, 769, 404, - 0, 405, 406, 0, 407, 0, 409, 410, 411, 412, - 413, 0, 770, 771, 0, 0, 416, 417, 772, 419, - 773, 1226, 421, 422, 774, 424, 425, 426, 427, 428, - 0, 0, 429, 430, 431, 432, 433, 0, 0, 434, - 435, 436, 437, 438, 1116, 776, 0, 441, 0, 443, - 444, 445, 446, 0, 0, 447, 0, 0, 448, 449, - 450, 451, 452, 453, 777, 778, 779, 780, 781, 782, - 783, 784, 785, 786, 787, 465, 466, 467, 468, 735, - 1223, 542, 0, 0, 0, 810, 1227, 1228, 0, 0, - 0, 0, 0, 0, 0, 92, 93, 94, 95, 96, - 97, 98, 99, 0, 100, 101, 102, 0, 0, 0, - 0, 0, 0, 0, 103, 104, 0, 105, 106, 107, - 0, 109, 110, 111, 736, 737, 0, 738, 739, 0, - 117, 118, 119, 120, 121, 122, 0, 0, 123, 124, - 740, 741, 127, 0, 128, 129, 130, 131, 742, 0, - 0, 0, 134, 135, 136, 137, 138, 139, 0, 141, - 142, 143, 0, 144, 145, 146, 147, 148, 149, 0, - 0, 151, 152, 153, 0, 0, 0, 0, 0, 0, - 0, 155, 156, 157, 158, 159, 160, 161, 743, 744, - 164, 0, 165, 0, 166, 167, 168, 169, 170, 171, - 0, 172, 173, 174, 175, 176, 0, 0, 177, 178, - 179, 180, 181, 0, 182, 183, 184, 0, 185, 186, - 187, 0, 188, 189, 190, 191, 745, 193, 194, 195, - 196, 746, 1224, 198, 0, 199, 200, 747, 202, 0, - 203, 0, 204, 0, 0, 0, 207, 208, 209, 0, - 211, 0, 212, 0, 748, 749, 215, 0, 216, 217, - 218, 219, 220, 221, 0, 223, 224, 225, 226, 0, - 227, 228, 229, 230, 231, 232, 0, 233, 0, 750, - 236, 237, 238, 239, 751, 752, 0, 753, 0, 243, - 0, 0, 246, 0, 248, 249, 250, 251, 252, 0, - 0, 253, 0, 255, 0, 0, 257, 258, 259, 0, - 0, 260, 261, 262, 263, 264, 754, 266, 267, 268, + 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, 1329, 1051, 0, + 1330, 1331, 1332, 0, 1333, 1334, 1335, 1336, 1337, 1338, + 0, 0, 1491, 0, 93, 94, 95, 96, 97, 98, + 99, 100, 1052, 101, 102, 103, 1053, 1054, 1055, 1056, + 1057, 1058, 1059, 104, 105, 1060, 106, 107, 108, 0, + 110, 111, 112, 743, 744, 0, 745, 746, 1061, 118, + 119, 120, 121, 122, 123, 1062, 1063, 124, 125, 747, + 748, 128, 1064, 129, 130, 131, 132, 749, 1065, 0, + 1066, 135, 136, 137, 138, 139, 140, 0, 142, 143, + 144, 1067, 145, 146, 147, 148, 149, 150, 1068, 0, + 152, 153, 154, 1069, 1070, 1071, 0, 1072, 1073, 1074, + 156, 157, 158, 159, 160, 161, 162, 750, 751, 165, + 1075, 166, 1076, 167, 168, 169, 170, 171, 172, 1077, + 173, 174, 175, 176, 177, 1078, 1079, 178, 179, 180, + 181, 182, 1080, 183, 184, 185, 1081, 186, 187, 188, + 1082, 189, 190, 191, 192, 752, 194, 195, 196, 197, + 753, 1083, 199, 1084, 200, 201, 754, 203, 1085, 204, + 1086, 205, 0, 1087, 0, 208, 209, 210, 0, 212, + 1088, 213, 1089, 755, 756, 216, 1090, 217, 218, 219, + 220, 221, 222, 223, 0, 225, 226, 227, 228, 1091, + 229, 230, 231, 232, 233, 234, 1092, 235, 0, 757, + 238, 239, 240, 241, 242, 758, 759, 1093, 760, 1094, + 246, 0, 0, 249, 0, 251, 252, 253, 254, 255, + 1095, 1096, 256, 0, 258, 0, 1097, 260, 261, 262, + 1098, 1099, 263, 264, 265, 266, 267, 761, 269, 270, + 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, + 281, 282, 283, 284, 285, 286, 762, 0, 763, 290, + 291, 292, 764, 1100, 294, 295, 0, 297, 1101, 765, + 299, 766, 301, 302, 303, 1102, 304, 305, 1103, 1104, + 306, 307, 308, 1105, 1106, 309, 767, 0, 312, 0, + 768, 315, 316, 317, 318, 319, 320, 321, 322, 323, + 324, 1107, 325, 326, 769, 328, 329, 770, 331, 332, + 333, 1108, 334, 335, 336, 337, 338, 339, 1109, 340, + 341, 342, 771, 344, 345, 346, 347, 1110, 348, 349, + 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, + 360, 1111, 361, 362, 0, 364, 365, 366, 772, 368, + 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, + 1112, 379, 380, 381, 382, 383, 1113, 384, 773, 386, + 387, 388, 0, 390, 391, 774, 393, 1114, 394, 395, + 396, 397, 398, 399, 400, 401, 402, 403, 404, 775, + 406, 776, 408, 1115, 409, 410, 1116, 411, 0, 413, + 414, 415, 416, 417, 1117, 777, 778, 1118, 1119, 420, + 421, 779, 423, 780, 1120, 425, 426, 781, 428, 429, + 430, 431, 432, 1121, 1122, 433, 434, 435, 436, 437, + 1123, 1124, 438, 439, 440, 441, 442, 1125, 783, 1126, + 445, 0, 447, 448, 449, 450, 1127, 1128, 451, 1129, + 1130, 452, 453, 454, 455, 456, 457, 784, 785, 786, + 787, 788, 789, 790, 791, 792, 793, 794, 469, 470, + 471, 472, 498, 0, 0, 0, 0, 0, 0, 0, + 0, 1739, 0, 0, 0, 0, 0, 0, 93, 94, + 95, 96, 97, 98, 99, 100, 0, 101, 102, 103, + 0, 0, 0, 0, 0, 0, 0, 104, 105, 0, + 106, 107, 108, 0, 110, 111, 112, 113, 114, 0, + 116, 117, 0, 118, 119, 120, 121, 122, 123, 0, + 0, 124, 125, 126, 127, 128, 0, 129, 130, 131, + 132, 133, 0, 0, 0, 135, 136, 137, 138, 139, + 140, 0, 142, 143, 144, 0, 145, 146, 147, 148, + 149, 150, 0, 0, 152, 153, 154, 0, 0, 0, + 0, 0, 0, 0, 156, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 0, 166, 0, 167, 168, 169, + 170, 171, 172, 0, 173, 174, 175, 176, 177, 0, + 0, 178, 179, 180, 181, 182, 0, 183, 184, 185, + 0, 186, 187, 188, 0, 189, 190, 191, 192, 193, + 194, 195, 196, 197, 198, 0, 199, 0, 200, 201, + 202, 203, 0, 204, 0, 205, 0, 0, 0, 208, + 209, 210, 0, 212, 0, 213, 0, 214, 215, 216, + 0, 217, 218, 219, 220, 221, 222, 223, 0, 225, + 226, 227, 228, 0, 229, 230, 231, 232, 233, 234, + 0, 235, 0, 237, 238, 239, 240, 241, 242, 243, + 244, 0, 245, 0, 246, 0, 0, 249, 0, 251, + 252, 253, 254, 255, 0, 0, 256, 0, 258, 0, + 0, 260, 261, 262, 0, 0, 263, 264, 265, 266, + 267, 500, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 0, 289, 290, 291, 292, 293, 0, 294, 295, + 0, 297, 0, 298, 299, 300, 301, 302, 303, 0, + 304, 305, 0, 0, 306, 307, 308, 0, 0, 309, + 310, 0, 312, 0, 314, 315, 316, 317, 318, 319, + 320, 321, 322, 323, 324, 0, 325, 326, 327, 328, + 329, 330, 331, 332, 333, 0, 334, 335, 336, 337, + 338, 339, 0, 340, 341, 342, 343, 344, 345, 346, + 347, 0, 348, 349, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 0, 361, 362, 0, 364, + 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 0, 379, 380, 381, 382, 383, + 0, 384, 385, 386, 387, 388, 0, 390, 391, 392, + 393, 0, 394, 395, 396, 397, 398, 399, 400, 401, + 402, 403, 404, 502, 406, 407, 408, 0, 409, 410, + 0, 411, 0, 413, 414, 415, 416, 417, 0, 418, + 419, 0, 0, 420, 421, 422, 423, 424, 0, 425, + 426, 427, 428, 429, 430, 431, 432, 0, 0, 433, + 434, 435, 436, 437, 0, 0, 438, 439, 440, 441, + 442, 443, 444, 0, 445, 0, 447, 448, 449, 450, + 0, 0, 451, 0, 0, 452, 453, 454, 455, 456, + 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, + 467, 468, 469, 470, 471, 472, 742, 1232, 547, 0, + 0, 0, 818, 0, 0, 2226, 0, 0, 0, 0, + 0, 0, 93, 94, 95, 96, 97, 98, 99, 100, + 0, 101, 102, 103, 0, 0, 0, 0, 0, 0, + 0, 104, 105, 0, 106, 107, 108, 0, 110, 111, + 112, 743, 744, 0, 745, 746, 0, 118, 119, 120, + 121, 122, 123, 0, 0, 124, 125, 747, 748, 128, + 0, 129, 130, 131, 132, 749, 0, 0, 0, 135, + 136, 137, 138, 139, 140, 0, 142, 143, 144, 0, + 145, 146, 147, 148, 149, 150, 0, 0, 152, 153, + 154, 0, 0, 0, 0, 0, 0, 0, 156, 157, + 158, 159, 160, 161, 162, 750, 751, 165, 1367, 166, + 0, 167, 168, 169, 170, 171, 172, 0, 173, 174, + 175, 176, 177, 0, 0, 178, 179, 180, 181, 182, + 0, 183, 184, 185, 0, 186, 187, 188, 0, 189, + 190, 191, 192, 752, 194, 195, 196, 197, 753, 1233, + 199, 0, 200, 201, 754, 203, 0, 204, 0, 205, + 0, 0, 0, 208, 209, 210, 0, 212, 0, 213, + 0, 755, 756, 216, 0, 217, 218, 219, 220, 221, + 222, 223, 0, 225, 226, 227, 228, 0, 229, 230, + 231, 232, 233, 234, 0, 235, 0, 757, 238, 239, + 240, 241, 242, 758, 759, 0, 760, 0, 246, 0, + 0, 249, 0, 251, 252, 253, 254, 255, 0, 0, + 256, 0, 258, 0, 0, 260, 261, 262, 0, 0, + 263, 264, 265, 266, 267, 761, 269, 270, 271, 272, + 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, + 283, 284, 285, 286, 762, 0, 763, 290, 291, 292, + 764, 0, 294, 295, 0, 297, 0, 765, 299, 766, + 301, 302, 303, 0, 304, 305, 1234, 0, 306, 307, + 308, 0, 0, 309, 767, 0, 312, 0, 768, 315, + 316, 317, 318, 319, 320, 321, 322, 323, 324, 0, + 325, 326, 769, 328, 329, 770, 331, 332, 333, 0, + 334, 335, 336, 337, 338, 339, 0, 340, 341, 342, + 771, 344, 345, 346, 347, 0, 348, 349, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 0, + 361, 362, 0, 364, 365, 366, 772, 368, 369, 370, + 371, 372, 373, 374, 375, 376, 377, 378, 0, 379, + 380, 381, 382, 383, 0, 384, 773, 386, 387, 388, + 0, 390, 391, 774, 393, 0, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, 404, 775, 406, 776, + 408, 0, 409, 410, 0, 411, 0, 413, 414, 415, + 416, 417, 0, 777, 778, 0, 0, 420, 421, 779, + 423, 780, 1235, 425, 426, 781, 428, 429, 430, 431, + 432, 0, 0, 433, 434, 435, 436, 437, 0, 0, + 438, 439, 440, 441, 442, 1125, 783, 0, 445, 0, + 447, 448, 449, 450, 0, 0, 451, 0, 0, 452, + 453, 454, 455, 456, 457, 784, 785, 786, 787, 788, + 789, 790, 791, 792, 793, 794, 469, 470, 471, 472, + 742, 1232, 547, 0, 0, 0, 818, 1236, 1237, 0, + 0, 0, 0, 0, 0, 0, 93, 94, 95, 96, + 97, 98, 99, 100, 0, 101, 102, 103, 0, 0, + 0, 0, 0, 0, 0, 104, 105, 0, 106, 107, + 108, 0, 110, 111, 112, 743, 744, 0, 745, 746, + 0, 118, 119, 120, 121, 122, 123, 0, 0, 124, + 125, 747, 748, 128, 0, 129, 130, 131, 132, 749, + 0, 0, 0, 135, 136, 137, 138, 139, 140, 0, + 142, 143, 144, 0, 145, 146, 147, 148, 149, 150, + 0, 0, 152, 153, 154, 0, 0, 0, 0, 0, + 0, 0, 156, 157, 158, 159, 160, 161, 162, 750, + 751, 165, 1369, 166, 0, 167, 168, 169, 170, 171, + 172, 0, 173, 174, 175, 176, 177, 0, 0, 178, + 179, 180, 181, 182, 0, 183, 184, 185, 0, 186, + 187, 188, 0, 189, 190, 191, 192, 752, 194, 195, + 196, 197, 753, 1233, 199, 0, 200, 201, 754, 203, + 0, 204, 0, 205, 0, 0, 0, 208, 209, 210, + 0, 212, 0, 213, 0, 755, 756, 216, 0, 217, + 218, 219, 220, 221, 222, 223, 0, 225, 226, 227, + 228, 0, 229, 230, 231, 232, 233, 234, 0, 235, + 0, 757, 238, 239, 240, 241, 242, 758, 759, 0, + 760, 0, 246, 0, 0, 249, 0, 251, 252, 253, + 254, 255, 0, 0, 256, 0, 258, 0, 0, 260, + 261, 262, 0, 0, 263, 264, 265, 266, 267, 761, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 280, 281, 282, 283, 755, 0, 756, 287, 288, - 289, 757, 0, 291, 292, 0, 294, 0, 758, 296, - 759, 298, 299, 300, 0, 301, 302, 1225, 0, 303, - 304, 305, 0, 0, 306, 760, 0, 309, 0, 761, - 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, - 0, 322, 323, 762, 325, 326, 763, 328, 329, 330, - 0, 331, 332, 333, 334, 335, 336, 337, 338, 339, - 764, 341, 342, 343, 344, 0, 345, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, 356, 0, 357, - 358, 0, 360, 361, 362, 765, 364, 365, 366, 367, - 368, 369, 370, 371, 372, 373, 374, 0, 375, 376, - 377, 378, 379, 0, 380, 766, 382, 383, 384, 0, - 386, 387, 767, 389, 0, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 768, 402, 769, 404, - 0, 405, 406, 0, 407, 0, 409, 410, 411, 412, - 413, 0, 770, 771, 0, 0, 416, 417, 772, 419, - 773, 1226, 421, 422, 774, 424, 425, 426, 427, 428, - 0, 0, 429, 430, 431, 432, 433, 0, 0, 434, - 435, 436, 437, 438, 1116, 776, 0, 441, 0, 443, - 444, 445, 446, 0, 0, 447, 0, 0, 448, 449, - 450, 451, 452, 453, 777, 778, 779, 780, 781, 782, - 783, 784, 785, 786, 787, 465, 466, 467, 468, 0, - 1299, 0, 0, 1300, 0, 0, 1227, 1228, 1301, 1302, - 1303, 0, 0, 0, 0, 0, 0, 0, 1299, 0, - 0, 1300, 0, 0, 0, 1304, 1301, 1302, 1303, 1753, - 0, 0, 0, 1306, 0, 0, 1299, 0, 0, 1300, - 1307, 0, 0, 1304, 1301, 1302, 1303, 0, 0, 0, - 0, 1306, 0, 0, 0, 0, 0, 0, 1307, 0, - 0, 1304, 0, 0, 1299, 1308, 0, 1300, 0, 1306, - 0, 0, 1301, 1302, 1303, 0, 1307, 0, 0, 0, - 0, 0, 0, 1308, 0, 0, 0, 0, 0, 1304, - 0, 0, 1942, 0, 0, 0, 0, 1306, 0, 0, - 0, 1308, 0, 0, 1307, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1754, 0, 0, 0, - 0, 0, 0, 0, 1299, 0, 0, 1300, 0, 1308, - 0, 0, 1301, 1302, 1303, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1304, - 0, 0, 0, 0, 0, 0, 0, 1306, 0, 0, - 0, 0, 0, 0, 1307, 1309, 0, 0, 0, 0, - 0, 0, 0, 1980, 0, 0, 0, 0, 1981, 0, - 1310, 0, 0, 1309, 0, 1311, 0, 0, 0, 1308, - 2913, 0, 0, 0, 0, 0, 0, 0, 1310, 0, - 0, 1309, 0, 1311, 0, 0, 1312, 1313, 0, 0, - 0, 0, 0, 0, 0, 0, 1310, 0, 0, 0, - 1314, 1311, 0, 0, 1312, 1313, 0, 0, 0, 1309, - 0, 0, 0, 0, 0, 0, 0, 0, 1314, 0, - 0, 0, 1312, 1313, 1310, 0, 0, 0, 0, 1311, - 0, 0, 0, 0, 0, 0, 1314, 0, 1315, 0, - 0, 1316, 0, 0, 0, 0, 0, 0, 0, 0, - 1312, 1313, 0, 0, 0, 1317, 1315, 0, 1318, 1316, - 0, 0, 0, 0, 1314, 0, 0, 0, 0, 1309, - 0, 0, 0, 1317, 1315, 0, 1318, 1316, 0, 0, - 0, 0, 0, 0, 1310, 0, 0, 0, 0, 1311, - 0, 1317, 0, 0, 1318, 0, 0, 0, 0, 0, - 0, 0, 1315, 0, 0, 1316, 0, 0, 0, 0, - 1312, 1313, 0, 0, 0, 0, 0, 2914, 0, 1317, - 0, 0, 1318, 0, 1314, 0, 0, 0, 0, 0, + 279, 280, 281, 282, 283, 284, 285, 286, 762, 0, + 763, 290, 291, 292, 764, 0, 294, 295, 0, 297, + 0, 765, 299, 766, 301, 302, 303, 0, 304, 305, + 1234, 0, 306, 307, 308, 0, 0, 309, 767, 0, + 312, 0, 768, 315, 316, 317, 318, 319, 320, 321, + 322, 323, 324, 0, 325, 326, 769, 328, 329, 770, + 331, 332, 333, 0, 334, 335, 336, 337, 338, 339, + 0, 340, 341, 342, 771, 344, 345, 346, 347, 0, + 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, + 358, 359, 360, 0, 361, 362, 0, 364, 365, 366, + 772, 368, 369, 370, 371, 372, 373, 374, 375, 376, + 377, 378, 0, 379, 380, 381, 382, 383, 0, 384, + 773, 386, 387, 388, 0, 390, 391, 774, 393, 0, + 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, + 404, 775, 406, 776, 408, 0, 409, 410, 0, 411, + 0, 413, 414, 415, 416, 417, 0, 777, 778, 0, + 0, 420, 421, 779, 423, 780, 1235, 425, 426, 781, + 428, 429, 430, 431, 432, 0, 0, 433, 434, 435, + 436, 437, 0, 0, 438, 439, 440, 441, 442, 1125, + 783, 0, 445, 0, 447, 448, 449, 450, 0, 0, + 451, 0, 0, 452, 453, 454, 455, 456, 457, 784, + 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, + 469, 470, 471, 472, 742, 1232, 547, 0, 0, 0, + 818, 1236, 1237, 0, 0, 0, 0, 0, 0, 0, + 93, 94, 95, 96, 97, 98, 99, 100, 0, 101, + 102, 103, 0, 0, 0, 0, 0, 0, 0, 104, + 105, 0, 106, 107, 108, 0, 110, 111, 112, 743, + 744, 0, 745, 746, 0, 118, 119, 120, 121, 122, + 123, 0, 0, 124, 125, 747, 748, 128, 0, 129, + 130, 131, 132, 749, 0, 0, 0, 135, 136, 137, + 138, 139, 140, 0, 142, 143, 144, 0, 145, 146, + 147, 148, 149, 150, 0, 0, 152, 153, 154, 0, + 0, 0, 0, 0, 0, 0, 156, 157, 158, 159, + 160, 161, 162, 750, 751, 165, 0, 166, 0, 167, + 168, 169, 170, 171, 172, 0, 173, 174, 175, 176, + 177, 0, 0, 178, 179, 180, 181, 182, 0, 183, + 184, 185, 0, 186, 187, 188, 0, 189, 190, 191, + 192, 752, 194, 195, 196, 197, 753, 1233, 199, 0, + 200, 201, 754, 203, 0, 204, 0, 205, 0, 0, + 0, 208, 209, 210, 0, 212, 0, 213, 0, 755, + 756, 216, 0, 217, 218, 219, 220, 221, 222, 223, + 0, 225, 226, 227, 228, 0, 229, 230, 231, 232, + 233, 234, 0, 235, 0, 757, 238, 239, 240, 241, + 242, 758, 759, 0, 760, 0, 246, 0, 0, 249, + 0, 251, 252, 253, 254, 255, 0, 0, 256, 0, + 258, 0, 0, 260, 261, 262, 0, 0, 263, 264, + 265, 266, 267, 761, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 762, 0, 763, 290, 291, 292, 764, 0, + 294, 295, 0, 297, 0, 765, 299, 766, 301, 302, + 303, 0, 304, 305, 1234, 0, 306, 307, 308, 0, + 0, 309, 767, 0, 312, 0, 768, 315, 316, 317, + 318, 319, 320, 321, 322, 323, 324, 0, 325, 326, + 769, 328, 329, 770, 331, 332, 333, 0, 334, 335, + 336, 337, 338, 339, 0, 340, 341, 342, 771, 344, + 345, 346, 347, 0, 348, 349, 350, 351, 352, 353, + 354, 355, 356, 357, 358, 359, 360, 0, 361, 362, + 0, 364, 365, 366, 772, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, 378, 0, 379, 380, 381, + 382, 383, 0, 384, 773, 386, 387, 388, 0, 390, + 391, 774, 393, 0, 394, 395, 396, 397, 398, 399, + 400, 401, 402, 403, 404, 775, 406, 776, 408, 0, + 409, 410, 0, 411, 0, 413, 414, 415, 416, 417, + 0, 777, 778, 0, 0, 420, 421, 779, 423, 780, + 1235, 425, 426, 781, 428, 429, 430, 431, 432, 0, + 0, 433, 434, 435, 436, 437, 0, 0, 438, 439, + 440, 441, 442, 1125, 783, 0, 445, 0, 447, 448, + 449, 450, 0, 0, 451, 0, 0, 452, 453, 454, + 455, 456, 457, 784, 785, 786, 787, 788, 789, 790, + 791, 792, 793, 794, 469, 470, 471, 472, 0, 1308, + 0, 0, 1309, 0, 0, 1236, 1237, 1310, 1311, 1312, + 0, 0, 0, 0, 0, 0, 0, 1308, 0, 0, + 1309, 0, 0, 0, 1313, 1310, 1311, 1312, 1765, 0, + 0, 0, 1315, 0, 0, 0, 0, 0, 0, 1316, + 0, 0, 1313, 0, 0, 0, 1308, 0, 0, 1309, + 1315, 0, 0, 0, 1310, 1311, 1312, 1316, 0, 0, + 0, 0, 0, 0, 1317, 1308, 0, 0, 1309, 0, + 0, 1313, 0, 1310, 1311, 1312, 0, 0, 0, 1315, + 0, 0, 1317, 0, 0, 0, 1316, 0, 0, 0, + 1313, 0, 0, 1962, 0, 0, 0, 0, 1315, 0, + 0, 0, 0, 0, 0, 1316, 0, 0, 0, 0, + 0, 1317, 0, 0, 0, 1766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1299, 0, 1319, 1300, 0, 0, 0, - 0, 1301, 1302, 1303, 0, 0, 0, 0, 0, 0, - 0, 0, 1315, 1319, 0, 1316, 0, 0, 1304, 0, - 0, 1985, 0, 0, 0, 0, 1306, 1299, 0, 1317, - 1300, 1319, 1318, 1307, 0, 1301, 1302, 1303, 0, 0, + 1317, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1308, 0, + 0, 1309, 0, 0, 0, 0, 1310, 1311, 1312, 0, + 0, 0, 0, 0, 1318, 0, 0, 0, 0, 0, + 0, 0, 2000, 1313, 0, 0, 0, 2001, 0, 0, + 1319, 1315, 1318, 0, 0, 1320, 0, 0, 1316, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1319, 0, + 2948, 0, 0, 1320, 0, 0, 0, 1321, 1322, 0, + 0, 1318, 0, 1317, 0, 0, 0, 0, 0, 0, + 0, 1323, 0, 0, 0, 1321, 1322, 1319, 0, 0, + 1318, 0, 1320, 0, 0, 0, 0, 0, 0, 1323, + 0, 0, 0, 0, 0, 0, 1319, 0, 0, 0, + 0, 1320, 0, 0, 1321, 1322, 0, 0, 0, 1324, + 0, 0, 1325, 0, 0, 0, 0, 0, 1323, 0, + 0, 0, 0, 1321, 1322, 0, 1326, 1324, 0, 1327, + 1325, 0, 0, 0, 0, 0, 0, 1323, 0, 0, + 0, 0, 0, 0, 1326, 0, 0, 1327, 0, 0, + 0, 0, 0, 0, 0, 0, 1324, 0, 0, 1325, + 0, 0, 0, 1318, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1326, 0, 1324, 1327, 1308, 1325, 1319, + 1309, 0, 0, 0, 1320, 1310, 1311, 1312, 0, 0, + 0, 0, 1326, 0, 0, 1327, 0, 0, 0, 2949, + 0, 0, 1313, 0, 0, 2005, 1321, 1322, 0, 0, + 1315, 0, 0, 0, 0, 0, 0, 1316, 1328, 0, + 1323, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1328, 0, 0, 0, + 0, 1308, 1317, 0, 1309, 0, 0, 0, 0, 1310, + 1311, 1312, 0, 0, 0, 0, 0, 0, 1324, 0, + 0, 1325, 0, 0, 0, 1328, 1313, 0, 0, 0, + 0, 0, 0, 0, 1315, 1326, 0, 1770, 1327, 0, + 0, 1316, 0, 0, 1328, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1974, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1317, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1329, 0, + 0, 1330, 1331, 1332, 0, 1333, 1334, 1335, 1336, 1337, + 1338, 0, 0, 0, 0, 0, 1329, 0, 0, 1330, + 1331, 1332, 1318, 1333, 1334, 1335, 1336, 1337, 1338, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1319, 0, + 0, 0, 0, 1320, 0, 1329, 0, 1328, 1330, 1331, + 1332, 0, 1333, 1334, 1335, 1336, 1337, 1338, 0, 0, + 0, 0, 0, 0, 1329, 1321, 1322, 1330, 1331, 1332, + 0, 1333, 1334, 1335, 1336, 1337, 1338, 0, 0, 1323, + 0, 2010, 0, 0, 0, 0, 1318, 0, 1308, 0, + 0, 1309, 0, 0, 0, 0, 1310, 1311, 1312, 0, + 0, 0, 1319, 0, 0, 0, 0, 1320, 0, 0, + 0, 0, 0, 1313, 0, 0, 2012, 1324, 0, 0, + 1325, 1315, 0, 0, 0, 0, 0, 0, 1316, 1321, + 1322, 0, 0, 0, 1326, 0, 0, 1327, 0, 0, + 0, 0, 0, 1323, 0, 0, 0, 1329, 0, 0, + 1330, 1331, 1332, 1317, 1333, 1334, 1335, 1336, 1337, 1338, + 0, 0, 0, 1308, 0, 0, 1309, 0, 0, 0, + 0, 1310, 1311, 1312, 0, 0, 0, 0, 0, 0, + 0, 1324, 0, 0, 1325, 0, 0, 0, 1313, 0, + 0, 2272, 0, 0, 0, 0, 1315, 0, 1326, 0, + 0, 1327, 1308, 1316, 0, 1309, 0, 0, 0, 0, + 1310, 1311, 1312, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1328, 1313, 1317, 0, + 0, 0, 0, 0, 0, 1315, 0, 0, 0, 0, + 0, 0, 1316, 0, 0, 0, 0, 1308, 0, 0, + 1309, 0, 0, 1318, 0, 1310, 1311, 1312, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1317, 0, 1319, + 0, 0, 1313, 0, 1320, 0, 0, 0, 0, 0, + 1315, 0, 0, 0, 0, 0, 0, 1316, 0, 0, + 1328, 0, 0, 0, 0, 0, 1321, 1322, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1954, 0, 1304, 0, 1755, 0, 0, 0, 1308, 1319, - 1306, 0, 0, 0, 0, 0, 0, 1307, 0, 0, + 1323, 0, 1317, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1329, 0, 1318, 1330, + 1331, 1332, 0, 1333, 1334, 1335, 1336, 1337, 1338, 0, + 0, 0, 0, 0, 1319, 0, 0, 0, 1324, 1320, + 0, 1325, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1326, 0, 1318, 1327, 0, + 0, 1321, 1322, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1319, 0, 1323, 0, 0, 1320, 0, + 1329, 0, 0, 1330, 1331, 1332, 0, 1333, 1334, 1335, + 1336, 1337, 1338, 0, 0, 0, 0, 0, 0, 0, + 1321, 1322, 1318, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1324, 1323, 0, 1325, 0, 1319, 0, + 0, 0, 0, 1320, 0, 0, 0, 0, 0, 0, + 1326, 1308, 0, 1327, 1309, 0, 0, 0, 0, 1310, + 1311, 1312, 0, 0, 0, 1321, 1322, 1328, 0, 0, + 0, 0, 1324, 0, 0, 1325, 1313, 0, 0, 1323, + 0, 0, 0, 0, 1315, 0, 0, 0, 0, 1326, + 1308, 1316, 1327, 1309, 0, 0, 0, 0, 1310, 1311, + 1312, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1313, 1317, 1324, 0, 0, + 1325, 0, 0, 1315, 0, 0, 0, 0, 0, 0, + 1316, 0, 0, 0, 1326, 0, 0, 1327, 0, 0, + 0, 0, 1328, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1317, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1329, 0, 0, + 1330, 1331, 1332, 0, 1333, 1334, 1335, 1336, 1337, 1338, + 0, 1328, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1308, 0, 0, 1309, 0, 0, 0, 0, 1310, + 1311, 1312, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2230, 0, 0, 1318, 0, 0, 0, + 0, 0, 0, 0, 1315, 0, 1328, 0, 0, 0, + 0, 1316, 1319, 0, 0, 0, 0, 1320, 0, 0, + 0, 0, 1329, 0, 0, 1330, 1331, 1332, 0, 1333, + 1334, 1335, 1336, 1337, 1338, 1318, 1317, 0, 0, 1321, + 1322, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1319, 0, 1323, 0, 0, 1320, 0, 0, 0, + 0, 1329, 0, 0, 1330, 1331, 1332, 0, 1333, 1334, + 1335, 1336, 1337, 1338, 0, 0, 0, 0, 1321, 1322, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1324, 1323, 0, 1325, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1329, 0, 1326, 1330, + 1331, 1332, 0, 1333, 1334, 1335, 1336, 1337, 1338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1308, 0, 0, 1320, 0, 0, 1321, 1322, - 1323, 0, 1324, 1325, 1326, 1327, 1328, 1329, 0, 0, - 0, 0, 0, 1320, 0, 0, 1321, 1322, 1323, 1319, - 1324, 1325, 1326, 1327, 1328, 1329, 0, 0, 0, 0, - 0, 1320, 0, 0, 1321, 1322, 1323, 0, 1324, 1325, - 1326, 1327, 1328, 1329, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1309, 1320, - 0, 0, 1321, 1322, 1323, 0, 1324, 1325, 1326, 1327, - 1328, 1329, 0, 1310, 0, 0, 1299, 0, 1311, 1300, - 0, 0, 0, 0, 1301, 1302, 1303, 1990, 0, 0, - 0, 0, 1309, 0, 0, 0, 0, 0, 0, 1312, - 1313, 1304, 0, 0, 1992, 0, 0, 1310, 0, 1306, - 0, 0, 1311, 1314, 0, 0, 1307, 0, 0, 1320, - 0, 0, 1321, 1322, 1323, 0, 1324, 1325, 1326, 1327, - 1328, 1329, 0, 1312, 1313, 0, 0, 0, 0, 0, - 0, 1308, 0, 0, 0, 0, 0, 1314, 0, 0, - 0, 1315, 0, 0, 1316, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1299, 1317, 0, - 1300, 1318, 0, 0, 0, 1301, 1302, 1303, 0, 0, - 0, 0, 0, 0, 0, 1315, 0, 0, 1316, 0, - 0, 0, 1304, 0, 0, 0, 0, 0, 0, 0, - 1306, 0, 1317, 0, 0, 1318, 1299, 1307, 0, 1300, - 0, 0, 0, 0, 1301, 1302, 1303, 0, 0, 0, + 1324, 0, 0, 1325, 0, 0, 1318, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1326, 0, 0, + 1327, 0, 1319, 0, 0, 0, 0, 1320, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1304, 1308, 0, 2247, 0, 0, 0, 0, 1306, - 0, 1309, 0, 0, 0, 0, 1307, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1310, 0, 1319, 0, - 0, 1311, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1308, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1299, 1312, 1313, 1300, 0, 0, 0, 0, 1301, - 1302, 1303, 1319, 0, 0, 0, 1314, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1304, 0, 0, 0, - 0, 0, 0, 0, 1306, 0, 0, 0, 0, 0, - 1299, 1307, 0, 1300, 0, 0, 0, 0, 1301, 1302, - 1303, 0, 1309, 0, 1315, 0, 0, 1316, 0, 0, - 0, 0, 0, 0, 0, 0, 1308, 1310, 0, 0, - 0, 1317, 1311, 1306, 1318, 0, 0, 0, 1320, 0, - 1307, 1321, 1322, 1323, 0, 1324, 1325, 1326, 1327, 1328, - 1329, 1309, 0, 1312, 1313, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1308, 1310, 1314, 0, 0, - 0, 1311, 1320, 0, 0, 1321, 1322, 1323, 0, 1324, - 1325, 1326, 1327, 1328, 1329, 0, 0, 0, 0, 0, - 0, 0, 1312, 1313, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1315, 1314, 0, 1316, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1321, + 1322, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1323, 0, 0, 0, 0, 0, 0, + 1328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1319, 1317, 0, 0, 1318, 1309, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1310, 0, 0, 1315, 0, 1311, 1316, 0, 0, + 0, 1324, 0, 0, 1325, 0, 0, 0, 0, 1328, + 0, 0, 0, 0, 0, 0, 0, 0, 1326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1317, 0, 0, 1318, 1309, 0, 1312, 1313, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1310, 1314, 0, 0, 0, 1311, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1312, 1313, 0, 0, - 0, 0, 1319, 0, 0, 0, 0, 0, 0, 1315, - 1314, 1320, 1316, 0, 1321, 1322, 1323, 0, 1324, 1325, - 1326, 1327, 1328, 1329, 0, 0, 1317, 0, 0, 1318, - 0, 0, 0, 0, 2205, 0, 0, 0, 0, 0, - 0, 1319, 0, 0, 0, 0, 0, 0, 1315, 0, - 0, 1316, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1317, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1329, 0, 0, 1330, 1331, 1332, 0, 1333, 1334, 1335, + 1336, 1337, 1338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1320, 0, 0, 1321, 1322, 1323, 0, 1324, - 1325, 1326, 1327, 1328, 1329, 0, 1319, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1329, + 1328, 0, 1330, 1331, 1332, 0, 1333, 1334, 1335, 1336, + 1785, 1338, 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, 1320, 0, 0, 1321, 1322, 1323, 0, 1324, 1325, - 1326, 1327, 1328, 1329, 0, 1319, 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, 1320, 0, 0, 1321, - 1322, 1323, 0, 1324, 1325, 1326, 1327, 1328, 1329, 0, + 0, 0, 0, 0, 0, 0, 0, 1051, 0, 1674, + 1329, 0, 0, 1330, 1331, 1332, 0, 1333, 1334, 1335, + 1336, 1337, 1338, 93, 94, 95, 96, 97, 98, 99, + 100, 1052, 101, 102, 103, 1053, 1054, 1055, 1056, 1057, + 1058, 1059, 104, 105, 1060, 106, 107, 108, 0, 110, + 111, 112, 743, 744, 0, 745, 746, 1061, 118, 119, + 120, 121, 122, 123, 1062, 1063, 124, 125, 747, 748, + 128, 1064, 129, 130, 131, 132, 749, 1065, 0, 1066, + 135, 136, 137, 138, 139, 140, 0, 142, 143, 144, + 1067, 145, 146, 147, 148, 149, 150, 1068, 0, 152, + 153, 154, 1069, 1070, 1071, 0, 1072, 1073, 1074, 156, + 157, 158, 159, 160, 161, 162, 750, 751, 165, 1075, + 166, 1076, 167, 168, 169, 170, 171, 172, 1077, 173, + 174, 175, 176, 177, 1078, 1079, 178, 179, 180, 181, + 182, 1080, 183, 184, 185, 1081, 186, 187, 188, 1082, + 189, 190, 191, 192, 752, 194, 195, 196, 197, 753, + 1083, 199, 1084, 200, 201, 754, 203, 1085, 204, 1086, + 205, 0, 1087, 0, 208, 209, 210, 0, 212, 1088, + 213, 1089, 755, 756, 216, 1090, 217, 218, 219, 220, + 221, 222, 223, 0, 225, 226, 227, 228, 1091, 229, + 230, 231, 232, 233, 234, 1092, 235, 0, 757, 238, + 239, 240, 241, 242, 758, 759, 1093, 760, 1094, 246, + 0, 0, 249, 0, 251, 252, 253, 254, 255, 1095, + 1096, 256, 0, 258, 0, 1097, 260, 261, 262, 1098, + 1099, 263, 264, 265, 266, 267, 761, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 762, 0, 763, 290, 291, + 292, 764, 1100, 294, 295, 0, 297, 1101, 765, 299, + 766, 301, 302, 303, 1102, 304, 305, 1103, 1104, 306, + 307, 308, 1105, 1106, 309, 767, 0, 312, 0, 768, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 1107, 325, 326, 769, 328, 329, 770, 331, 332, 333, + 1108, 334, 335, 336, 337, 338, 339, 1109, 340, 341, + 342, 771, 344, 345, 346, 347, 1110, 348, 349, 350, + 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, + 1111, 361, 362, 0, 364, 365, 366, 772, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 1112, + 379, 380, 381, 382, 383, 1113, 384, 773, 386, 387, + 388, 0, 390, 391, 774, 393, 1114, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, 404, 775, 406, + 776, 408, 1115, 409, 410, 1116, 411, 0, 413, 414, + 415, 416, 417, 1117, 777, 778, 1118, 1119, 420, 421, + 779, 423, 780, 1120, 425, 426, 781, 428, 429, 430, + 431, 432, 1121, 1122, 433, 434, 435, 436, 437, 1123, + 1124, 438, 439, 440, 441, 442, 1125, 783, 1126, 445, + 0, 447, 448, 449, 450, 1127, 1128, 451, 1129, 1130, + 452, 453, 454, 455, 456, 457, 784, 785, 786, 787, + 788, 789, 790, 791, 792, 793, 794, 469, 470, 471, + 472, 1051, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 93, 94, 95, + 96, 97, 98, 99, 100, 1052, 101, 102, 103, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 104, 105, 1060, 106, + 107, 108, 0, 110, 111, 112, 743, 744, 0, 745, + 746, 1061, 118, 119, 120, 121, 122, 123, 1062, 1063, + 124, 125, 747, 748, 128, 1064, 129, 130, 131, 132, + 749, 1065, 0, 1066, 135, 136, 137, 138, 139, 140, + 0, 142, 143, 144, 1067, 145, 146, 147, 148, 149, + 150, 1068, 0, 152, 153, 154, 1069, 1070, 1071, 0, + 1072, 1073, 1074, 156, 157, 158, 159, 160, 161, 162, + 750, 751, 165, 1075, 166, 1076, 167, 168, 169, 170, + 171, 172, 1077, 173, 174, 175, 176, 177, 1078, 1079, + 178, 179, 180, 181, 182, 1080, 183, 184, 185, 1081, + 186, 187, 188, 1082, 189, 190, 191, 192, 752, 194, + 195, 196, 197, 753, 1083, 199, 1084, 200, 201, 754, + 203, 1085, 204, 1086, 205, 0, 1087, 0, 208, 209, + 210, 0, 212, 1088, 213, 1089, 755, 756, 216, 1090, + 217, 218, 219, 220, 221, 222, 223, 0, 225, 226, + 227, 228, 1091, 229, 230, 231, 232, 233, 234, 1092, + 235, 0, 757, 238, 239, 240, 241, 242, 758, 759, + 1093, 760, 1094, 246, 0, 0, 249, 0, 251, 252, + 253, 254, 255, 1095, 1096, 256, 0, 258, 0, 1097, + 260, 261, 262, 1098, 1099, 263, 264, 265, 266, 267, + 761, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 762, + 0, 763, 290, 291, 292, 764, 1100, 294, 295, 0, + 297, 1101, 765, 299, 766, 301, 302, 303, 1102, 304, + 305, 1103, 1104, 306, 307, 308, 1105, 1106, 309, 767, + 0, 312, 0, 768, 315, 316, 317, 318, 319, 320, + 321, 322, 323, 324, 1107, 325, 326, 769, 328, 329, + 770, 331, 332, 333, 1108, 334, 335, 336, 337, 338, + 339, 1109, 340, 341, 342, 771, 344, 345, 346, 347, + 1110, 348, 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 1111, 361, 362, 0, 364, 365, + 366, 772, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 1112, 379, 380, 381, 382, 383, 1113, + 384, 773, 386, 387, 388, 0, 390, 391, 774, 393, + 1114, 394, 395, 396, 397, 398, 399, 400, 401, 402, + 403, 404, 775, 406, 776, 408, 1115, 409, 410, 1116, + 411, 0, 413, 414, 415, 416, 417, 1117, 777, 778, + 1118, 1119, 420, 421, 779, 423, 780, 1120, 425, 426, + 781, 428, 429, 430, 431, 432, 1121, 1122, 433, 434, + 435, 436, 437, 1123, 1124, 438, 439, 440, 441, 442, + 1125, 783, 1126, 445, 0, 447, 448, 449, 450, 1127, + 1128, 451, 1129, 1130, 452, 453, 454, 455, 456, 457, + 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, + 794, 469, 470, 471, 472, 1051, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 93, 94, 95, 96, 1820, 98, 99, 100, 1052, + 101, 102, 103, 1053, 1054, 1055, 1056, 1057, 1058, 1059, + 104, 105, 1060, 106, 107, 108, 0, 110, 111, 112, + 743, 744, 0, 745, 746, 1061, 118, 119, 120, 121, + 122, 123, 1062, 1063, 124, 125, 747, 748, 128, 1064, + 129, 130, 131, 132, 749, 1065, 0, 1066, 135, 136, + 137, 138, 139, 140, 0, 142, 143, 144, 1067, 145, + 146, 147, 148, 149, 150, 1068, 0, 152, 153, 154, + 1069, 1070, 1071, 0, 1072, 1073, 1074, 156, 157, 158, + 159, 160, 161, 162, 750, 751, 165, 1075, 166, 1076, + 167, 168, 169, 170, 171, 172, 1077, 173, 174, 175, + 176, 177, 1078, 1079, 178, 179, 180, 1821, 182, 1080, + 183, 184, 185, 1081, 186, 187, 188, 1082, 189, 190, + 191, 192, 752, 194, 195, 196, 197, 753, 1083, 199, + 1084, 200, 201, 754, 203, 1085, 204, 1086, 205, 0, + 1087, 0, 208, 209, 210, 0, 212, 1088, 213, 1089, + 755, 756, 216, 1090, 217, 218, 219, 220, 221, 222, + 223, 0, 225, 226, 227, 228, 1091, 229, 230, 231, + 232, 233, 234, 1092, 235, 0, 757, 238, 239, 240, + 241, 242, 758, 759, 1093, 760, 1094, 246, 0, 0, + 249, 0, 251, 252, 253, 254, 255, 1095, 1096, 256, + 0, 258, 0, 1097, 260, 261, 262, 1098, 1099, 263, + 264, 265, 266, 267, 761, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + 284, 285, 286, 762, 0, 763, 290, 291, 292, 764, + 1100, 294, 295, 0, 297, 1101, 765, 299, 766, 301, + 302, 303, 1102, 304, 305, 1103, 1104, 306, 307, 308, + 1105, 1106, 309, 767, 0, 312, 0, 768, 315, 316, + 317, 318, 319, 320, 321, 322, 323, 324, 1107, 325, + 326, 769, 328, 329, 770, 331, 332, 333, 1108, 334, + 335, 336, 337, 338, 339, 1109, 340, 341, 342, 771, + 344, 345, 346, 347, 1110, 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 1111, 361, + 362, 0, 364, 365, 366, 772, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 1112, 379, 380, + 381, 382, 383, 1113, 1822, 773, 386, 387, 388, 0, + 390, 391, 774, 393, 1114, 394, 395, 396, 397, 398, + 399, 400, 401, 402, 403, 404, 775, 406, 776, 408, + 1115, 409, 410, 1116, 411, 0, 413, 414, 415, 416, + 417, 1117, 777, 778, 1118, 1119, 420, 421, 779, 423, + 780, 1120, 425, 426, 781, 428, 429, 430, 431, 432, + 1121, 1122, 433, 434, 435, 436, 437, 1123, 1124, 438, + 439, 440, 441, 442, 1125, 783, 1126, 445, 0, 447, + 448, 449, 450, 1127, 1128, 451, 1129, 1130, 452, 453, + 454, 455, 456, 457, 784, 785, 786, 787, 788, 789, + 790, 791, 792, 793, 794, 469, 470, 471, 472, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1043, 0, 1661, 1320, 0, 0, 1321, 1322, - 1323, 0, 1324, 1325, 1326, 1327, 1328, 1329, 92, 93, - 94, 95, 96, 97, 98, 99, 1044, 100, 101, 102, - 1045, 1046, 1047, 1048, 1049, 1050, 1051, 103, 104, 1052, - 105, 106, 107, 0, 109, 110, 111, 736, 737, 0, - 738, 739, 1053, 117, 118, 119, 120, 121, 122, 1054, - 1055, 123, 124, 740, 741, 127, 1056, 128, 129, 130, - 131, 742, 1057, 0, 1058, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 1059, 144, 145, 146, 147, - 148, 149, 1060, 0, 151, 152, 153, 1061, 1062, 1063, - 0, 1064, 1065, 1066, 155, 156, 157, 158, 159, 160, - 161, 743, 744, 164, 1067, 165, 1068, 166, 167, 168, - 169, 170, 171, 1069, 172, 173, 174, 175, 176, 1070, - 1071, 177, 178, 179, 180, 181, 1072, 182, 183, 184, - 1073, 185, 186, 187, 1074, 188, 189, 190, 191, 745, - 193, 194, 195, 196, 746, 1075, 198, 1076, 199, 200, - 747, 202, 1077, 203, 1078, 204, 0, 1079, 0, 207, - 208, 209, 0, 211, 1080, 212, 1081, 748, 749, 215, - 1082, 216, 217, 218, 219, 220, 221, 0, 223, 224, - 225, 226, 1083, 227, 228, 229, 230, 231, 232, 1084, - 233, 0, 750, 236, 237, 238, 239, 751, 752, 1085, - 753, 1086, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 1087, 1088, 253, 0, 255, 0, 1089, 257, - 258, 259, 1090, 1091, 260, 261, 262, 263, 264, 754, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 755, 0, - 756, 287, 288, 289, 757, 1092, 291, 292, 0, 294, - 1093, 758, 296, 759, 298, 299, 300, 1094, 301, 302, - 1095, 1096, 303, 304, 305, 1097, 1098, 306, 760, 0, - 309, 0, 761, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 1099, 322, 323, 762, 325, 326, 763, - 328, 329, 330, 1100, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 764, 341, 342, 343, 344, 1101, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 1102, 357, 358, 0, 360, 361, 362, 765, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 1103, 375, 376, 377, 378, 379, 1104, 380, 766, 382, - 383, 384, 0, 386, 387, 767, 389, 1105, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 768, - 402, 769, 404, 1106, 405, 406, 1107, 407, 0, 409, - 410, 411, 412, 413, 1108, 770, 771, 1109, 1110, 416, - 417, 772, 419, 773, 1111, 421, 422, 774, 424, 425, - 426, 427, 428, 1112, 1113, 429, 430, 431, 432, 433, - 1114, 1115, 434, 435, 436, 437, 438, 1116, 776, 1117, - 441, 0, 443, 444, 445, 446, 1118, 1119, 447, 1120, - 1121, 448, 449, 450, 451, 452, 453, 777, 778, 779, - 780, 781, 782, 783, 784, 785, 786, 787, 465, 466, - 467, 468, 1043, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 1044, 100, 101, 102, - 1045, 1046, 1047, 1048, 1049, 1050, 1051, 103, 104, 1052, - 105, 106, 107, 0, 109, 110, 111, 736, 737, 0, - 738, 739, 1053, 117, 118, 119, 120, 121, 122, 1054, - 1055, 123, 124, 740, 741, 127, 1056, 128, 129, 130, - 131, 742, 1057, 0, 1058, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 1059, 144, 145, 146, 147, - 148, 149, 1060, 0, 151, 152, 153, 1061, 1062, 1063, - 0, 1064, 1065, 1066, 155, 156, 157, 158, 159, 160, - 161, 743, 744, 164, 1067, 165, 1068, 166, 167, 168, - 169, 170, 171, 1069, 172, 173, 174, 175, 176, 1070, - 1071, 177, 178, 179, 180, 181, 1072, 182, 183, 184, - 1073, 185, 186, 187, 1074, 188, 189, 190, 191, 745, - 193, 194, 195, 196, 746, 1075, 198, 1076, 199, 200, - 747, 202, 1077, 203, 1078, 204, 0, 1079, 0, 207, - 208, 209, 0, 211, 1080, 212, 1081, 748, 749, 215, - 1082, 216, 217, 218, 219, 220, 221, 0, 223, 224, - 225, 226, 1083, 227, 228, 229, 230, 231, 232, 1084, - 233, 0, 750, 236, 237, 238, 239, 751, 752, 1085, - 753, 1086, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 1087, 1088, 253, 0, 255, 0, 1089, 257, - 258, 259, 1090, 1091, 260, 261, 262, 263, 264, 754, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 755, 0, - 756, 287, 288, 289, 757, 1092, 291, 292, 0, 294, - 1093, 758, 296, 759, 298, 299, 300, 1094, 301, 302, - 1095, 1096, 303, 304, 305, 1097, 1098, 306, 760, 0, - 309, 0, 761, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 1099, 322, 323, 762, 325, 326, 763, - 328, 329, 330, 1100, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 764, 341, 342, 343, 344, 1101, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 1102, 357, 358, 0, 360, 361, 362, 765, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 1103, 375, 376, 377, 378, 379, 1104, 380, 766, 382, - 383, 384, 0, 386, 387, 767, 389, 1105, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 768, - 402, 769, 404, 1106, 405, 406, 1107, 407, 0, 409, - 410, 411, 412, 413, 1108, 770, 771, 1109, 1110, 416, - 417, 772, 419, 773, 1111, 421, 422, 774, 424, 425, - 426, 427, 428, 1112, 1113, 429, 430, 431, 432, 433, - 1114, 1115, 434, 435, 436, 437, 438, 1116, 776, 1117, - 441, 0, 443, 444, 445, 446, 1118, 1119, 447, 1120, - 1121, 448, 449, 450, 451, 452, 453, 777, 778, 779, - 780, 781, 782, 783, 784, 785, 786, 787, 465, 466, - 467, 468, 1043, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 1802, 97, 98, 99, 1044, 100, 101, 102, - 1045, 1046, 1047, 1048, 1049, 1050, 1051, 103, 104, 1052, - 105, 106, 107, 0, 109, 110, 111, 736, 737, 0, - 738, 739, 1053, 117, 118, 119, 120, 121, 122, 1054, - 1055, 123, 124, 740, 741, 127, 1056, 128, 129, 130, - 131, 742, 1057, 0, 1058, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 1059, 144, 145, 146, 147, - 148, 149, 1060, 0, 151, 152, 153, 1061, 1062, 1063, - 0, 1064, 1065, 1066, 155, 156, 157, 158, 159, 160, - 161, 743, 744, 164, 1067, 165, 1068, 166, 167, 168, - 169, 170, 171, 1069, 172, 173, 174, 175, 176, 1070, - 1071, 177, 178, 179, 1803, 181, 1072, 182, 183, 184, - 1073, 185, 186, 187, 1074, 188, 189, 190, 191, 745, - 193, 194, 195, 196, 746, 1075, 198, 1076, 199, 200, - 747, 202, 1077, 203, 1078, 204, 0, 1079, 0, 207, - 208, 209, 0, 211, 1080, 212, 1081, 748, 749, 215, - 1082, 216, 217, 218, 219, 220, 221, 0, 223, 224, - 225, 226, 1083, 227, 228, 229, 230, 231, 232, 1084, - 233, 0, 750, 236, 237, 238, 239, 751, 752, 1085, - 753, 1086, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 1087, 1088, 253, 0, 255, 0, 1089, 257, - 258, 259, 1090, 1091, 260, 261, 262, 263, 264, 754, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 755, 0, - 756, 287, 288, 289, 757, 1092, 291, 292, 0, 294, - 1093, 758, 296, 759, 298, 299, 300, 1094, 301, 302, - 1095, 1096, 303, 304, 305, 1097, 1098, 306, 760, 0, - 309, 0, 761, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 1099, 322, 323, 762, 325, 326, 763, - 328, 329, 330, 1100, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 764, 341, 342, 343, 344, 1101, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 1102, 357, 358, 0, 360, 361, 362, 765, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 1103, 375, 376, 377, 378, 379, 1104, 1804, 766, 382, - 383, 384, 0, 386, 387, 767, 389, 1105, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 768, - 402, 769, 404, 1106, 405, 406, 1107, 407, 0, 409, - 410, 411, 412, 413, 1108, 770, 771, 1109, 1110, 416, - 417, 772, 419, 773, 1111, 421, 422, 774, 424, 425, - 426, 427, 428, 1112, 1113, 429, 430, 431, 432, 433, - 1114, 1115, 434, 435, 436, 437, 438, 1116, 776, 1117, - 441, 0, 443, 444, 445, 446, 1118, 1119, 447, 1120, - 1121, 448, 449, 450, 451, 452, 453, 777, 778, 779, - 780, 781, 782, 783, 784, 785, 786, 787, 465, 466, - 467, 468, 91, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 817, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 820, 0, 821, 0, 134, 135, 136, 137, 138, - 139, 140, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 150, 151, 152, 153, 822, 823, 824, - 825, 826, 827, 828, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 833, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 205, 0, 206, 207, - 208, 209, 210, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 221, 222, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 0, 0, 253, 254, 255, 256, 0, 257, - 258, 259, 841, 842, 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, 0, 291, 292, 293, 294, - 0, 847, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 308, - 309, 310, 850, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 851, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 854, 380, 381, 382, - 383, 384, 385, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 856, 404, 0, 405, 406, 0, 407, 408, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 859, 419, 860, 0, 421, 422, 862, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 863, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 442, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 91, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 133, 0, 134, 135, 136, 137, 138, - 139, 140, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 150, 151, 152, 153, 0, 0, 0, - 154, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 205, 0, 206, 207, - 208, 209, 210, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 221, 222, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 0, 0, 253, 254, 255, 256, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 265, + 0, 0, 0, 0, 0, 93, 94, 95, 96, 97, + 98, 99, 100, 0, 101, 102, 103, 0, 0, 0, + 0, 0, 0, 0, 104, 105, 0, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 0, + 118, 119, 120, 121, 122, 123, 0, 825, 124, 125, + 126, 127, 128, 0, 129, 130, 131, 132, 828, 0, + 829, 0, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 0, 145, 146, 147, 148, 149, 150, 0, + 151, 152, 153, 154, 830, 831, 832, 833, 834, 835, + 836, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 0, 166, 0, 167, 168, 169, 170, 171, 172, + 0, 173, 174, 175, 176, 177, 0, 0, 178, 179, + 180, 181, 182, 0, 183, 184, 185, 0, 186, 187, + 188, 0, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 841, 0, 199, 0, 200, 201, 202, 203, 0, + 204, 0, 205, 206, 0, 207, 208, 209, 210, 211, + 212, 0, 213, 0, 214, 215, 216, 0, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 0, 229, 230, 231, 232, 233, 234, 0, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 0, 245, + 0, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 0, 0, 256, 257, 258, 259, 0, 260, 261, + 262, 849, 850, 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, 0, 294, 295, 296, 297, 0, + 855, 299, 300, 301, 302, 303, 0, 304, 305, 0, + 0, 306, 307, 308, 0, 0, 309, 310, 311, 312, + 313, 858, 315, 316, 317, 318, 319, 320, 321, 322, + 323, 324, 0, 325, 326, 859, 328, 329, 330, 331, + 332, 333, 0, 334, 335, 336, 337, 338, 339, 0, + 340, 341, 342, 343, 344, 345, 346, 347, 0, 348, + 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, + 359, 360, 0, 361, 362, 363, 364, 365, 366, 367, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 0, 379, 380, 381, 382, 383, 862, 384, 385, + 386, 387, 388, 389, 390, 391, 392, 393, 0, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 405, 406, 864, 408, 0, 409, 410, 0, 411, 412, + 413, 414, 415, 416, 417, 0, 418, 419, 0, 0, + 420, 421, 867, 423, 868, 0, 425, 426, 870, 428, + 429, 430, 431, 432, 0, 0, 433, 434, 435, 436, + 437, 871, 0, 438, 439, 440, 441, 442, 443, 444, + 0, 445, 446, 447, 448, 449, 450, 0, 0, 451, + 0, 0, 452, 453, 454, 455, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 92, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, + 94, 95, 96, 97, 98, 99, 100, 0, 101, 102, + 103, 0, 0, 0, 0, 0, 0, 0, 104, 105, + 0, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 0, 118, 119, 120, 121, 122, 123, + 0, 0, 124, 125, 126, 127, 128, 0, 129, 130, + 131, 132, 133, 0, 134, 0, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 0, 145, 146, 147, + 148, 149, 150, 0, 151, 152, 153, 154, 0, 0, + 0, 155, 0, 0, 0, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 0, 166, 0, 167, 168, + 169, 170, 171, 172, 0, 173, 174, 175, 176, 177, + 0, 0, 178, 179, 180, 181, 182, 0, 183, 184, + 185, 0, 186, 187, 188, 0, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 0, 199, 0, 200, + 201, 202, 203, 0, 204, 0, 205, 206, 0, 207, + 208, 209, 210, 211, 212, 0, 213, 0, 214, 215, + 216, 0, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 0, 229, 230, 231, 232, 233, + 234, 0, 235, 236, 237, 238, 239, 240, 241, 242, + 243, 244, 0, 245, 0, 246, 247, 248, 249, 250, + 251, 252, 253, 254, 255, 0, 0, 256, 257, 258, + 259, 0, 260, 261, 262, 0, 0, 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, 0, 291, 292, 293, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 308, + 286, 287, 288, 289, 290, 291, 292, 293, 0, 294, + 295, 296, 297, 0, 298, 299, 300, 301, 302, 303, + 0, 304, 305, 0, 0, 306, 307, 308, 0, 0, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 385, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 0, 405, 406, 0, 407, 408, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 442, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 1416, 128, 129, 130, - 131, 132, 0, 0, 1417, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 1418, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 1419, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 1420, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 1421, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 1422, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 1416, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 1418, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 1419, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 221, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 1868, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 1421, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 1422, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 735, 0, 542, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 736, 737, 0, - 738, 739, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 740, 741, 127, 0, 128, 129, 130, - 131, 742, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 743, 744, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 745, - 193, 194, 195, 196, 746, 1224, 198, 0, 199, 200, - 747, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 748, 749, 215, - 0, 216, 217, 218, 219, 220, 221, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 750, 236, 237, 238, 239, 751, 752, 0, - 753, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 754, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 755, 0, - 756, 287, 288, 289, 757, 0, 291, 292, 0, 294, - 0, 758, 296, 759, 298, 299, 300, 0, 301, 302, - 1225, 0, 303, 304, 305, 0, 0, 306, 760, 0, - 309, 0, 761, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 762, 325, 326, 763, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 764, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 765, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 766, 382, - 383, 384, 0, 386, 387, 767, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 768, - 402, 769, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 770, 771, 0, 0, 416, - 417, 772, 419, 773, 1226, 421, 422, 774, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 1116, 776, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 777, 778, 779, - 780, 781, 782, 783, 784, 785, 786, 787, 465, 466, - 467, 468, 494, 0, 572, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 3, 4, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 221, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 572, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 221, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 573, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 572, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 616, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 573, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 735, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 3, 4, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 736, 737, 0, - 738, 739, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 740, 741, 127, 0, 128, 129, 130, - 131, 742, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 743, 744, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 745, - 193, 194, 195, 196, 746, 0, 198, 0, 199, 200, - 747, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 748, 749, 215, - 0, 216, 217, 218, 219, 220, 221, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 750, 236, 237, 238, 239, 751, 752, 0, - 753, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 754, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 755, 0, - 756, 287, 288, 289, 757, 0, 291, 292, 0, 294, - 0, 758, 296, 759, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 760, 0, - 309, 0, 761, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 762, 325, 326, 763, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 764, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 765, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 766, 382, - 383, 384, 0, 386, 387, 767, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 768, - 402, 769, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 770, 771, 0, 0, 416, - 417, 772, 419, 773, 0, 421, 422, 774, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 1116, 776, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 777, 778, 779, - 780, 781, 782, 783, 784, 785, 786, 787, 465, 466, - 467, 468, 494, 0, 572, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 1714, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 221, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 1715, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 1716, 407, 0, 409, - 1717, 411, 1718, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 1719, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 2634, 0, 0, 0, 0, 2635, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 221, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 495, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 221, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 497, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 547, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 221, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 548, 415, 0, 0, 549, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 572, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 611, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 572, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 614, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 572, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 618, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 572, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 221, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 646, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 221, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 572, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 1138, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 572, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 1140, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 572, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 1546, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 2286, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 221, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 2300, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 221, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 572, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 2431, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 221, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 559, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 221, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 560, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 561, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 562, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 563, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 221, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 582, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 636, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 723, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 726, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 729, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 221, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 561, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 563, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 1374, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 221, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 0, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 1511, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 1786, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 1798, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 1800, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 494, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 0, 109, 110, 111, 112, 113, 0, - 115, 116, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 125, 126, 127, 0, 128, 129, 130, - 131, 132, 0, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 0, 151, 152, 153, 0, 0, 0, - 0, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 179, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 0, 198, 0, 199, 200, - 201, 202, 0, 203, 0, 204, 0, 0, 0, 207, - 208, 209, 0, 211, 0, 212, 0, 213, 214, 215, - 0, 216, 217, 218, 219, 220, 221, 0, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 0, 235, 236, 237, 238, 239, 240, 241, 0, - 242, 0, 243, 0, 0, 246, 0, 248, 249, 250, - 251, 252, 0, 0, 253, 0, 255, 0, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 496, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 0, - 286, 287, 288, 289, 290, 0, 291, 292, 0, 294, - 0, 295, 296, 297, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 307, 0, - 309, 0, 311, 312, 313, 314, 315, 316, 317, 0, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 0, 339, 340, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 0, 360, 361, 362, 363, 0, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 381, 382, - 383, 384, 0, 386, 387, 388, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 498, - 402, 403, 404, 0, 405, 406, 0, 407, 0, 409, - 410, 411, 412, 413, 0, 414, 415, 0, 0, 416, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 439, 440, 0, - 441, 0, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 654, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 655, 109, 110, 111, 0, 656, 657, - 658, 659, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 660, 661, 127, 0, 128, 129, 130, - 131, 0, 0, 662, 0, 134, 135, 136, 137, 138, - 139, 663, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 664, 151, 152, 153, 0, 0, 0, - 665, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 666, 667, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 668, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 0, - 193, 194, 195, 196, 0, 0, 198, 0, 199, 200, - 669, 202, 0, 203, 0, 204, 670, 0, 671, 207, - 208, 209, 672, 211, 0, 212, 0, 0, 0, 215, - 0, 216, 217, 218, 219, 220, 673, 674, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 675, 0, 236, 237, 238, 239, 676, 677, 0, - 678, 0, 243, 679, 680, 246, 681, 248, 249, 250, - 251, 252, 0, 0, 253, 682, 255, 683, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 684, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 685, 686, - 687, 287, 288, 289, 0, 0, 291, 292, 688, 294, - 0, 0, 296, 689, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 0, 690, - 309, 691, 0, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 0, 325, 326, 0, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 692, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 693, 360, 361, 362, 694, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 695, 382, - 383, 384, 696, 386, 387, 697, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 698, - 402, 0, 404, 0, 405, 406, 0, 407, 699, 409, - 410, 411, 412, 413, 0, 700, 701, 0, 0, 416, - 417, 0, 419, 0, 0, 421, 422, 702, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 0, 703, 0, - 441, 704, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 654, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 465, 466, - 467, 468, 0, 92, 93, 94, 95, 96, 97, 98, - 99, 0, 100, 101, 102, 0, 0, 0, 0, 0, - 0, 0, 103, 104, 0, 105, 106, 107, 655, 109, - 110, 111, 0, 656, 657, 658, 659, 0, 117, 118, - 119, 120, 121, 122, 0, 0, 123, 124, 660, 661, - 127, 0, 128, 129, 130, 131, 0, 0, 662, 0, - 134, 135, 136, 137, 138, 139, 663, 141, 142, 143, - 0, 144, 145, 146, 147, 148, 149, 0, 664, 151, - 152, 153, 0, 0, 0, 665, 0, 0, 0, 155, - 156, 157, 158, 159, 160, 161, 666, 667, 164, 0, - 165, 0, 166, 167, 168, 169, 170, 171, 0, 172, - 173, 174, 175, 176, 0, 0, 177, 178, 668, 180, - 181, 0, 182, 183, 184, 0, 185, 186, 187, 0, - 188, 189, 190, 191, 0, 193, 194, 195, 196, 0, - 0, 198, 0, 199, 200, 669, 202, 0, 203, 0, - 204, 670, 0, 671, 207, 208, 209, 672, 211, 0, - 212, 0, 0, 0, 215, 0, 216, 217, 218, 219, - 220, 221, 674, 223, 224, 225, 226, 0, 227, 228, - 229, 230, 231, 232, 0, 233, 675, 0, 236, 237, - 238, 239, 676, 677, 0, 678, 0, 243, 679, 680, - 246, 681, 248, 249, 250, 251, 252, 0, 0, 253, - 682, 255, 683, 0, 257, 258, 259, 0, 0, 260, - 261, 262, 263, 264, 684, 266, 267, 268, 269, 270, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, - 281, 282, 283, 685, 686, 687, 287, 288, 289, 0, - 0, 291, 292, 688, 294, 0, 0, 296, 689, 298, - 299, 300, 0, 301, 302, 0, 0, 303, 304, 305, - 0, 0, 306, 0, 690, 309, 691, 0, 312, 313, - 314, 315, 316, 317, 318, 319, 320, 321, 0, 322, - 323, 0, 325, 326, 0, 328, 329, 330, 0, 331, - 332, 333, 334, 335, 336, 337, 338, 339, 692, 341, - 342, 343, 344, 0, 345, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 0, 357, 358, 693, - 360, 361, 362, 694, 364, 365, 366, 367, 368, 369, - 370, 371, 372, 373, 374, 0, 375, 376, 377, 378, - 379, 0, 380, 695, 382, 383, 384, 696, 386, 387, - 697, 389, 0, 390, 391, 392, 393, 394, 395, 396, - 397, 398, 399, 400, 698, 402, 0, 404, 0, 405, - 406, 0, 407, 699, 409, 410, 411, 412, 413, 0, - 700, 701, 0, 0, 416, 417, 0, 419, 0, 0, - 421, 422, 702, 424, 425, 426, 427, 428, 0, 0, - 429, 430, 431, 432, 433, 0, 0, 434, 435, 436, - 437, 438, 0, 703, 0, 441, 704, 443, 444, 445, - 446, 0, 0, 447, 0, 0, 448, 449, 450, 451, - 452, 453, 2372, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 465, 466, 467, 468, 0, 92, 93, - 94, 95, 96, 97, 98, 99, 0, 100, 101, 102, - 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, - 105, 106, 107, 2373, 109, 110, 111, 0, 656, 2374, - 658, 659, 0, 117, 118, 119, 120, 121, 122, 0, - 0, 123, 124, 660, 661, 127, 0, 128, 129, 130, - 131, 0, 0, 2375, 0, 134, 135, 136, 137, 138, - 139, 2376, 141, 142, 143, 0, 144, 145, 146, 147, - 148, 149, 0, 2377, 151, 152, 153, 0, 0, 0, - 2378, 0, 0, 0, 155, 156, 157, 158, 159, 160, - 161, 666, 667, 164, 0, 165, 0, 166, 167, 168, - 169, 170, 171, 0, 172, 173, 174, 175, 176, 0, - 0, 177, 178, 668, 180, 181, 0, 182, 183, 184, - 0, 185, 186, 187, 0, 188, 189, 190, 191, 0, - 193, 194, 195, 196, 0, 0, 198, 0, 199, 200, - 669, 202, 0, 203, 0, 204, 2379, 0, 2380, 207, - 208, 209, 2381, 211, 0, 212, 0, 0, 0, 215, - 0, 216, 217, 218, 219, 220, 221, 2382, 223, 224, - 225, 226, 0, 227, 228, 229, 230, 231, 232, 0, - 233, 2383, 0, 236, 237, 238, 239, 676, 677, 0, - 678, 0, 243, 2384, 2385, 246, 2386, 248, 249, 250, - 251, 252, 0, 0, 253, 2387, 255, 2388, 0, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 2579, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 685, 2390, - 687, 287, 288, 289, 0, 0, 291, 292, 2392, 294, - 0, 0, 296, 689, 298, 299, 300, 0, 301, 302, - 0, 0, 303, 304, 305, 0, 0, 306, 0, 2394, - 309, 2395, 0, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 0, 322, 323, 0, 325, 326, 0, - 328, 329, 330, 0, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 692, 341, 342, 343, 344, 0, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 2396, 360, 361, 362, 0, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 376, 377, 378, 379, 0, 380, 0, 382, - 383, 384, 2398, 386, 387, 697, 389, 0, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 2580, - 402, 0, 404, 0, 405, 406, 0, 407, 2400, 409, - 410, 411, 412, 413, 0, 700, 701, 0, 0, 416, - 417, 0, 419, 0, 0, 421, 422, 2401, 424, 425, - 426, 427, 428, 0, 0, 429, 430, 431, 432, 433, - 0, 0, 434, 435, 436, 437, 438, 0, 703, 0, - 441, 2402, 443, 444, 445, 446, 0, 0, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 654, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 465, 466, - 467, 468, 0, 92, 93, 94, 95, 96, 97, 98, - 99, 0, 100, 101, 102, 0, 0, 0, 0, 0, - 0, 0, 103, 104, 0, 105, 106, 107, 655, 109, - 110, 111, 0, 656, 657, 658, 659, 0, 117, 118, - 119, 120, 121, 122, 0, 0, 123, 124, 660, 661, - 127, 0, 128, 129, 130, 131, 0, 0, 662, 0, - 134, 135, 136, 137, 138, 139, 663, 141, 142, 143, - 0, 144, 145, 146, 147, 148, 149, 0, 664, 151, - 152, 153, 0, 0, 0, 665, 0, 0, 0, 155, - 156, 157, 158, 159, 160, 161, 666, 667, 164, 0, - 165, 0, 166, 167, 168, 169, 170, 171, 0, 172, - 173, 174, 175, 176, 0, 0, 177, 178, 668, 180, - 181, 0, 182, 183, 184, 0, 185, 186, 187, 0, - 188, 189, 190, 191, 0, 193, 194, 195, 196, 0, - 0, 198, 0, 199, 200, 669, 202, 0, 203, 0, - 204, 670, 0, 671, 207, 208, 209, 672, 211, 0, - 212, 0, 0, 0, 215, 0, 216, 217, 218, 219, - 220, 221, 674, 223, 224, 225, 226, 0, 227, 228, - 229, 230, 231, 232, 0, 233, 675, 0, 236, 237, - 238, 239, 676, 677, 0, 678, 0, 243, 679, 680, - 246, 681, 248, 249, 250, 251, 252, 0, 0, 253, - 682, 255, 683, 0, 257, 258, 259, 0, 0, 260, - 261, 262, 263, 264, 0, 266, 267, 268, 269, 270, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, - 281, 282, 283, 685, 686, 687, 287, 288, 289, 0, - 0, 291, 292, 688, 294, 0, 0, 296, 689, 298, - 299, 300, 0, 301, 302, 0, 0, 303, 304, 305, - 0, 0, 306, 0, 690, 309, 691, 0, 312, 313, - 314, 315, 316, 317, 318, 319, 320, 321, 0, 322, - 323, 0, 325, 326, 0, 328, 329, 330, 0, 331, - 332, 333, 334, 335, 336, 337, 338, 339, 692, 341, - 342, 343, 344, 0, 345, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 0, 357, 358, 693, - 360, 361, 362, 0, 364, 365, 366, 367, 368, 369, - 370, 371, 372, 373, 374, 0, 375, 376, 377, 378, - 379, 0, 380, 0, 382, 383, 384, 696, 386, 387, - 697, 389, 0, 390, 391, 392, 393, 394, 395, 396, - 397, 398, 399, 400, 0, 402, 0, 404, 0, 405, - 406, 0, 407, 699, 409, 410, 411, 412, 413, 0, - 700, 701, 0, 0, 416, 417, 0, 419, 0, 0, - 421, 422, 702, 424, 425, 426, 427, 428, 0, 0, - 429, 430, 431, 432, 433, 0, 0, 434, 435, 436, - 437, 438, 0, 703, 0, 441, 704, 443, 444, 445, - 446, 0, 0, 447, 0, 0, 448, 449, 450, 451, - 452, 453, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 465, 466, 467, 468 -}; - -static const yytype_int16 yycheck[] = -{ - 6, 6, 615, 488, 58, 525, 601, 558, 0, 991, - 630, 695, 6, 35, 792, 531, 622, 989, 871, 964, - 16, 0, 0, 0, 1727, 581, 724, 576, 701, 727, - 873, 1133, 0, 969, 1133, 1133, 1267, 1133, 792, 524, - 1220, 30, 1796, 1164, 522, 624, 889, 529, 16, 966, - 960, 60, 29, 615, 1030, 617, 2132, 619, 901, 1169, - 2084, 1802, 530, 1804, 2132, 2157, 2156, 60, 531, 1747, - 2042, 1620, 1621, 0, 1793, 1683, 1625, 994, 34, 2168, - 1248, 2175, 660, 661, 1296, 1297, 799, 5, 0, 5, - 5, 9, 13, 14, 0, 5, 2048, 13, 14, 88, - 536, 78, 0, 58, 1349, 58, 5, 50, 2443, 687, - 1395, 5, 9, 5, 13, 14, 5, 1666, 1667, 5, - 1397, 13, 14, 5, 13, 14, 5, 67, 0, 1134, - 9, 13, 14, 168, 5, 11, 5, 5, 2440, 598, - 5, 5, 73, 1994, 16, 5, 1865, 598, 107, 1723, - 5, 5, 5, 635, 11, 909, 5, 29, 58, 40, - 40, 169, 75, 35, 1738, 41, 117, 4, 3, 4, - 5, 58, 9, 86, 9, 731, 2426, 9, 5, 2492, - 212, 93, 27, 11, 120, 858, 48, 93, 60, 34, - 1262, 3, 8, 83, 2583, 93, 15, 73, 145, 238, - 16, 17, 18, 2073, 4, 11, 78, 2614, 168, 9, - 2047, 1930, 1931, 41, 1982, 2528, 2713, 2514, 303, 31, - 32, 122, 58, 2359, 978, 165, 137, 981, 982, 1262, - 107, 75, 279, 2675, 196, 41, 303, 127, 267, 145, - 818, 819, 86, 20, 370, 73, 27, 120, 27, 287, - 287, 218, 158, 349, 27, 34, 270, 163, 11, 162, - 2781, 34, 168, 210, 169, 2600, 844, 73, 27, 2411, - 206, 177, 448, 11, 1262, 181, 792, 37, 117, 2537, - 115, 340, 798, 350, 11, 432, 1269, 432, 15, 1002, - 160, 115, 478, 977, 115, 22, 1009, 264, 396, 158, - 2558, 2614, 117, 169, 210, 491, 33, 34, 401, 368, - 403, 173, 2809, 869, 2103, 354, 11, 493, 2290, 118, - 59, 2397, 2294, 229, 410, 874, 188, 795, 67, 2281, - 4, 193, 130, 431, 118, 9, 202, 916, 13, 14, - 287, 2869, 489, 2435, 489, 1953, 41, 2437, 2102, 130, - 68, 217, 222, 902, 2651, 167, 323, 169, 281, 86, - 226, 375, 120, 489, 124, 186, 228, 2888, 454, 281, - 229, 130, 278, 108, 314, 281, 211, 135, 73, 928, - 2099, 287, 2101, 281, 106, 200, 341, 264, 341, 428, - 189, 2180, 354, 489, 299, 911, 912, 232, 2840, 484, - 362, 430, 1385, 959, 371, 189, 309, 2935, 298, 2906, - 2712, 931, 1961, 1962, 1963, 1964, 2552, 484, 1967, 1968, - 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 264, 2742, - 342, 1144, 271, 1262, 5, 397, 342, 2695, 397, 2581, - 1035, 341, 489, 2280, 342, 266, 2214, 271, 408, 264, - 489, 266, 1683, 168, 341, 493, 493, 2327, 493, 2709, - 2867, 493, 2851, 430, 1536, 2778, 2040, 283, 2042, 374, - 2019, 2020, 1417, 292, 147, 1760, 2811, 424, 276, 345, - 2199, 489, 444, 434, 1761, 425, 478, 93, 163, 925, - 23, 397, 1497, 232, 430, 408, 29, 1473, 957, 478, - 478, 478, 1535, 2592, 1749, 341, 957, 2583, 2810, 531, - 478, 373, 402, 394, 394, 2583, 522, 1729, 424, 108, - 1502, 194, 244, 1143, 1755, 531, 432, 2824, 1134, 2501, - 252, 432, 368, 378, 2506, 531, 447, 2509, 493, 451, - 493, 2493, 448, 453, 450, 451, 489, 601, 1536, 1537, - 1538, 557, 558, 451, 2867, 313, 487, 430, 385, 386, - 491, 570, 530, 489, 408, 475, 489, 453, 489, 1737, - 441, 489, 487, 489, 489, 581, 491, 570, 490, 489, - 492, 487, 2336, 579, 490, 491, 492, 1165, 1166, 475, - 489, 488, 490, 493, 492, 489, 1572, 489, 590, 378, - 489, 1157, 135, 489, 593, 378, 478, 489, 2349, 485, - 489, 590, 590, 590, 620, 621, 622, 2468, 489, 2711, - 489, 489, 590, 2717, 489, 489, 582, 2716, 485, 489, - 442, 1344, 1238, 160, 489, 489, 489, 1620, 1621, 0, - 489, 238, 1625, 480, 481, 480, 481, 2325, 480, 481, - 453, 451, 480, 481, 482, 483, 484, 485, 530, 531, - 476, 477, 478, 590, 480, 481, 482, 483, 484, 485, - 492, 478, 475, 1252, 2646, 475, 482, 483, 484, 485, - 480, 481, 489, 1666, 1667, 1163, 489, 1867, 27, 695, - 327, 115, 1446, 408, 1214, 1251, 11, 1253, 570, 1305, - 1178, 1257, 1456, 218, 23, 1459, 1222, 1536, 1537, 2428, - 29, 451, 1291, 1292, 1270, 1271, 2290, 1273, 590, 493, - 2294, 2329, 1953, 322, 2816, 731, 1211, 1212, 442, 482, - 483, 484, 485, 1218, 1283, 475, 263, 1293, 489, 78, - 522, 1347, 480, 481, 482, 483, 484, 485, 87, 264, - 30, 350, 285, 1221, 130, 361, 238, 1336, 73, 1222, - 397, 487, 539, 478, 541, 491, 158, 1346, 174, 1348, - 497, 2861, 23, 23, 54, 2851, 491, 116, 29, 1557, - 156, 1891, 337, 2851, 561, 2539, 792, 1897, 196, 23, - 2002, 397, 798, 799, 800, 29, 1649, 1955, 490, 526, - 361, 493, 335, 1557, 1647, 130, 339, 444, 453, 8, - 816, 245, 11, 250, 251, 238, 135, 16, 17, 18, - 1518, 1731, 1300, 1308, 444, 1983, 232, 795, 1434, 1442, - 475, 428, 438, 1718, 1719, 368, 397, 229, 1820, 845, - 75, 1539, 2934, 1541, 78, 451, 1544, 186, 870, 158, - 413, 86, 266, 1415, 163, 582, 371, 271, 197, 865, - 866, 867, 23, 869, 870, 2889, 2890, 1843, 29, 475, - 294, 149, 354, 357, 1469, 1470, 1471, 438, 238, 2844, - 1442, 2846, 484, 489, 135, 135, 278, 893, 489, 491, - 23, 1497, 489, 158, 2015, 271, 29, 23, 163, 1461, - 276, 2132, 435, 29, 1466, 911, 912, 321, 1751, 489, - 238, 1828, 2461, 695, 2938, 430, 238, 484, 2492, 75, - 229, 358, 359, 795, 491, 472, 2680, 2501, 489, 361, - 86, 354, 2506, 942, 943, 2509, 945, 361, 944, 453, - 1876, 266, 948, 949, 2685, 1881, 428, 936, 1426, 942, - 943, 276, 945, 959, 2528, 2920, 130, 4, 4, 1515, - 832, 475, 9, 9, 229, 397, 285, 1452, 401, 278, - 403, 977, 1457, 397, 135, 489, 327, 67, 1961, 1962, - 1963, 1964, 156, 216, 1967, 1968, 1969, 1970, 1971, 1972, - 1973, 1974, 1975, 1976, 354, 401, 1002, 403, 870, 31, - 32, 2550, 135, 1009, 993, 428, 438, 489, 1490, 135, - 491, 362, 2192, 278, 438, 792, 335, 281, 800, 451, - 339, 798, 428, 4, 1030, 115, 354, 451, 9, 493, - 472, 495, 354, 667, 285, 285, 2019, 2020, 487, 415, - 2614, 1557, 491, 475, 5, 384, 397, 8, 387, 368, - 426, 475, 1530, 14, 1570, 689, 2158, 489, 167, 2158, - 2158, 93, 2158, 24, 493, 489, 489, 28, 428, 2618, - 942, 943, 2646, 945, 2777, 327, 64, 65, 1634, 1635, - 1636, 1637, 172, 361, 283, 451, 720, 453, 339, 339, - 340, 490, 266, 444, 493, 482, 1574, 271, 2329, 876, - 428, 1799, 276, 1801, 490, 23, 428, 493, 885, 489, - 362, 29, 149, 13, 14, 1671, 435, 368, 368, 397, - 490, 898, 1642, 493, 285, 490, 94, 909, 1134, 489, - 1725, 2113, 909, 1562, 911, 912, 2257, 1566, 1144, 1568, - 2112, 559, 560, 1921, 562, 397, 2031, 2032, 2033, 2034, - 490, 1157, 285, 493, 401, 2100, 403, 1163, 1164, 285, - 438, 489, 401, 490, 403, 2868, 493, 489, 2742, 595, - 2924, 597, 1178, 451, 335, 2111, 266, 2113, 339, 2151, - 2295, 271, 2297, 487, 435, 489, 2299, 491, 2891, 2302, - 490, 1634, 444, 1636, 1637, 977, 830, 475, 13, 14, - 212, 169, 335, 930, 2778, 490, 339, 368, 493, 335, - 168, 489, 54, 339, 848, 174, 1222, 135, 490, 13, - 14, 493, 1895, 1896, 314, 216, 1222, 489, 2071, 472, - 522, 150, 1238, 490, 202, 368, 493, 196, 335, 329, - 1860, 415, 368, 2946, 150, 1251, 150, 1253, 150, 217, - 1256, 1257, 426, 1221, 522, 266, 1248, 489, 226, 490, - 1266, 491, 1268, 1269, 1270, 1271, 1272, 1273, 1274, 1248, - 1248, 1248, 490, 232, 435, 493, 36, 476, 477, 478, - 1248, 480, 481, 482, 483, 484, 485, 1293, 489, 1295, - 444, 294, 260, 2867, 1300, 1301, 1302, 1303, 1304, 1305, - 13, 14, 435, 1309, 1310, 13, 14, 490, 1314, 435, - 493, 490, 1318, 1919, 493, 1321, 1322, 1323, 1324, 1325, - 1326, 1327, 1328, 1329, 361, 490, 1332, 286, 493, 361, - 490, 1337, 82, 493, 1340, 425, 1342, 490, 1344, 455, - 493, 1347, 432, 2464, 490, 490, 441, 493, 493, 1221, - 490, 490, 2583, 493, 493, 310, 490, 94, 361, 493, - 397, 1367, 150, 490, 489, 397, 493, 285, 1364, 490, - 490, 489, 493, 493, 184, 185, 1248, 345, 2132, 1385, - 35, 1163, 1164, 2365, 490, 13, 14, 493, 1394, 1395, - 490, 489, 2337, 493, 397, 1372, 1178, 1875, 150, 490, - 489, 438, 493, 695, 490, 1921, 438, 493, 490, 489, - 442, 493, 0, 490, 451, 150, 493, 335, 1997, 451, - 1426, 339, 490, 13, 14, 493, 1432, 695, 1434, 1914, - 13, 14, 169, 2286, 1990, 438, 13, 14, 475, 1311, - 250, 251, 401, 475, 403, 150, 490, 2300, 451, 493, - 368, 490, 489, 281, 493, 490, 490, 489, 493, 493, - 490, 13, 14, 493, 1942, 202, 425, 1473, 397, 428, - 1476, 1477, 475, 1479, 490, 36, 490, 493, 2461, 493, - 217, 490, 1960, 489, 493, 1262, 489, 489, 1215, 226, - 1217, 1497, 490, 2191, 522, 493, 490, 227, 2619, 493, - 1372, 2080, 487, 2052, 1510, 93, 5, 1985, 800, 1515, - 490, 5, 490, 493, 1992, 493, 490, 435, 1300, 493, - 13, 14, 489, 260, 1530, 2131, 489, 2133, 490, 1506, - 490, 493, 800, 493, 490, 36, 490, 493, 490, 493, - 490, 493, 490, 493, 281, 493, 163, 490, 358, 359, - 493, 1557, 2147, 489, 55, 490, 145, 145, 493, 490, - 13, 14, 493, 489, 1570, 489, 1572, 2550, 1574, 158, - 158, 13, 14, 1579, 163, 163, 489, 1354, 1584, 489, - 168, 13, 14, 13, 14, 13, 14, 13, 14, 177, - 13, 14, 489, 181, 13, 14, 13, 14, 13, 14, - 1622, 5, 2356, 13, 14, 106, 13, 14, 345, 349, - 350, 349, 350, 5, 1620, 1621, 1622, 2589, 489, 1625, - 2851, 210, 210, 254, 255, 358, 359, 489, 1634, 1635, - 1636, 1637, 349, 350, 1506, 2618, 911, 912, 1644, 489, - 229, 229, 1648, 489, 1426, 1651, 349, 350, 489, 1671, - 489, 5, 489, 5, 2132, 489, 489, 489, 489, 146, - 1666, 1667, 9, 489, 15, 1671, 452, 695, 212, 493, - 2368, 2369, 97, 36, 368, 163, 278, 2455, 163, 1685, - 276, 227, 1688, 489, 1690, 977, 408, 489, 86, 278, - 278, 1418, 493, 281, 195, 432, 408, 54, 287, 287, - 257, 1428, 408, 1430, 54, 1711, 1433, 408, 490, 977, - 2188, 498, 1439, 2397, 1441, 408, 150, 1723, 1723, 451, - 1742, 93, 491, 266, 142, 266, 1453, 2306, 489, 1723, - 36, 1458, 1738, 1738, 36, 1462, 1463, 1464, 1465, 35, - 1467, 1468, 2321, 244, 1738, 1737, 1752, 3, 1530, 5, - 1622, 252, 9, 489, 342, 406, 406, 447, 1737, 1737, - 1737, 1767, 487, 264, 487, 2316, 408, 408, 408, 1737, - 408, 489, 800, 493, 11, 337, 406, 493, 488, 1785, - 1557, 271, 493, 498, 1561, 489, 408, 489, 177, 159, - 168, 490, 1574, 1570, 295, 6, 1802, 1803, 1804, 1671, - 11, 489, 36, 432, 15, 210, 493, 371, 282, 397, - 21, 22, 23, 493, 489, 26, 218, 1689, 29, 30, - 266, 218, 33, 34, 218, 287, 490, 319, 279, 2583, - 444, 489, 489, 1705, 150, 424, 424, 1843, 150, 340, - 281, 451, 266, 490, 432, 472, 472, 490, 487, 36, - 281, 1723, 266, 109, 110, 490, 490, 490, 36, 168, - 448, 362, 450, 451, 488, 1737, 1738, 78, 491, 1875, - 1742, 1163, 1164, 168, 85, 86, 87, 88, 89, 408, - 472, 382, 490, 490, 490, 490, 1178, 490, 489, 2367, - 490, 490, 490, 490, 489, 1163, 1164, 490, 489, 487, - 291, 448, 490, 491, 492, 489, 448, 438, 281, 478, - 1178, 522, 430, 1919, 474, 1921, 282, 282, 282, 493, - 237, 266, 408, 2905, 489, 150, 285, 196, 184, 185, - 150, 150, 408, 1939, 490, 408, 1942, 408, 408, 2455, - 1917, 490, 1948, 488, 279, 1951, 451, 281, 1954, 977, - 490, 489, 36, 490, 1960, 1961, 1962, 1963, 1964, 493, - 150, 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, - 1976, 488, 1994, 2027, 1980, 1981, 488, 150, 271, 1985, - 141, 11, 168, 163, 1990, 168, 1992, 490, 1994, 490, - 246, 247, 248, 249, 250, 251, 448, 2003, 254, 255, - 2006, 490, 2008, 2025, 397, 168, 490, 489, 1300, 2015, - 2016, 490, 493, 2019, 2020, 475, 342, 177, 2024, 2025, - 2042, 490, 490, 490, 437, 84, 489, 282, 150, 172, - 489, 1808, 1300, 2628, 2040, 2040, 2042, 2042, 419, 489, - 36, 490, 489, 79, 432, 1917, 2040, 2053, 2042, 493, - 488, 490, 168, 493, 489, 399, 489, 2063, 217, 36, - 290, 490, 67, 2548, 217, 288, 54, 489, 73, 490, - 490, 181, 478, 2079, 1851, 2681, 2696, 489, 55, 490, - 451, 86, 187, 198, 695, 408, 271, 1864, 491, 271, - 491, 491, 491, 1875, 408, 36, 491, 2851, 50, 478, - 36, 491, 358, 359, 491, 2583, 491, 491, 491, 491, - 115, 491, 117, 2633, 55, 491, 491, 491, 266, 281, - 489, 2127, 1994, 491, 949, 2131, 2132, 2133, 490, 106, - 491, 2651, 107, 491, 1426, 1163, 1164, 490, 85, 36, - 87, 451, 89, 95, 1921, 491, 168, 489, 491, 1926, - 1178, 1928, 1879, 2025, 491, 1932, 1933, 217, 1426, 491, - 1942, 491, 491, 491, 2784, 106, 491, 172, 2040, 121, - 2042, 491, 2650, 491, 489, 2653, 300, 450, 1960, 86, - 131, 489, 2188, 2739, 489, 329, 490, 139, 489, 800, - 489, 143, 218, 81, 115, 200, 36, 150, 73, 2205, - 122, 150, 2179, 1985, 36, 490, 54, 2763, 350, 2765, - 1992, 350, 164, 469, 470, 167, 36, 2702, 195, 493, - 432, 489, 489, 489, 489, 489, 73, 437, 36, 186, - 182, 172, 432, 2015, 67, 2755, 284, 67, 1530, 489, - 419, 489, 493, 2856, 2850, 2251, 2252, 23, 36, 352, - 2256, 2257, 522, 29, 195, 2261, 368, 478, 2264, 2265, - 36, 266, 1530, 2269, 271, 489, 271, 244, 479, 186, - 242, 36, 1300, 419, 485, 252, 489, 488, 284, 55, - 284, 492, 1574, 489, 2290, 2290, 497, 264, 2294, 2294, - 264, 490, 490, 489, 2779, 281, 2290, 349, 9, 336, - 2294, 281, 198, 244, 33, 281, 1574, 2179, 489, 314, - 2316, 252, 430, 524, 525, 526, 490, 120, 295, 271, - 9, 22, 490, 264, 329, 2114, 1440, 279, 590, 1797, - 106, 2127, 2320, 2077, 2778, 2524, 2847, 2361, 2164, 2853, - 2927, 2318, 2319, 2349, 2688, 2904, 557, 558, 559, 560, - 2132, 562, 2358, 2892, 295, 2132, 2602, 1803, 2169, 135, - 964, 2367, 573, 340, 1791, 1853, 977, 2850, 2095, 321, - 2902, 582, 1788, 2851, 2131, 2848, 1211, 2154, 1163, 1857, - 1919, 2455, 593, 2154, 903, 362, 1411, 2752, 1752, 952, - 2668, 2397, 2119, 951, 605, 930, 2838, 2057, 1426, 340, - 1767, 1385, 2833, 2767, 2312, 382, 2188, 2134, 2135, 2136, - 2137, 2138, 2139, 2140, 2141, 2142, 2143, 1410, 2290, 195, - 425, 362, 2294, 2042, 954, 695, 1738, 432, 2647, 2281, - 641, 642, 643, 2296, 2742, 2040, 2741, 2759, 2520, 2760, - 1262, 382, 1262, 1262, 1269, 1262, 2318, 2319, 2836, 2455, - 2837, 2820, 1338, 1649, 1755, 2461, 1253, 1580, 2464, 1479, - 1689, 2438, 2468, 1686, 1342, 1726, 2056, 1861, 244, 2734, - 2476, 2477, 1364, 1222, 2480, 2257, 252, 1570, 936, -1, - 2078, 1365, -1, -1, -1, -1, 2492, 2492, 264, -1, - -1, -1, -1, -1, -1, 2501, 2501, -1, 2492, -1, - 2506, 2506, 1530, 2509, 2509, -1, -1, 2501, -1, 285, - 2516, 2517, 2506, -1, -1, 2509, -1, -1, -1, 295, - -1, -1, 2528, 2528, 2530, -1, -1, -1, -1, -1, - 800, -1, 479, 2310, 2528, -1, 2313, -1, -1, -1, - -1, -1, -1, -1, 2550, 492, 1574, -1, -1, -1, - -1, -1, 1163, 1164, -1, -1, -1, -1, -1, 335, - 1385, 170, -1, 339, 340, 174, 2438, 1178, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 2583, -1, -1, - -1, -1, -1, 1875, -1, 2367, 362, 196, -1, -1, - -1, -1, 368, 804, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 382, 1875, 2614, 2614, - -1, -1, 2618, 2619, -1, 2397, 2593, -1, -1, -1, - 2614, -1, -1, 232, -1, -1, 573, -1, -1, 2501, - 239, -1, -1, -1, 2506, 2657, 2642, 2509, 2615, -1, - 2646, 2646, -1, -1, 2650, -1, -1, 2653, -1, -1, - 1942, 2657, 2646, -1, -1, -1, -1, 2434, 605, 435, - 871, -1, -1, -1, -1, 2671, -1, -1, 1960, -1, - -1, -1, -1, -1, 1942, 2681, -1, 286, 2455, 2685, - 2686, -1, 2464, -1, -1, -1, -1, -1, -1, 1300, - -1, 145, 1960, 1985, 641, 642, 643, -1, -1, -1, - 1992, -1, 913, -1, 158, -1, -1, 977, -1, 163, - -1, -1, -1, -1, -1, 522, -1, 1985, -1, 930, - 931, 2593, -1, 2015, 1992, 936, 937, 938, -1, -1, - -1, -1, -1, 2739, -1, -1, 2742, 2742, 2715, -1, - -1, -1, -1, 2615, -1, 354, -1, 2015, 2742, -1, - -1, -1, 963, 964, -1, -1, 210, 2763, -1, 2765, - -1, 2767, -1, -1, -1, 976, -1, -1, -1, -1, - -1, -1, 2778, 2778, 2646, 229, -1, -1, -1, -1, - -1, -1, 993, -1, 2778, 2657, 997, -1, -1, -1, - -1, -1, 401, 2799, 403, 1620, 1621, 2774, -1, -1, - 1625, 2583, -1, -1, -1, -1, 2583, -1, -1, -1, - 419, -1, -1, 2819, 2820, 1426, 425, -1, -1, 428, - -1, -1, 2549, -1, 278, -1, -1, 2833, -1, -1, - -1, -1, -1, 287, 0, -1, -1, 2619, -1, -1, - 2132, 1666, 1667, 2715, 2850, 2851, -1, 1875, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 2584, 2585, -1, - -1, 2867, 2867, 2869, 2132, -1, -1, -1, 2650, -1, - -1, 2653, 2599, 2867, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 2860, -1, -1, -1, -1, 695, -1, - -1, -1, -1, 1163, 1164, -1, 2188, -1, -1, -1, - -1, -1, 2774, -1, -1, -1, -1, -1, 1178, -1, - -1, -1, -1, -1, 1942, -1, -1, -1, 1129, 1530, - 2188, -1, -1, -1, -1, -1, 1137, 93, -1, 2935, - -1, -1, 1960, 2710, -1, -1, 1147, -1, -1, -1, - -1, -1, -1, 2670, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 1985, -1, -1, - -1, -1, -1, 1574, 1992, 2257, 913, -1, -1, 1180, - 424, 2698, -1, 8, -1, -1, 11, -1, -1, 145, - -1, 16, 17, 18, -1, -1, -1, 2015, 2860, 2257, - 937, -1, 158, 800, -1, -1, -1, 163, 33, -1, - 1211, 1212, 168, 1214, 1215, -1, 1217, 1218, -1, 1220, - -1, 177, -1, -1, -1, 181, 963, -1, -1, -1, - -1, -1, -1, -1, 8, -1, -1, 11, -1, 976, - 1300, -1, -1, 487, -1, -1, 490, 491, -1, -1, - -1, -1, -1, -1, 210, -1, -1, -1, -1, -1, - 997, -1, -1, -1, -1, -1, 1267, 41, -1, -1, - -1, -1, -1, 229, 48, -1, -1, 1278, -1, 2851, - -1, -1, -1, -1, 2851, 2367, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 73, - -1, -1, -1, -1, -1, -1, -1, 1308, -1, 2367, - -1, -1, -1, -1, 2132, 2397, -1, -1, -1, -1, - -1, -1, 278, -1, -1, 281, -1, -1, -1, -1, - -1, 287, -1, -1, -1, -1, -1, -1, -1, 2397, - 1341, 1342, -1, -1, -1, -1, 1961, 1962, 1963, 1964, - -1, -1, 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, - 1975, 1976, 1363, -1, 1365, -1, 1426, -1, 8, 143, - 2188, 11, -1, 1374, -1, 1376, 16, 17, 18, -1, - 977, -1, 2464, -1, -1, -1, 342, -1, -1, 214, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 173, - 1137, 41, -1, -1, 2019, 2020, 2464, 1408, 48, -1, - -1, -1, -1, -1, 188, -1, 1417, 1418, -1, 193, - -1, -1, -1, -1, -1, -1, -1, 1428, 1429, 1430, - 1431, -1, 1433, 73, -1, -1, -1, -1, 1439, 2257, - 1441, 397, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 1452, 1453, -1, 228, -1, 1457, 1458, 283, -1, - -1, 1462, 1463, 1464, 1465, -1, 1467, 1468, 424, -1, - 1530, -1, -1, -1, 1875, -1, 432, -1, -1, -1, - -1, -1, -1, 1220, -1, -1, 1487, 1488, 1489, -1, - -1, -1, 448, -1, 450, 451, -1, -1, -1, -1, - -1, 2583, -1, 1504, -1, -1, -1, -1, -1, 283, - -1, -1, -1, 8, 1574, -1, 11, -1, -1, -1, - -1, 16, 17, 18, -1, 2583, -1, -1, -1, -1, - -1, 487, -1, 173, 490, 491, 492, 2619, -1, -1, - -1, 1942, -1, -1, -1, -1, -1, 8, 188, 2367, - 11, -1, -1, 193, -1, 16, 17, 18, -1, 1960, - -1, 2619, -1, -1, -1, -1, 1163, 1164, 2650, -1, - -1, 2653, 33, -1, 214, 215, -1, -1, -1, 2397, - 41, 1178, -1, -1, 1985, -1, -1, 48, 228, -1, - -1, 1992, 2650, -1, -1, 2653, -1, -1, -1, 373, - -1, -1, -1, -1, 1341, -1, -1, -1, -1, -1, - -1, -1, 73, 8, 2015, -1, 11, -1, -1, -1, - -1, 16, 17, 18, -1, -1, 1363, -1, 1365, 269, - -1, -1, -1, -1, -1, -1, -1, -1, 33, -1, - -1, 1642, -1, 283, -1, -1, 2464, -1, 1649, -1, - -1, 476, 477, 478, -1, 480, 481, 482, 483, 484, - 485, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 1408, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 1683, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 193, 473, - -1, -1, -1, 1300, -1, -1, 480, 481, 482, 483, - 484, 485, 173, -1, -1, 1716, -1, -1, -1, 214, - -1, -1, 1723, -1, -1, -1, -1, 188, -1, -1, - -1, 2132, 193, 373, -1, -1, -1, 1738, -1, 8, - -1, 1742, 11, -1, 1745, -1, 1747, 16, 17, 18, - 1487, 1488, -1, 214, 215, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 33, 2583, -1, 228, 8, 2851, - -1, 11, 41, -1, -1, -1, 16, 17, 18, 48, - -1, -1, -1, -1, -1, -1, 8, 2188, 283, 11, - -1, -1, 1793, 2851, 16, 17, 18, -1, -1, -1, - -1, 2619, -1, -1, 73, 266, -1, -1, 269, -1, - -1, 33, -1, -1, -1, 1875, -1, -1, -1, 214, - -1, -1, 283, -1, -1, 286, -1, -1, -1, 1426, - -1, -1, 2650, 473, -1, 2653, 476, 477, 478, -1, - 480, 481, 482, 483, 484, 485, 2461, -1, -1, -1, - -1, -1, 1853, -1, -1, -1, 2257, 1858, -1, -1, - -1, -1, -1, -1, 1865, 1866, 1867, 1868, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 1879, -1, - -1, -1, 1942, -1, -1, 1886, -1, -1, 283, -1, - -1, -1, -1, -1, -1, -1, -1, 1898, -1, -1, - 1960, -1, -1, -1, 173, -1, -1, -1, -1, -1, - -1, -1, 373, 1914, -1, -1, -1, -1, -1, 188, - -1, -1, -1, -1, 193, 1985, -1, -1, -1, 1930, - 1931, -1, 1992, 1530, -1, 2550, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 214, 215, -1, -1, -1, - -1, -1, 1953, -1, -1, 2015, -1, -1, -1, 228, - -1, -1, -1, -1, -1, -1, 2367, -1, -1, -1, - -1, -1, -1, -1, 214, -1, -1, 1574, -1, 1716, - -1, 476, 477, 478, -1, 480, 481, 482, 483, 484, - 485, -1, 214, -1, -1, -1, 2397, 266, -1, -1, - 269, -1, -1, 2618, -1, -1, -1, -1, -1, -1, - -1, -1, 473, -1, 283, 476, 477, 478, -1, 480, - 481, 482, 483, 484, 485, -1, -1, -1, 2029, -1, - -1, -1, 493, 2851, -1, -1, 2037, 2038, 2039, 2040, - -1, 2042, 2043, 283, -1, -1, 2047, 2048, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 283, -1, 2464, -1, -1, -1, -1, -1, -1, - -1, -1, 2132, -1, -1, -1, 2077, -1, -1, -1, - -1, 476, 477, 478, -1, 480, 481, 482, 483, 484, - 485, -1, 2093, -1, 2095, -1, -1, -1, 2099, 2100, - 2101, -1, 2103, 8, 373, -1, 11, -1, -1, -1, - -1, 16, 17, 18, -1, -1, -1, -1, 2119, -1, - 2121, 1858, -1, -1, -1, -1, -1, -1, 2188, 1866, - 1867, 1868, -1, 2134, 2135, 2136, 2137, 2138, 2139, 2140, - 2141, 2142, 2143, -1, -1, -1, -1, -1, -1, 1886, - -1, -1, -1, -1, -1, 2156, -1, -1, 2159, -1, - -1, -1, -1, -1, -1, -1, 557, 558, 2169, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 2180, - -1, -1, 2583, -1, -1, -1, -1, -1, -1, -1, - -1, 2192, -1, -1, -1, -1, -1, 2257, 2199, -1, - -1, -1, -1, -1, 473, -1, -1, 476, 477, 478, - -1, 480, 481, 482, 483, 484, 485, -1, 2619, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 620, - 621, 8, -1, -1, 11, -1, 476, 477, 478, -1, - 480, 481, 482, 483, 484, 485, 2247, -1, -1, 2650, - -1, -1, 2653, -1, 476, 477, 478, -1, 480, 481, - 482, 483, 484, 485, 41, -1, -1, -1, -1, 2270, - -1, 48, 2273, 2274, 2275, 2276, -1, -1, 1875, 2280, - 2281, -1, 2283, -1, -1, 2286, -1, -1, -1, 2290, - -1, -1, -1, 2294, 0, -1, 73, -1, -1, 2300, - 2037, 2038, 2039, -1, -1, -1, -1, 2367, -1, 214, - -1, -1, -1, 19, -1, 2316, -1, -1, -1, 2320, - -1, -1, -1, 29, 2325, 31, 32, -1, 2329, -1, - -1, -1, -1, -1, -1, -1, 2337, 2397, -1, -1, - -1, 47, -1, -1, -1, 1942, -1, -1, -1, -1, - 56, -1, -1, -1, -1, -1, 2093, -1, -1, -1, - -1, 2362, 68, 1960, -1, -1, 143, -1, -1, -1, - -1, -1, -1, 79, -1, -1, -1, 792, 283, -1, - -1, -1, -1, 798, -1, 91, -1, 93, 1985, -1, - -1, -1, -1, -1, -1, 1992, 173, -1, -1, -1, - -1, -1, -1, -1, 2464, 111, -1, -1, 799, -1, - -1, 188, -1, -1, -1, -1, 193, -1, 2015, 125, - -1, -1, 2159, -1, -1, 816, -1, 2428, -1, 135, - -1, -1, -1, -1, -1, 141, 2437, -1, -1, -1, - -1, -1, -1, 149, -1, 151, 152, 2448, -1, -1, - 2851, 228, -1, -1, 845, 2192, -1, -1, 164, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 885, -1, -1, -1, 865, 866, 867, -1, -1, 870, - -1, -1, -1, -1, -1, -1, 192, -1, -1, -1, - -1, 2492, 2493, -1, 909, 2496, 911, 912, 2499, -1, - 2501, -1, 893, -1, -1, 2506, 283, -1, 2509, -1, - 2511, -1, -1, 2514, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 2583, -1, 231, -1, 2528, -1, -1, - -1, -1, -1, -1, -1, 2132, 2273, 2274, 2275, 2276, - -1, -1, -1, -1, -1, -1, -1, 2548, 2549, -1, - -1, -1, -1, 944, -1, -1, 2557, 948, 949, 2619, - -1, -1, -1, 978, -1, -1, 981, 982, -1, -1, - -1, 476, 477, 478, -1, 480, 481, 482, 483, 484, - 485, -1, -1, 2584, 2585, -1, -1, -1, -1, -1, - 2650, 2188, -1, 2653, 2595, -1, 373, -1, 2599, -1, - -1, -1, 308, -1, -1, 311, -1, -1, -1, -1, - 2611, 1002, -1, 2614, -1, -1, -1, -1, 1009, 8, - -1, -1, 11, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 2633, 339, -1, -1, -1, -1, -1, 1030, - -1, 347, -1, -1, -1, 2646, -1, -1, -1, -1, - 2651, -1, 41, -1, -1, 361, -1, -1, -1, 48, - 2257, -1, 368, -1, -1, 2666, 372, -1, -1, 2670, - -1, -1, -1, -1, -1, -1, 382, -1, 2679, -1, - -1, -1, -1, -1, 73, -1, -1, 393, -1, -1, - -1, 397, -1, -1, -1, -1, 473, 2698, -1, -1, - -1, 2702, -1, 480, 481, 482, 483, 484, 485, -1, - -1, -1, -1, 2714, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 433, -1, -1, - -1, -1, 438, -1, -1, -1, -1, -1, -1, 8, - -1, 2742, 11, -1, -1, 451, 1161, 16, 17, 18, - 2751, -1, -1, 1144, 2755, -1, -1, 1172, 2759, 1174, - -1, -1, -1, -1, 33, -1, -1, -1, 1183, 475, - 2367, -1, -1, -1, -1, -1, -1, 2778, 2779, 2780, - 2781, -1, -1, 489, 173, 1200, 492, -1, 3, -1, - -1, 2851, -1, 8, -1, -1, 11, -1, -1, 188, - 2397, 16, 17, 18, 193, -1, -1, -1, -1, -1, - -1, -1, 1227, 1228, -1, -1, -1, -1, 33, -1, - 2557, 36, -1, 2824, -1, -1, 41, -1, -1, -1, - -1, -1, -1, 48, -1, 2836, -1, 2838, -1, 228, - -1, -1, -1, -1, 1259, 1260, 2847, -1, 1263, 1264, - -1, -1, 8, -1, -1, 11, -1, -1, 73, -1, - 2861, -1, -1, -1, -1, 1256, 2867, 2464, -1, -1, - -1, -1, -1, -1, 2611, 1266, -1, 1268, -1, -1, - 1271, 1272, 1273, 1274, -1, 41, -1, 2888, -1, -1, - -1, -1, 48, -1, 283, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 1295, -1, -1, -1, -1, -1, - 1301, 1302, 1303, 1304, -1, -1, -1, 73, 1309, 1310, - 109, 110, -1, 1314, -1, -1, -1, 1318, -1, -1, - 1321, 1322, 1323, 1324, 1325, 1326, 1327, 1328, 1329, -1, - -1, 1332, 2679, -1, -1, 214, 1337, -1, -1, 1340, - -1, 1342, -1, 1344, -1, -1, -1, -1, 173, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 8, - -1, -1, 11, 188, -1, -1, 1367, 2714, 193, 1394, - 1395, -1, -1, -1, 373, -1, 2583, 143, -1, -1, - -1, -1, -1, -1, -1, 184, 185, -1, -1, 214, - 215, -1, 41, 1394, 1395, -1, -1, -1, -1, 48, - -1, -1, -1, 228, 283, 8, -1, 173, 11, -1, - -1, -1, 2619, 16, 17, 18, -1, -1, -1, -1, - -1, 1446, 188, -1, 73, -1, -1, 193, -1, -1, - 33, 1456, -1, 36, 1459, -1, -1, -1, 41, -1, - -1, 266, -1, 2650, 269, 48, 2653, 246, 247, 248, - 249, 250, 251, -1, -1, 254, 255, -1, 283, -1, - -1, 286, 228, -1, -1, -1, -1, -1, -1, -1, - 73, -1, 1473, -1, 473, 1476, 1477, -1, 1479, -1, - -1, 480, 481, 482, 483, 484, 485, -1, -1, 8, - -1, -1, 11, -1, 143, -1, -1, 16, 17, 18, - -1, -1, -1, -1, -1, -1, 1531, 1532, -1, 1510, - -1, -1, -1, -1, 33, -1, -1, 283, -1, -1, - -1, -1, 41, -1, 173, -1, -1, -1, -1, 48, - -1, -1, 1557, -1, -1, -1, -1, -1, -1, 188, - -1, -1, -1, -1, 193, 1570, -1, -1, 373, -1, - -1, -1, -1, -1, 73, -1, -1, -1, -1, 358, - 359, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 173, 1572, -1, -1, -1, -1, -1, -1, 1579, 228, - -1, -1, -1, 1584, -1, 188, -1, -1, -1, -1, - 193, -1, -1, -1, -1, -1, -1, 476, 477, 478, - -1, 480, 481, 482, 483, 484, 485, 373, -1, -1, - -1, 214, 215, -1, -1, -1, -1, -1, -1, -1, - -1, 1622, -1, -1, -1, 228, -1, -1, -1, -1, - -1, -1, -1, 1634, 283, 1636, 1637, -1, 886, -1, - -1, -1, -1, 1644, 2851, -1, -1, 1648, 473, -1, - 1651, 476, 477, 478, 173, 480, 481, 482, 483, 484, - 485, -1, -1, 266, -1, -1, 269, -1, -1, 188, - 469, 470, -1, -1, 193, -1, -1, -1, 926, -1, - 283, -1, -1, 286, 1685, -1, -1, 1688, -1, 1690, - 489, -1, -1, -1, -1, 214, 215, -1, -1, -1, - -1, -1, -1, 1728, -1, -1, -1, 473, -1, 228, - -1, -1, -1, -1, 480, 481, 482, 483, 484, 485, - 8, -1, -1, 11, 373, -1, -1, -1, 16, 17, - 18, -1, -1, -1, 1759, 1760, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 33, -1, 266, -1, -1, - 269, 1752, -1, 41, -1, -1, -1, -1, -1, -1, - 48, -1, -1, -1, 283, -1, 1767, 286, -1, -1, - 373, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 1785, 73, 1034, -1, -1, -1, - -1, -1, -1, 1041, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 8, - -1, -1, 11, -1, 473, -1, -1, 16, 17, 18, - -1, 480, 481, 482, 483, 484, 485, -1, -1, -1, - -1, -1, 1843, -1, 33, -1, -1, -1, -1, -1, - -1, -1, 41, -1, 373, -1, -1, -1, -1, 48, - -1, -1, -1, -1, -1, -1, -1, 1892, -1, -1, - 473, -1, -1, 476, 477, 478, -1, 480, 481, 482, - 483, 484, 485, -1, 73, 173, -1, 490, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 188, -1, 23, -1, -1, 193, -1, -1, 29, -1, - -1, -1, -1, -1, -1, 36, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 214, 215, -1, -1, - -1, -1, -1, -1, 55, -1, -1, -1, 1939, -1, - 228, -1, -1, -1, -1, -1, -1, 1948, -1, -1, - 1951, -1, -1, 1954, 473, -1, -1, 476, 477, 478, - -1, 480, 481, 482, 483, 484, 485, -1, -1, -1, - -1, 490, 109, 110, -1, -1, -1, -1, 266, 1980, - 1981, 269, -1, -1, 173, 106, -1, -1, -1, -1, - -1, -1, -1, 1994, -1, 283, -1, -1, 286, 188, - -1, -1, 2003, -1, 193, 2006, 1254, 2008, -1, -1, - -1, -1, -1, -1, 135, 2016, -1, 1265, -1, -1, - -1, 1269, -1, 2024, 2025, 214, 215, 1275, 1276, 1277, - -1, -1, -1, -1, -1, -1, 1284, -1, -1, 228, - -1, -1, -1, -1, -1, -1, -1, 184, 185, -1, - -1, -1, 2053, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 2063, 8, -1, -1, 11, -1, -1, -1, - -1, 16, 17, 18, 195, -1, -1, 266, 2079, -1, - 269, -1, -1, -1, -1, 373, -1, -1, 33, -1, - -1, 1339, 8, -1, 283, 11, 41, 286, -1, -1, - 16, 17, 18, 48, -1, -1, -1, 2132, -1, 246, - 247, 248, 249, 250, 251, -1, -1, 254, 255, -1, - -1, -1, -1, 244, -1, 41, -1, -1, 73, -1, - -1, 252, 48, 1381, -1, -1, -1, -1, 8, -1, - -1, 11, -1, 264, -1, 1393, 16, 17, 18, -1, - 1398, -1, -1, -1, -1, -1, -1, 73, -1, -1, - -1, -1, -1, 33, 285, -1, -1, -1, -1, -1, - -1, 41, -1, -1, 295, -1, -1, -1, 48, -1, - -1, -1, -1, -1, 373, 473, -1, -1, 476, 477, - 478, -1, 480, 481, 482, 483, 484, 485, -1, -1, - -1, -1, 490, 73, 2205, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 335, -1, -1, -1, 339, 340, - -1, 358, 359, -1, -1, -1, -1, -1, 173, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 362, -1, 188, -1, -1, -1, 368, 193, -1, - 2251, 2252, -1, -1, -1, 2256, -1, 173, -1, -1, - 2261, 382, -1, 2264, 2265, -1, -1, -1, 2269, 214, - 215, -1, 188, -1, -1, -1, -1, 193, -1, -1, - -1, -1, -1, 228, 473, -1, -1, 476, 477, 478, - -1, 480, 481, 482, 483, 484, 485, -1, -1, -1, - -1, 490, -1, 173, -1, -1, -1, -1, -1, -1, - -1, -1, 228, -1, 435, 2316, -1, -1, 188, -1, - -1, 266, -1, 193, 269, -1, -1, -1, -1, -1, - -1, 2356, 469, 470, 1582, -1, 2361, -1, 283, -1, - -1, 286, -1, -1, 214, 215, -1, -1, -1, -1, - -1, -1, -1, 1601, -1, -1, -1, 2358, 228, -1, - -1, -1, -1, -1, -1, -1, -1, 283, -1, -1, - 1618, -1, 1620, 1621, -1, 1623, -1, 1625, 2403, 2404, - -1, -1, 1630, -1, -1, 1633, -1, -1, -1, -1, - 1638, -1, -1, 1641, -1, -1, 266, -1, -1, 269, - -1, -1, -1, -1, -1, 1653, -1, -1, -1, 1657, - 1658, 1659, 1660, 283, -1, -1, 286, -1, 1666, 1667, - -1, 1669, 1670, -1, -1, -1, -1, -1, 373, -1, - -1, -1, -1, 1681, -1, 36, 1684, -1, -1, -1, - -1, -1, -1, -1, 1692, 1693, 1694, 1695, 1696, 1697, - 1698, 1699, 1700, 1701, 55, -1, -1, 373, -1, -1, - -1, 1709, -1, -1, -1, 1713, -1, 2468, -1, -1, - -1, -1, -1, -1, -1, 2476, 2477, -1, -1, 2480, - -1, -1, -1, -1, -1, -1, -1, 1735, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 373, -1, 106, 107, -1, -1, -1, - -1, -1, -1, -1, 115, 2516, 2517, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 473, 2530, - -1, 476, 477, 478, -1, 480, 481, 482, 483, 484, - 485, -1, -1, -1, -1, 490, -1, 2572, 2573, -1, - -1, -1, -1, -1, -1, -1, -1, 473, 2583, -1, - 476, 477, 478, -1, 480, 481, 482, 483, 484, 485, - -1, 172, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 195, -1, -1, -1, 1846, 1847, - 1848, -1, -1, 473, -1, -1, 476, 477, 478, -1, - 480, 481, 482, 483, 484, 485, -1, -1, -1, -1, - 490, -1, 8, -1, -1, 11, -1, -1, -1, -1, - 16, 17, 18, -1, -1, -1, 1884, -1, -1, -1, - -1, 2642, -1, 244, -1, -1, -1, 33, -1, -1, - -1, 252, -1, -1, -1, 41, 2657, -1, -1, -1, - -1, -1, 48, 264, -1, 266, 8, -1, -1, 11, - 2671, -1, -1, -1, 16, 17, 18, -1, -1, -1, - -1, -1, -1, -1, -1, 2686, -1, 73, -1, -1, - 1938, 33, -1, -1, 295, -1, 1944, -1, -1, 41, - -1, -1, -1, -1, -1, -1, 48, -1, -1, 1957, - 1958, 1959, -1, 1961, 1962, 1963, 1964, -1, -1, 1967, - 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, - -1, 73, -1, -1, -1, -1, -1, -1, -1, 340, - -1, -1, -1, -1, -1, -1, -1, 1995, -1, -1, - 1998, -1, 2000, -1, -1, -1, 2004, 2005, -1, -1, - -1, 362, -1, -1, -1, -1, 2767, -1, -1, -1, - 2018, 2019, 2020, 2021, -1, 2023, -1, -1, -1, -1, - -1, 382, -1, 384, -1, -1, 387, 173, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 2799, -1, - -1, -1, 188, -1, -1, -1, -1, 193, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 2819, 2820, - -1, -1, -1, -1, -1, -1, 2851, -1, 214, 215, - -1, 173, 2833, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 228, -1, -1, -1, 188, -1, 2096, -1, - -1, 193, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 2869, -1, - -1, -1, 214, 215, -1, -1, -1, -1, -1, -1, - 266, 8, -1, 269, 11, -1, 228, -1, 489, -1, - -1, -1, -1, -1, -1, -1, -1, 283, -1, -1, - 286, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 41, -1, -1, -1, -1, -1, - -1, 48, -1, -1, 266, -1, -1, 269, -1, -1, - -1, -1, -1, -1, 2935, -1, -1, -1, -1, -1, - -1, 283, -1, -1, 286, -1, 73, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 2206, -1, - -1, -1, 2210, 2211, -1, 2213, -1, -1, 2216, 2217, - 2218, 2219, -1, -1, -1, 2223, 2224, 2225, 2226, 2227, - 2228, 2229, 2230, 2231, 2232, 2233, 2234, 373, -1, -1, - -1, -1, -1, -1, -1, -1, 2244, -1, -1, -1, - 8, -1, 2250, 11, -1, 2253, -1, 2255, 16, 17, - 18, 2259, -1, -1, 2262, 2263, 143, -1, 2266, 2267, - -1, -1, -1, -1, -1, 33, -1, -1, -1, -1, - -1, 373, -1, 41, -1, -1, -1, -1, -1, -1, - 48, -1, -1, -1, -1, -1, 173, -1, -1, 8, - -1, -1, 11, -1, -1, -1, -1, -1, -1, 2307, - -1, 188, -1, -1, -1, 73, 193, 2315, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 2328, -1, 41, -1, -1, -1, -1, 473, -1, 48, - 476, 477, 478, -1, 480, 481, 482, 483, 484, 485, - -1, 228, -1, -1, 490, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 73, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 473, -1, -1, 476, 477, 478, -1, 480, 481, - 482, 483, 484, 485, -1, -1, -1, -1, 490, -1, - -1, -1, -1, -1, -1, -1, 283, -1, -1, -1, - -1, -1, -1, -1, -1, 173, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 188, -1, -1, -1, 143, 193, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 214, 215, -1, 2457, - -1, -1, -1, 2461, 173, -1, -1, -1, -1, -1, - 228, -1, 2470, 2471, 2472, -1, -1, 2475, -1, 188, - 2478, 2479, -1, -1, 193, 2483, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 373, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 266, -1, - -1, 269, -1, -1, -1, -1, -1, -1, -1, 228, - -1, -1, -1, -1, -1, 283, -1, -1, 286, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 2550, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 2569, -1, -1, 283, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 473, -1, -1, -1, - -1, -1, -1, 480, 481, 482, 483, 484, 485, -1, - -1, -1, -1, -1, -1, 373, -1, -1, -1, 2617, - 2618, -1, -1, -1, -1, 2623, 2624, 2625, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 373, -1, 2664, 2665, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 2677, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 2689, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 473, -1, -1, 476, 477, - 478, -1, 480, 481, 482, 483, 484, 485, -1, -1, - -1, -1, 490, -1, -1, -1, -1, -1, 2736, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 2754, -1, -1, -1, - -1, -1, -1, -1, 473, -1, -1, -1, -1, -1, - -1, 480, 481, 482, 483, 484, 485, -1, 2776, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 2790, -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, -1, -1, -1, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, -1, -1, - -1, -1, 35, -1, -1, 38, 39, -1, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 2858, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 2872, 68, 69, 70, 71, 72, - -1, 74, -1, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, -1, 87, 88, 89, 90, 91, 92, - -1, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, -1, 118, 119, 120, 121, 122, - 123, -1, 125, 126, 127, 128, 129, 130, -1, 132, - 133, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, -1, 146, 147, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, -1, 159, 160, 161, 162, - -1, 164, -1, 166, 167, -1, 169, 170, 171, 172, - 173, 174, -1, 176, -1, 178, 179, 180, -1, 182, - 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - -1, 194, 195, 196, 197, 198, 199, -1, 201, 202, - 203, 204, 205, 206, 207, 208, 209, -1, 211, -1, - 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, - -1, -1, 225, 226, 227, 228, -1, 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, -1, -1, - 283, 284, 285, -1, -1, 288, 289, 290, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, - 303, -1, 305, 306, 307, 308, 309, 310, 311, 312, - 313, -1, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, -1, 330, 331, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, -1, - 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 360, -1, 362, - 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, -1, 379, 380, 381, 382, - 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, - 393, -1, 395, 396, -1, 398, 399, 400, 401, 402, - 403, 404, -1, 406, 407, -1, -1, 410, 411, 412, - 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, - 423, -1, -1, 426, 427, 428, 429, 430, 431, -1, - 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, - 443, 444, 445, 446, -1, -1, 449, -1, -1, 452, - 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, - 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, - 473, -1, -1, -1, -1, -1, -1, 480, 481, 482, - -1, -1, -1, -1, 487, -1, 489, 490, -1, -1, - -1, 494, -1, 496, 497, 3, 4, 5, 6, 7, - 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, - -1, 19, 20, 21, 22, 23, 24, 25, 26, -1, - 28, 29, 30, -1, -1, -1, -1, 35, -1, -1, - 38, 39, -1, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, -1, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, -1, - 68, 69, 70, 71, 72, -1, 74, -1, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, -1, 87, - 88, 89, 90, 91, 92, -1, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, -1, - 118, 119, 120, 121, 122, 123, -1, 125, 126, 127, - 128, 129, -1, -1, 132, 133, 134, 135, 136, -1, - 138, 139, 140, -1, 142, 143, 144, -1, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, - -1, 159, 160, 161, 162, -1, 164, -1, 166, 167, - -1, 169, 170, 171, 172, 173, 174, -1, 176, -1, - 178, 179, 180, -1, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, -1, 194, 195, 196, 197, - 198, 199, -1, 201, 202, 203, 204, 205, 206, 207, - 208, 209, -1, 211, -1, 213, 214, 215, 216, 217, - 218, 219, 220, 221, 222, -1, -1, 225, 226, 227, - 228, -1, 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, -1, -1, 283, 284, 285, -1, -1, - 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, - 298, 299, 300, 301, 302, 303, -1, 305, 306, 307, - 308, 309, 310, 311, 312, 313, -1, 315, 316, 317, - 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, - 328, -1, 330, 331, 332, 333, 334, 335, 336, 337, - 338, 339, 340, 341, -1, 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, - -1, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 388, 389, 390, 391, 392, 393, -1, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, -1, 406, 407, - -1, -1, 410, 411, 412, 413, 414, 415, 416, 417, - 418, 419, 420, 421, 422, 423, -1, -1, 426, 427, - 428, 429, 430, 431, -1, 433, 434, 435, 436, 437, - 438, 439, -1, 441, 442, 443, 444, 445, 446, -1, - -1, 449, -1, 451, 452, 453, 454, 455, 456, 457, + 319, 320, 321, 322, 323, 324, 0, 325, 326, 327, + 328, 329, 330, 331, 332, 333, 0, 334, 335, 336, + 337, 338, 339, 0, 340, 341, 342, 343, 344, 345, + 346, 347, 0, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 0, 361, 362, 363, + 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 0, 379, 380, 381, 382, + 383, 0, 384, 385, 386, 387, 388, 389, 390, 391, + 392, 393, 0, 394, 395, 396, 397, 398, 399, 400, + 401, 402, 403, 404, 405, 406, 407, 408, 0, 409, + 410, 0, 411, 412, 413, 414, 415, 416, 417, 0, + 418, 419, 0, 0, 420, 421, 422, 423, 424, 0, + 425, 426, 427, 428, 429, 430, 431, 432, 0, 0, + 433, 434, 435, 436, 437, 0, 0, 438, 439, 440, + 441, 442, 443, 444, 0, 445, 446, 447, 448, 449, + 450, 0, 0, 451, 0, 0, 452, 453, 454, 455, + 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 498, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 93, 94, 95, 96, 97, 98, 99, + 100, 0, 101, 102, 103, 0, 0, 0, 0, 0, + 0, 0, 104, 105, 0, 106, 107, 108, 0, 110, + 111, 112, 113, 114, 0, 116, 117, 0, 118, 119, + 120, 121, 122, 123, 0, 0, 124, 125, 126, 127, + 128, 1429, 129, 130, 131, 132, 133, 0, 0, 1430, + 135, 136, 137, 138, 139, 140, 0, 142, 143, 144, + 1431, 145, 146, 147, 148, 149, 150, 0, 0, 152, + 153, 154, 0, 0, 0, 0, 0, 0, 0, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 0, + 166, 0, 167, 168, 169, 170, 171, 172, 0, 173, + 174, 175, 176, 177, 0, 0, 178, 179, 180, 181, + 182, 0, 183, 184, 185, 0, 186, 187, 188, 0, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 0, 199, 0, 200, 201, 202, 203, 0, 204, 1432, + 205, 0, 0, 0, 208, 209, 210, 0, 212, 0, + 213, 0, 214, 215, 216, 0, 217, 218, 219, 220, + 221, 1433, 223, 0, 225, 226, 227, 228, 0, 229, + 230, 231, 232, 233, 234, 0, 235, 0, 237, 238, + 239, 240, 241, 242, 243, 244, 0, 245, 0, 246, + 0, 0, 249, 0, 251, 252, 253, 254, 255, 0, + 0, 256, 0, 258, 0, 0, 260, 261, 262, 0, + 0, 263, 264, 265, 266, 267, 500, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 287, 0, 289, 290, 291, + 292, 293, 0, 294, 295, 0, 297, 0, 298, 299, + 300, 301, 302, 303, 0, 304, 305, 0, 0, 306, + 307, 308, 0, 0, 309, 310, 0, 312, 0, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 0, 325, 326, 327, 328, 329, 330, 331, 332, 333, + 1434, 334, 335, 336, 337, 338, 339, 0, 340, 341, + 342, 343, 344, 345, 346, 347, 0, 348, 349, 350, + 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, + 0, 361, 362, 0, 364, 365, 366, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 0, + 379, 380, 381, 382, 383, 0, 384, 385, 386, 387, + 388, 0, 390, 391, 392, 393, 0, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, 404, 502, 406, + 407, 408, 0, 409, 410, 0, 411, 0, 413, 414, + 415, 416, 417, 0, 418, 419, 0, 0, 420, 421, + 422, 423, 424, 0, 425, 426, 427, 428, 429, 430, + 431, 432, 0, 1435, 433, 434, 435, 436, 437, 0, + 0, 438, 439, 440, 441, 442, 443, 444, 0, 445, + 0, 447, 448, 449, 450, 0, 0, 451, 0, 0, + 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 498, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 93, 94, 95, + 96, 97, 98, 99, 100, 0, 101, 102, 103, 0, + 0, 0, 0, 0, 0, 0, 104, 105, 0, 106, + 107, 108, 0, 110, 111, 112, 113, 114, 0, 116, + 117, 0, 118, 119, 120, 121, 122, 123, 0, 0, + 124, 125, 126, 127, 128, 1429, 129, 130, 131, 132, + 133, 0, 0, 0, 135, 136, 137, 138, 139, 140, + 0, 142, 143, 144, 1431, 145, 146, 147, 148, 149, + 150, 0, 0, 152, 153, 154, 0, 0, 0, 0, + 0, 0, 0, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 0, 166, 0, 167, 168, 169, 170, + 171, 172, 0, 173, 174, 175, 176, 177, 0, 0, + 178, 179, 180, 181, 182, 0, 183, 184, 185, 0, + 186, 187, 188, 0, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 0, 199, 0, 200, 201, 202, + 203, 0, 204, 1432, 205, 0, 0, 0, 208, 209, + 210, 0, 212, 0, 213, 0, 214, 215, 216, 0, + 217, 218, 219, 220, 221, 222, 223, 0, 225, 226, + 227, 228, 0, 229, 230, 231, 232, 233, 234, 0, + 235, 0, 237, 238, 239, 240, 241, 242, 243, 244, + 0, 245, 0, 246, 0, 0, 249, 0, 251, 252, + 253, 254, 255, 0, 0, 256, 0, 258, 1888, 0, + 260, 261, 262, 0, 0, 263, 264, 265, 266, 267, + 500, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 0, 289, 290, 291, 292, 293, 0, 294, 295, 0, + 297, 0, 298, 299, 300, 301, 302, 303, 0, 304, + 305, 0, 0, 306, 307, 308, 0, 0, 309, 310, + 0, 312, 0, 314, 315, 316, 317, 318, 319, 320, + 321, 322, 323, 324, 0, 325, 326, 327, 328, 329, + 330, 331, 332, 333, 1434, 334, 335, 336, 337, 338, + 339, 0, 340, 341, 342, 343, 344, 345, 346, 347, + 0, 348, 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 0, 361, 362, 0, 364, 365, + 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 0, 379, 380, 381, 382, 383, 0, + 384, 385, 386, 387, 388, 0, 390, 391, 392, 393, + 0, 394, 395, 396, 397, 398, 399, 400, 401, 402, + 403, 404, 502, 406, 407, 408, 0, 409, 410, 0, + 411, 0, 413, 414, 415, 416, 417, 0, 418, 419, + 0, 0, 420, 421, 422, 423, 424, 0, 425, 426, + 427, 428, 429, 430, 431, 432, 0, 1435, 433, 434, + 435, 436, 437, 0, 0, 438, 439, 440, 441, 442, + 443, 444, 0, 445, 0, 447, 448, 449, 450, 0, + 0, 451, 0, 0, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 471, 472, 473, -1, 475, -1, -1, - -1, -1, 480, 481, -1, -1, -1, -1, -1, 487, - -1, 489, 490, -1, -1, -1, 494, -1, 496, 497, - 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, - -1, -1, -1, -1, -1, -1, 19, 20, 21, 22, - 23, 24, 25, 26, -1, 28, 29, 30, -1, -1, - -1, -1, 35, -1, -1, 38, 39, -1, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - -1, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, -1, 68, 69, 70, 71, 72, - -1, 74, -1, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, -1, 87, 88, 89, 90, 91, 92, - -1, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, -1, 118, 119, 120, 121, 122, - 123, -1, 125, 126, 127, 128, 129, -1, -1, 132, - 133, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, -1, 146, 147, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, -1, 159, 160, 161, 162, - -1, 164, -1, 166, 167, -1, 169, 170, 171, 172, - 173, 174, -1, 176, -1, 178, 179, 180, -1, 182, - 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - -1, 194, 195, 196, 197, 198, 199, -1, 201, 202, - 203, 204, 205, 206, 207, 208, 209, -1, 211, -1, - 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, - -1, -1, 225, 226, 227, 228, -1, 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, -1, -1, - 283, 284, 285, -1, -1, 288, 289, 290, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, - 303, -1, 305, 306, 307, 308, 309, 310, 311, 312, - 313, -1, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, -1, 330, 331, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, -1, - 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, -1, 379, 380, 381, 382, - 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, - 393, -1, 395, 396, 397, 398, 399, 400, 401, 402, - 403, 404, -1, 406, 407, -1, -1, 410, 411, 412, - 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, - 423, -1, -1, 426, 427, 428, 429, 430, 431, -1, - 433, 434, 435, 436, 437, 438, 439, -1, 441, 442, - 443, 444, 445, 446, -1, -1, 449, -1, 451, 452, - 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, - 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, - 473, -1, 475, -1, -1, -1, -1, 480, 481, -1, - -1, -1, -1, -1, 487, -1, 489, -1, -1, -1, - -1, 494, -1, 496, 497, 3, 4, 5, 6, 7, - 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, - -1, 19, 20, 21, 22, 23, 24, 25, 26, -1, - 28, 29, 30, -1, -1, -1, -1, 35, -1, -1, - 38, 39, -1, 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, -1, - 68, 69, 70, 71, 72, -1, 74, -1, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, -1, 87, - 88, 89, 90, 91, 92, -1, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, -1, - 118, 119, 120, 121, 122, 123, -1, 125, 126, 127, - 128, 129, -1, -1, 132, 133, 134, 135, 136, -1, - 138, 139, 140, -1, 142, 143, 144, -1, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, - -1, 159, 160, 161, 162, -1, 164, -1, 166, 167, - 168, 169, 170, 171, 172, 173, 174, -1, 176, -1, - 178, 179, 180, -1, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, -1, 194, 195, 196, 197, - 198, 199, -1, 201, 202, 203, 204, 205, 206, 207, - 208, 209, -1, 211, -1, 213, 214, 215, 216, 217, - 218, 219, 220, 221, 222, -1, 224, 225, 226, 227, - 228, -1, 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, -1, -1, 283, 284, 285, -1, -1, - 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, - 298, 299, 300, 301, 302, 303, -1, 305, 306, 307, - 308, 309, 310, 311, 312, 313, -1, 315, 316, 317, - 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, - 328, -1, 330, 331, 332, 333, 334, 335, 336, 337, - 338, 339, 340, 341, -1, 343, 344, 345, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, - 358, 359, 360, -1, 362, 363, 364, 365, 366, 367, + 468, 469, 470, 471, 472, 742, 0, 547, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 93, 94, 95, 96, 97, 98, 99, 100, 0, + 101, 102, 103, 0, 0, 0, 0, 0, 0, 0, + 104, 105, 0, 106, 107, 108, 0, 110, 111, 112, + 743, 744, 0, 745, 746, 0, 118, 119, 120, 121, + 122, 123, 0, 0, 124, 125, 747, 748, 128, 0, + 129, 130, 131, 132, 749, 0, 0, 0, 135, 136, + 137, 138, 139, 140, 0, 142, 143, 144, 0, 145, + 146, 147, 148, 149, 150, 0, 0, 152, 153, 154, + 0, 0, 0, 0, 0, 0, 0, 156, 157, 158, + 159, 160, 161, 162, 750, 751, 165, 0, 166, 0, + 167, 168, 169, 170, 171, 172, 0, 173, 174, 175, + 176, 177, 0, 0, 178, 179, 180, 181, 182, 0, + 183, 184, 185, 0, 186, 187, 188, 0, 189, 190, + 191, 192, 752, 194, 195, 196, 197, 753, 1233, 199, + 0, 200, 201, 754, 203, 0, 204, 0, 205, 0, + 0, 0, 208, 209, 210, 0, 212, 0, 213, 0, + 755, 756, 216, 0, 217, 218, 219, 220, 221, 222, + 223, 0, 225, 226, 227, 228, 0, 229, 230, 231, + 232, 233, 234, 0, 235, 0, 757, 238, 239, 240, + 241, 242, 758, 759, 0, 760, 0, 246, 0, 0, + 249, 0, 251, 252, 253, 254, 255, 0, 0, 256, + 0, 258, 0, 0, 260, 261, 262, 0, 0, 263, + 264, 265, 266, 267, 761, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + 284, 285, 286, 762, 0, 763, 290, 291, 292, 764, + 0, 294, 295, 0, 297, 0, 765, 299, 766, 301, + 302, 303, 0, 304, 305, 1234, 0, 306, 307, 308, + 0, 0, 309, 767, 0, 312, 0, 768, 315, 316, + 317, 318, 319, 320, 321, 322, 323, 324, 0, 325, + 326, 769, 328, 329, 770, 331, 332, 333, 0, 334, + 335, 336, 337, 338, 339, 0, 340, 341, 342, 771, + 344, 345, 346, 347, 0, 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 0, 361, + 362, 0, 364, 365, 366, 772, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 0, 379, 380, + 381, 382, 383, 0, 384, 773, 386, 387, 388, 0, + 390, 391, 774, 393, 0, 394, 395, 396, 397, 398, + 399, 400, 401, 402, 403, 404, 775, 406, 776, 408, + 0, 409, 410, 0, 411, 0, 413, 414, 415, 416, + 417, 0, 777, 778, 0, 0, 420, 421, 779, 423, + 780, 1235, 425, 426, 781, 428, 429, 430, 431, 432, + 0, 0, 433, 434, 435, 436, 437, 0, 0, 438, + 439, 440, 441, 442, 1125, 783, 0, 445, 0, 447, + 448, 449, 450, 0, 0, 451, 0, 0, 452, 453, + 454, 455, 456, 457, 784, 785, 786, 787, 788, 789, + 790, 791, 792, 793, 794, 469, 470, 471, 472, 498, + 0, 579, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 93, 94, 95, 96, 97, + 98, 99, 100, 0, 101, 102, 103, 3, 4, 0, + 0, 0, 0, 0, 104, 105, 0, 106, 107, 108, + 0, 110, 111, 112, 113, 114, 0, 116, 117, 0, + 118, 119, 120, 121, 122, 123, 0, 0, 124, 125, + 126, 127, 128, 0, 129, 130, 131, 132, 133, 0, + 0, 0, 135, 136, 137, 138, 139, 140, 0, 142, + 143, 144, 0, 145, 146, 147, 148, 149, 150, 0, + 0, 152, 153, 154, 0, 0, 0, 0, 0, 0, + 0, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 0, 166, 0, 167, 168, 169, 170, 171, 172, + 0, 173, 174, 175, 176, 177, 0, 0, 178, 179, + 180, 181, 182, 0, 183, 184, 185, 0, 186, 187, + 188, 0, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 0, 199, 0, 200, 201, 202, 203, 0, + 204, 0, 205, 0, 0, 0, 208, 209, 210, 0, + 212, 0, 213, 0, 214, 215, 216, 0, 217, 218, + 219, 220, 221, 222, 223, 0, 225, 226, 227, 228, + 0, 229, 230, 231, 232, 233, 234, 0, 235, 0, + 237, 238, 239, 240, 241, 242, 243, 244, 0, 245, + 0, 246, 0, 0, 249, 0, 251, 252, 253, 254, + 255, 0, 0, 256, 0, 258, 0, 0, 260, 261, + 262, 0, 0, 263, 264, 265, 266, 267, 500, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 287, 0, 289, + 290, 291, 292, 293, 0, 294, 295, 0, 297, 0, + 298, 299, 300, 301, 302, 303, 0, 304, 305, 0, + 0, 306, 307, 308, 0, 0, 309, 310, 0, 312, + 0, 314, 315, 316, 317, 318, 319, 320, 321, 322, + 323, 324, 0, 325, 326, 327, 328, 329, 330, 331, + 332, 333, 0, 334, 335, 336, 337, 338, 339, 0, + 340, 341, 342, 343, 344, 345, 346, 347, 0, 348, + 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, + 359, 360, 0, 361, 362, 0, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, - -1, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 388, 389, 390, 391, 392, 393, -1, 395, 396, -1, - 398, 399, 400, 401, 402, 403, 404, -1, 406, 407, - -1, 409, 410, 411, 412, 413, 414, 415, 416, 417, - 418, 419, 420, 421, 422, 423, -1, -1, 426, 427, - 428, 429, 430, 431, -1, 433, 434, 435, 436, 437, - 438, 439, -1, 441, 442, 443, 444, 445, 446, -1, - -1, 449, -1, -1, 452, 453, 454, 455, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 471, 472, 473, -1, -1, -1, -1, - -1, -1, 480, 481, -1, -1, -1, -1, -1, 487, - -1, 489, -1, -1, -1, -1, 494, -1, 496, 497, - 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, - -1, -1, -1, -1, -1, -1, 19, 20, 21, 22, - 23, 24, 25, 26, -1, 28, 29, 30, -1, -1, - -1, -1, 35, -1, -1, 38, 39, -1, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - -1, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, -1, 68, 69, 70, 71, 72, - -1, 74, -1, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, -1, 87, 88, 89, 90, 91, 92, - -1, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, -1, 118, 119, 120, 121, 122, - 123, -1, 125, 126, 127, 128, 129, -1, -1, 132, - 133, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, -1, 146, 147, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, -1, 159, 160, 161, 162, - -1, 164, -1, 166, 167, -1, 169, 170, 171, 172, - 173, 174, -1, 176, -1, 178, 179, 180, -1, 182, - 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - -1, 194, 195, 196, 197, 198, 199, -1, 201, 202, - 203, 204, 205, 206, 207, 208, 209, -1, 211, -1, - 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, - -1, -1, 225, 226, 227, 228, -1, 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, -1, -1, - 283, 284, 285, -1, -1, 288, 289, 290, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, - 303, -1, 305, 306, 307, 308, 309, 310, 311, 312, - 313, -1, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, -1, 330, 331, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, -1, - 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 360, -1, 362, - 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, -1, 379, 380, 381, 382, - 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, - 393, -1, 395, 396, -1, 398, 399, 400, 401, 402, - 403, 404, -1, 406, 407, -1, -1, 410, 411, 412, - 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, - 423, -1, -1, 426, 427, 428, 429, 430, 431, -1, - 433, 434, 435, 436, 437, 438, 439, -1, 441, 442, - 443, 444, 445, 446, -1, -1, 449, -1, -1, 452, - 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, - 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, - 473, -1, -1, -1, -1, -1, -1, 480, 481, 482, - -1, -1, -1, -1, 487, -1, 489, -1, -1, -1, - -1, 494, -1, 496, 497, 3, 4, 5, 6, 7, - 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, - -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, -1, -1, -1, -1, 35, -1, -1, - 38, 39, -1, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, -1, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, -1, - 68, 69, 70, 71, 72, -1, 74, -1, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, -1, 87, - 88, 89, 90, 91, 92, -1, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, -1, - 118, 119, 120, 121, 122, 123, -1, 125, 126, 127, - 128, 129, -1, -1, 132, 133, 134, 135, 136, -1, - 138, 139, 140, -1, 142, 143, 144, -1, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, - -1, 159, 160, 161, 162, -1, 164, -1, 166, 167, - -1, 169, 170, 171, 172, 173, 174, -1, 176, -1, - 178, 179, 180, -1, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, -1, 194, 195, 196, 197, - 198, 199, -1, 201, 202, 203, 204, 205, 206, 207, - 208, 209, -1, 211, -1, 213, 214, 215, 216, 217, - 218, 219, 220, 221, 222, -1, -1, 225, 226, 227, - 228, -1, 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, -1, -1, 283, 284, 285, -1, -1, - 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, - 298, 299, 300, 301, 302, 303, -1, 305, 306, 307, - 308, 309, 310, 311, 312, 313, -1, 315, 316, 317, - 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, - 328, -1, 330, 331, 332, 333, 334, 335, 336, 337, - 338, 339, 340, 341, -1, 343, 344, 345, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, - 358, 359, 360, -1, 362, 363, 364, 365, 366, 367, + 378, 0, 379, 380, 381, 382, 383, 0, 384, 385, + 386, 387, 388, 0, 390, 391, 392, 393, 0, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 502, 406, 407, 408, 0, 409, 410, 0, 411, 0, + 413, 414, 415, 416, 417, 0, 418, 419, 0, 0, + 420, 421, 422, 423, 424, 0, 425, 426, 427, 428, + 429, 430, 431, 432, 0, 0, 433, 434, 435, 436, + 437, 0, 0, 438, 439, 440, 441, 442, 443, 444, + 0, 445, 0, 447, 448, 449, 450, 0, 0, 451, + 0, 0, 452, 453, 454, 455, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 498, 0, 579, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, + 94, 95, 96, 97, 98, 99, 100, 0, 101, 102, + 103, 0, 0, 0, 0, 0, 0, 0, 104, 105, + 0, 106, 107, 108, 0, 110, 111, 112, 113, 114, + 0, 116, 117, 0, 118, 119, 120, 121, 122, 123, + 0, 0, 124, 125, 126, 127, 128, 0, 129, 130, + 131, 132, 133, 0, 0, 0, 135, 136, 137, 138, + 139, 140, 0, 142, 143, 144, 0, 145, 146, 147, + 148, 149, 150, 0, 0, 152, 153, 154, 0, 0, + 0, 0, 0, 0, 0, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 0, 166, 0, 167, 168, + 169, 170, 171, 172, 0, 173, 174, 175, 176, 177, + 0, 0, 178, 179, 180, 181, 182, 0, 183, 184, + 185, 0, 186, 187, 188, 0, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 0, 199, 0, 200, + 201, 202, 203, 0, 204, 0, 205, 0, 0, 0, + 208, 209, 210, 0, 212, 0, 213, 0, 214, 215, + 216, 0, 217, 218, 219, 220, 221, 222, 223, 0, + 225, 226, 227, 228, 0, 229, 230, 231, 232, 233, + 234, 0, 235, 0, 237, 238, 239, 240, 241, 242, + 243, 244, 0, 245, 0, 246, 0, 0, 249, 0, + 251, 252, 253, 254, 255, 0, 0, 256, 0, 258, + 0, 0, 260, 261, 262, 0, 0, 263, 264, 265, + 266, 267, 500, 269, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, + 286, 287, 0, 289, 290, 291, 292, 293, 0, 294, + 295, 0, 297, 0, 298, 299, 300, 301, 302, 303, + 0, 304, 305, 0, 580, 306, 307, 308, 0, 0, + 309, 310, 0, 312, 0, 314, 315, 316, 317, 318, + 319, 320, 321, 322, 323, 324, 0, 325, 326, 327, + 328, 329, 330, 331, 332, 333, 0, 334, 335, 336, + 337, 338, 339, 0, 340, 341, 342, 343, 344, 345, + 346, 347, 0, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 0, 361, 362, 0, + 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 0, 379, 380, 381, 382, + 383, 0, 384, 385, 386, 387, 388, 0, 390, 391, + 392, 393, 0, 394, 395, 396, 397, 398, 399, 400, + 401, 402, 403, 404, 502, 406, 407, 408, 0, 409, + 410, 0, 411, 0, 413, 414, 415, 416, 417, 0, + 418, 419, 0, 0, 420, 421, 422, 423, 424, 0, + 425, 426, 427, 428, 429, 430, 431, 432, 0, 0, + 433, 434, 435, 436, 437, 0, 0, 438, 439, 440, + 441, 442, 443, 444, 0, 445, 0, 447, 448, 449, + 450, 0, 0, 451, 0, 0, 452, 453, 454, 455, + 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 498, 0, 579, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 93, 94, 95, 96, 97, 98, 99, + 100, 0, 101, 102, 103, 0, 0, 0, 0, 0, + 0, 0, 104, 105, 0, 106, 107, 108, 0, 110, + 111, 112, 113, 114, 0, 116, 117, 0, 118, 119, + 120, 121, 122, 123, 0, 0, 124, 125, 126, 127, + 128, 0, 129, 130, 131, 132, 133, 0, 0, 0, + 135, 136, 137, 138, 139, 140, 0, 142, 143, 144, + 0, 145, 146, 147, 148, 149, 150, 0, 0, 152, + 153, 154, 0, 0, 0, 0, 0, 0, 0, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 0, + 166, 0, 167, 168, 169, 170, 171, 172, 0, 173, + 174, 175, 176, 177, 0, 0, 178, 179, 180, 181, + 182, 0, 183, 184, 185, 0, 186, 187, 188, 0, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 0, 199, 0, 200, 201, 202, 203, 0, 204, 0, + 205, 0, 0, 0, 208, 209, 210, 0, 212, 0, + 213, 0, 214, 215, 216, 0, 217, 218, 219, 220, + 221, 623, 223, 0, 225, 226, 227, 228, 0, 229, + 230, 231, 232, 233, 234, 0, 235, 0, 237, 238, + 239, 240, 241, 242, 243, 244, 0, 245, 0, 246, + 0, 0, 249, 0, 251, 252, 253, 254, 255, 0, + 0, 256, 0, 258, 0, 0, 260, 261, 262, 0, + 0, 263, 264, 265, 266, 267, 500, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 287, 0, 289, 290, 291, + 292, 293, 0, 294, 295, 0, 297, 0, 298, 299, + 300, 301, 302, 303, 0, 304, 305, 0, 580, 306, + 307, 308, 0, 0, 309, 310, 0, 312, 0, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 0, 325, 326, 327, 328, 329, 330, 331, 332, 333, + 0, 334, 335, 336, 337, 338, 339, 0, 340, 341, + 342, 343, 344, 345, 346, 347, 0, 348, 349, 350, + 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, + 0, 361, 362, 0, 364, 365, 366, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 0, + 379, 380, 381, 382, 383, 0, 384, 385, 386, 387, + 388, 0, 390, 391, 392, 393, 0, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, 404, 502, 406, + 407, 408, 0, 409, 410, 0, 411, 0, 413, 414, + 415, 416, 417, 0, 418, 419, 0, 0, 420, 421, + 422, 423, 424, 0, 425, 426, 427, 428, 429, 430, + 431, 432, 0, 0, 433, 434, 435, 436, 437, 0, + 0, 438, 439, 440, 441, 442, 443, 444, 0, 445, + 0, 447, 448, 449, 450, 0, 0, 451, 0, 0, + 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 742, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 93, 94, 95, + 96, 97, 98, 99, 100, 0, 101, 102, 103, 3, + 4, 0, 0, 0, 0, 0, 104, 105, 0, 106, + 107, 108, 0, 110, 111, 112, 743, 744, 0, 745, + 746, 0, 118, 119, 120, 121, 122, 123, 0, 0, + 124, 125, 747, 748, 128, 0, 129, 130, 131, 132, + 749, 0, 0, 0, 135, 136, 137, 138, 139, 140, + 0, 142, 143, 144, 0, 145, 146, 147, 148, 149, + 150, 0, 0, 152, 153, 154, 0, 0, 0, 0, + 0, 0, 0, 156, 157, 158, 159, 160, 161, 162, + 750, 751, 165, 0, 166, 0, 167, 168, 169, 170, + 171, 172, 0, 173, 174, 175, 176, 177, 0, 0, + 178, 179, 180, 181, 182, 0, 183, 184, 185, 0, + 186, 187, 188, 0, 189, 190, 191, 192, 752, 194, + 195, 196, 197, 753, 0, 199, 0, 200, 201, 754, + 203, 0, 204, 0, 205, 0, 0, 0, 208, 209, + 210, 0, 212, 0, 213, 0, 755, 756, 216, 0, + 217, 218, 219, 220, 221, 222, 223, 0, 225, 226, + 227, 228, 0, 229, 230, 231, 232, 233, 234, 0, + 235, 0, 757, 238, 239, 240, 241, 242, 758, 759, + 0, 760, 0, 246, 0, 0, 249, 0, 251, 252, + 253, 254, 255, 0, 0, 256, 0, 258, 0, 0, + 260, 261, 262, 0, 0, 263, 264, 265, 266, 267, + 761, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 762, + 0, 763, 290, 291, 292, 764, 0, 294, 295, 0, + 297, 0, 765, 299, 766, 301, 302, 303, 0, 304, + 305, 0, 0, 306, 307, 308, 0, 0, 309, 767, + 0, 312, 0, 768, 315, 316, 317, 318, 319, 320, + 321, 322, 323, 324, 0, 325, 326, 769, 328, 329, + 770, 331, 332, 333, 0, 334, 335, 336, 337, 338, + 339, 0, 340, 341, 342, 771, 344, 345, 346, 347, + 0, 348, 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 0, 361, 362, 0, 364, 365, + 366, 772, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 0, 379, 380, 381, 382, 383, 0, + 384, 773, 386, 387, 388, 0, 390, 391, 774, 393, + 0, 394, 395, 396, 397, 398, 399, 400, 401, 402, + 403, 404, 775, 406, 776, 408, 0, 409, 410, 0, + 411, 0, 413, 414, 415, 416, 417, 0, 777, 778, + 0, 0, 420, 421, 779, 423, 780, 0, 425, 426, + 781, 428, 429, 430, 431, 432, 0, 0, 433, 434, + 435, 436, 437, 0, 0, 438, 439, 440, 441, 442, + 1125, 783, 0, 445, 0, 447, 448, 449, 450, 0, + 0, 451, 0, 0, 452, 453, 454, 455, 456, 457, + 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, + 794, 469, 470, 471, 472, 498, 0, 579, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 93, 94, 95, 96, 97, 98, 99, 100, 0, + 101, 102, 103, 0, 0, 0, 0, 0, 0, 0, + 104, 105, 0, 106, 107, 108, 0, 110, 111, 112, + 113, 114, 0, 116, 117, 0, 118, 119, 120, 121, + 122, 123, 0, 0, 124, 125, 126, 127, 128, 0, + 129, 130, 131, 132, 133, 0, 0, 0, 135, 136, + 137, 138, 139, 140, 0, 142, 143, 144, 0, 145, + 146, 147, 148, 149, 150, 0, 0, 152, 153, 154, + 0, 0, 0, 0, 0, 0, 0, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 0, 166, 0, + 167, 168, 169, 170, 171, 172, 0, 173, 174, 175, + 176, 177, 0, 0, 178, 179, 180, 181, 182, 0, + 183, 184, 185, 0, 186, 187, 188, 0, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 0, 199, + 0, 200, 201, 202, 203, 0, 204, 0, 205, 0, + 0, 0, 208, 209, 210, 0, 1727, 0, 213, 0, + 214, 215, 216, 0, 217, 218, 219, 220, 221, 222, + 223, 0, 225, 226, 227, 228, 0, 229, 230, 231, + 232, 233, 234, 0, 235, 0, 237, 238, 239, 240, + 241, 242, 243, 244, 0, 245, 0, 246, 0, 0, + 249, 0, 251, 252, 253, 254, 255, 0, 0, 256, + 0, 258, 0, 0, 260, 261, 1728, 0, 0, 263, + 264, 265, 266, 267, 500, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + 284, 285, 286, 287, 0, 289, 290, 291, 292, 293, + 0, 294, 295, 0, 297, 0, 298, 299, 300, 301, + 302, 303, 0, 304, 305, 0, 0, 306, 307, 308, + 0, 0, 309, 310, 0, 312, 0, 314, 315, 316, + 317, 318, 319, 320, 321, 322, 323, 324, 0, 325, + 326, 327, 328, 329, 330, 331, 332, 333, 0, 334, + 335, 336, 337, 338, 339, 0, 340, 341, 342, 343, + 344, 345, 346, 347, 0, 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 0, 361, + 362, 0, 364, 365, 366, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 0, 379, 380, + 381, 382, 383, 0, 384, 385, 386, 387, 388, 0, + 390, 391, 392, 393, 0, 394, 395, 396, 397, 398, + 399, 400, 401, 402, 403, 404, 502, 406, 407, 408, + 0, 409, 410, 1729, 411, 0, 413, 1730, 415, 1731, + 417, 0, 418, 419, 0, 0, 420, 421, 422, 423, + 424, 0, 425, 426, 427, 428, 429, 430, 431, 432, + 0, 0, 433, 434, 1732, 436, 437, 0, 0, 438, + 439, 440, 441, 442, 443, 444, 0, 445, 0, 447, + 448, 449, 450, 0, 0, 451, 0, 0, 452, 453, + 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 498, + 2662, 0, 0, 0, 0, 2663, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 93, 94, 95, 96, 97, + 98, 99, 100, 0, 101, 102, 103, 0, 0, 0, + 0, 0, 0, 0, 104, 105, 0, 106, 107, 108, + 0, 110, 111, 112, 113, 114, 0, 116, 117, 0, + 118, 119, 120, 121, 122, 123, 0, 0, 124, 125, + 126, 127, 128, 0, 129, 130, 131, 132, 133, 0, + 0, 0, 135, 136, 137, 138, 139, 140, 0, 142, + 143, 144, 0, 145, 146, 147, 148, 149, 150, 0, + 0, 152, 153, 154, 0, 0, 0, 0, 0, 0, + 0, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 0, 166, 0, 167, 168, 169, 170, 171, 172, + 0, 173, 174, 175, 176, 177, 0, 0, 178, 179, + 180, 181, 182, 0, 183, 184, 185, 0, 186, 187, + 188, 0, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 0, 199, 0, 200, 201, 202, 203, 0, + 204, 0, 205, 0, 0, 0, 208, 209, 210, 0, + 212, 0, 213, 0, 214, 215, 216, 0, 217, 218, + 219, 220, 221, 222, 223, 0, 225, 226, 227, 228, + 0, 229, 230, 231, 232, 233, 234, 0, 235, 0, + 237, 238, 239, 240, 241, 242, 243, 244, 0, 245, + 0, 246, 0, 0, 249, 0, 251, 252, 253, 254, + 255, 0, 0, 256, 0, 258, 0, 0, 260, 261, + 262, 0, 0, 263, 264, 265, 266, 267, 500, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 287, 0, 289, + 290, 291, 292, 293, 0, 294, 295, 0, 297, 0, + 298, 299, 300, 301, 302, 303, 0, 304, 305, 0, + 0, 306, 307, 308, 0, 0, 309, 310, 0, 312, + 0, 314, 315, 316, 317, 318, 319, 320, 321, 322, + 323, 324, 0, 325, 326, 327, 328, 329, 330, 331, + 332, 333, 0, 334, 335, 336, 337, 338, 339, 0, + 340, 341, 342, 343, 344, 345, 346, 347, 0, 348, + 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, + 359, 360, 0, 361, 362, 0, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, - -1, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 388, 389, 390, 391, 392, 393, -1, 395, 396, -1, - 398, 399, 400, 401, 402, 403, 404, -1, 406, 407, - -1, -1, 410, 411, 412, 413, 414, 415, 416, 417, - 418, 419, 420, 421, 422, 423, -1, -1, 426, 427, - 428, 429, 430, 431, -1, 433, 434, 435, 436, 437, - 438, 439, -1, 441, 442, 443, 444, 445, 446, -1, - -1, 449, -1, -1, 452, 453, 454, 455, 456, 457, + 378, 0, 379, 380, 381, 382, 383, 0, 384, 385, + 386, 387, 388, 0, 390, 391, 392, 393, 0, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 502, 406, 407, 408, 0, 409, 410, 0, 411, 0, + 413, 414, 415, 416, 417, 0, 418, 419, 0, 0, + 420, 421, 422, 423, 424, 0, 425, 426, 427, 428, + 429, 430, 431, 432, 0, 0, 433, 434, 435, 436, + 437, 0, 0, 438, 439, 440, 441, 442, 443, 444, + 0, 445, 0, 447, 448, 449, 450, 0, 0, 451, + 0, 0, 452, 453, 454, 455, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 498, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, + 94, 95, 96, 97, 98, 99, 100, 499, 101, 102, + 103, 0, 0, 0, 0, 0, 0, 0, 104, 105, + 0, 106, 107, 108, 0, 110, 111, 112, 113, 114, + 0, 116, 117, 0, 118, 119, 120, 121, 122, 123, + 0, 0, 124, 125, 126, 127, 128, 0, 129, 130, + 131, 132, 133, 0, 0, 0, 135, 136, 137, 138, + 139, 140, 0, 142, 143, 144, 0, 145, 146, 147, + 148, 149, 150, 0, 0, 152, 153, 154, 0, 0, + 0, 0, 0, 0, 0, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 0, 166, 0, 167, 168, + 169, 170, 171, 172, 0, 173, 174, 175, 176, 177, + 0, 0, 178, 179, 180, 181, 182, 0, 183, 184, + 185, 0, 186, 187, 188, 0, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 0, 199, 0, 200, + 201, 202, 203, 0, 204, 0, 205, 0, 0, 0, + 208, 209, 210, 0, 212, 0, 213, 0, 214, 215, + 216, 0, 217, 218, 219, 220, 221, 222, 223, 0, + 225, 226, 227, 228, 0, 229, 230, 231, 232, 233, + 234, 0, 235, 0, 237, 238, 239, 240, 241, 242, + 243, 244, 0, 245, 0, 246, 0, 0, 249, 0, + 251, 252, 253, 254, 255, 0, 0, 256, 0, 258, + 0, 0, 260, 261, 262, 0, 0, 263, 264, 265, + 266, 267, 500, 269, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, + 286, 287, 0, 289, 290, 291, 292, 293, 0, 294, + 295, 0, 297, 0, 298, 299, 300, 301, 302, 303, + 0, 304, 305, 0, 0, 306, 307, 308, 0, 0, + 309, 310, 0, 312, 0, 314, 315, 316, 317, 318, + 319, 320, 321, 322, 323, 324, 0, 325, 326, 327, + 328, 329, 330, 501, 332, 333, 0, 334, 335, 336, + 337, 338, 339, 0, 340, 341, 342, 343, 344, 345, + 346, 347, 0, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 0, 361, 362, 0, + 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 0, 379, 380, 381, 382, + 383, 0, 384, 385, 386, 387, 388, 0, 390, 391, + 392, 393, 0, 394, 395, 396, 397, 398, 399, 400, + 401, 402, 403, 404, 502, 406, 407, 408, 0, 409, + 410, 0, 411, 0, 413, 414, 415, 416, 417, 0, + 418, 419, 0, 0, 420, 421, 422, 423, 424, 0, + 425, 426, 427, 428, 429, 430, 431, 432, 0, 0, + 433, 434, 435, 436, 437, 0, 0, 438, 439, 440, + 441, 442, 443, 444, 0, 445, 0, 447, 448, 449, + 450, 0, 0, 451, 0, 0, 452, 453, 454, 455, + 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 498, 0, 547, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 93, 94, 95, 96, 97, 98, 99, + 100, 0, 101, 102, 103, 0, 0, 0, 0, 0, + 0, 0, 104, 105, 0, 106, 107, 108, 0, 110, + 111, 112, 113, 114, 0, 116, 117, 0, 118, 119, + 120, 121, 122, 123, 0, 0, 124, 125, 126, 127, + 128, 0, 129, 130, 131, 132, 133, 0, 0, 0, + 135, 136, 137, 138, 139, 140, 0, 142, 143, 144, + 0, 145, 146, 147, 148, 149, 150, 0, 0, 152, + 153, 154, 0, 0, 0, 0, 0, 0, 0, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 0, + 166, 0, 167, 168, 169, 170, 171, 172, 0, 173, + 174, 175, 176, 177, 0, 0, 178, 179, 180, 181, + 182, 0, 183, 184, 185, 0, 186, 187, 188, 0, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 0, 199, 0, 200, 201, 202, 203, 0, 204, 0, + 205, 0, 0, 0, 208, 209, 210, 0, 212, 0, + 213, 0, 214, 215, 216, 0, 217, 218, 219, 220, + 221, 222, 223, 0, 225, 226, 227, 228, 0, 229, + 230, 231, 232, 233, 234, 0, 235, 0, 237, 238, + 239, 240, 241, 242, 243, 244, 0, 245, 0, 246, + 0, 0, 249, 0, 251, 252, 253, 254, 255, 0, + 0, 256, 0, 258, 0, 0, 260, 261, 262, 0, + 0, 263, 264, 265, 266, 267, 500, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 287, 0, 289, 290, 291, + 292, 293, 0, 294, 295, 0, 297, 0, 298, 299, + 300, 301, 302, 303, 0, 304, 305, 0, 0, 306, + 307, 308, 0, 0, 309, 310, 0, 312, 0, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 0, 325, 326, 327, 328, 329, 330, 331, 332, 333, + 0, 334, 335, 336, 337, 338, 339, 0, 340, 341, + 342, 343, 344, 345, 346, 347, 0, 348, 349, 350, + 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, + 0, 361, 362, 0, 364, 365, 366, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 0, + 379, 380, 381, 382, 383, 0, 384, 385, 386, 387, + 388, 0, 390, 391, 392, 393, 0, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, 404, 502, 406, + 407, 408, 0, 409, 410, 0, 411, 0, 413, 414, + 415, 416, 417, 0, 418, 419, 0, 0, 420, 421, + 422, 423, 424, 0, 425, 426, 427, 428, 429, 430, + 431, 432, 0, 0, 433, 434, 435, 436, 437, 0, + 0, 438, 439, 440, 441, 442, 443, 444, 0, 445, + 0, 447, 448, 449, 450, 0, 0, 451, 0, 0, + 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 498, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 93, 94, 95, + 96, 97, 98, 99, 100, 554, 101, 102, 103, 0, + 0, 0, 0, 0, 0, 0, 104, 105, 0, 106, + 107, 108, 0, 110, 111, 112, 113, 114, 0, 116, + 117, 0, 118, 119, 120, 121, 122, 123, 0, 0, + 124, 125, 126, 127, 128, 0, 129, 130, 131, 132, + 133, 0, 0, 0, 135, 136, 137, 138, 139, 140, + 0, 142, 143, 144, 0, 145, 146, 147, 148, 149, + 150, 0, 0, 152, 153, 154, 0, 0, 0, 0, + 0, 0, 0, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 0, 166, 0, 167, 168, 169, 170, + 171, 172, 0, 173, 174, 175, 176, 177, 0, 0, + 178, 179, 180, 181, 182, 0, 183, 184, 185, 0, + 186, 187, 188, 0, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 0, 199, 0, 200, 201, 202, + 203, 0, 204, 0, 205, 0, 0, 0, 208, 209, + 210, 0, 212, 0, 213, 0, 214, 215, 216, 0, + 217, 218, 219, 220, 221, 222, 223, 0, 225, 226, + 227, 228, 0, 229, 230, 231, 232, 233, 234, 0, + 235, 0, 237, 238, 239, 240, 241, 242, 243, 244, + 0, 245, 0, 246, 0, 0, 249, 0, 251, 252, + 253, 254, 255, 0, 0, 256, 0, 258, 0, 0, + 260, 261, 262, 0, 0, 263, 264, 265, 266, 267, + 500, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 0, 289, 290, 291, 292, 293, 0, 294, 295, 0, + 297, 0, 298, 299, 300, 301, 302, 303, 0, 304, + 305, 0, 0, 306, 307, 308, 0, 0, 309, 310, + 0, 312, 0, 314, 315, 316, 317, 318, 319, 320, + 321, 322, 323, 324, 0, 325, 326, 327, 328, 329, + 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, + 339, 0, 340, 341, 342, 343, 344, 345, 346, 347, + 0, 348, 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 0, 361, 362, 0, 364, 365, + 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 0, 379, 380, 381, 382, 383, 0, + 384, 385, 386, 387, 388, 0, 390, 391, 392, 393, + 0, 394, 395, 396, 397, 398, 399, 400, 401, 402, + 403, 404, 502, 406, 407, 408, 0, 409, 410, 0, + 411, 0, 413, 414, 415, 416, 417, 0, 555, 419, + 0, 0, 556, 421, 422, 423, 424, 0, 425, 426, + 427, 428, 429, 430, 431, 432, 0, 0, 433, 434, + 435, 436, 437, 0, 0, 438, 439, 440, 441, 442, + 443, 444, 0, 445, 0, 447, 448, 449, 450, 0, + 0, 451, 0, 0, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 471, 472, 473, -1, -1, -1, -1, - -1, -1, 480, 481, -1, -1, -1, -1, -1, 487, - -1, 489, -1, -1, -1, -1, 494, -1, 496, 497, - 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, - -1, -1, -1, -1, -1, -1, 19, 20, 21, 22, - 23, 24, 25, 26, -1, 28, 29, 30, -1, -1, - -1, -1, 35, -1, -1, 38, 39, -1, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - -1, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, -1, 68, 69, 70, 71, 72, - -1, 74, -1, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, -1, 87, 88, 89, 90, 91, 92, - -1, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, -1, 118, 119, 120, 121, 122, - 123, -1, 125, 126, 127, 128, 129, -1, -1, 132, - 133, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, -1, 146, 147, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, -1, 159, 160, 161, 162, - -1, 164, -1, 166, 167, -1, 169, 170, 171, 172, - 173, 174, -1, 176, -1, 178, 179, 180, -1, 182, - 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - -1, 194, 195, 196, 197, 198, 199, -1, 201, 202, - 203, 204, 205, 206, 207, 208, 209, -1, 211, -1, - 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, - -1, -1, 225, 226, 227, 228, -1, 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, -1, -1, - 283, 284, 285, -1, -1, 288, 289, 290, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, - 303, -1, 305, 306, 307, 308, 309, 310, 311, 312, - 313, -1, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, -1, 330, 331, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, -1, - 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 360, -1, 362, - 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, -1, 379, 380, 381, 382, - 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, - 393, -1, 395, 396, -1, 398, 399, 400, 401, 402, - 403, 404, -1, 406, 407, -1, -1, 410, 411, 412, - 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, - 423, -1, -1, 426, 427, 428, 429, 430, 431, -1, - 433, 434, 435, 436, 437, 438, 439, -1, 441, 442, - 443, 444, 445, 446, -1, -1, 449, -1, -1, 452, - 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, - 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, - 473, -1, -1, -1, -1, -1, -1, 480, 481, -1, - -1, -1, -1, -1, 487, -1, 489, 490, -1, -1, - -1, 494, -1, 496, 497, 3, 4, 5, 6, 7, - 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, - -1, 19, 20, 21, 22, 23, 24, 25, 26, -1, - 28, 29, 30, -1, -1, -1, -1, 35, -1, -1, - 38, 39, -1, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, -1, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, -1, - 68, 69, 70, 71, 72, -1, 74, -1, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, -1, 87, - 88, 89, 90, 91, 92, -1, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, -1, - 118, 119, 120, 121, 122, 123, -1, 125, 126, 127, - 128, 129, -1, -1, 132, 133, 134, 135, 136, -1, - 138, 139, 140, -1, 142, 143, 144, -1, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, - -1, 159, 160, 161, 162, -1, 164, -1, 166, 167, - -1, 169, 170, 171, 172, 173, 174, -1, 176, -1, - 178, 179, 180, -1, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, -1, 194, 195, 196, 197, - 198, 199, -1, 201, 202, 203, 204, 205, 206, 207, - 208, 209, -1, 211, -1, 213, 214, 215, 216, 217, - 218, 219, 220, 221, 222, -1, -1, 225, 226, 227, - 228, -1, 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, -1, -1, 283, 284, 285, -1, -1, - 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, - 298, 299, 300, 301, 302, 303, -1, 305, 306, 307, - 308, 309, 310, 311, 312, 313, -1, 315, 316, 317, - 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, - 328, -1, 330, 331, 332, 333, 334, 335, 336, 337, - 338, 339, 340, 341, -1, 343, 344, 345, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, - 358, 359, 360, -1, 362, 363, 364, 365, 366, 367, + 468, 469, 470, 471, 472, 498, 0, 579, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 93, 94, 95, 96, 97, 98, 99, 100, 0, + 101, 102, 103, 0, 0, 0, 0, 0, 0, 0, + 104, 105, 0, 106, 107, 108, 0, 110, 111, 112, + 113, 114, 0, 116, 117, 0, 118, 119, 120, 121, + 122, 123, 0, 0, 124, 125, 126, 127, 128, 0, + 129, 130, 131, 132, 133, 0, 0, 0, 135, 136, + 137, 138, 139, 140, 0, 142, 143, 144, 0, 145, + 146, 147, 148, 149, 150, 0, 0, 152, 153, 154, + 0, 0, 0, 0, 0, 0, 0, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 0, 166, 0, + 167, 168, 169, 170, 171, 172, 0, 173, 174, 175, + 176, 177, 0, 0, 178, 179, 180, 181, 182, 0, + 183, 184, 185, 0, 186, 187, 188, 0, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 0, 199, + 0, 200, 201, 202, 203, 0, 204, 0, 205, 0, + 0, 0, 208, 209, 210, 0, 212, 0, 213, 0, + 214, 215, 216, 0, 217, 218, 219, 220, 221, 618, + 223, 0, 225, 226, 227, 228, 0, 229, 230, 231, + 232, 233, 234, 0, 235, 0, 237, 238, 239, 240, + 241, 242, 243, 244, 0, 245, 0, 246, 0, 0, + 249, 0, 251, 252, 253, 254, 255, 0, 0, 256, + 0, 258, 0, 0, 260, 261, 262, 0, 0, 263, + 264, 265, 266, 267, 500, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + 284, 285, 286, 287, 0, 289, 290, 291, 292, 293, + 0, 294, 295, 0, 297, 0, 298, 299, 300, 301, + 302, 303, 0, 304, 305, 0, 0, 306, 307, 308, + 0, 0, 309, 310, 0, 312, 0, 314, 315, 316, + 317, 318, 319, 320, 321, 322, 323, 324, 0, 325, + 326, 327, 328, 329, 330, 331, 332, 333, 0, 334, + 335, 336, 337, 338, 339, 0, 340, 341, 342, 343, + 344, 345, 346, 347, 0, 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 0, 361, + 362, 0, 364, 365, 366, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 0, 379, 380, + 381, 382, 383, 0, 384, 385, 386, 387, 388, 0, + 390, 391, 392, 393, 0, 394, 395, 396, 397, 398, + 399, 400, 401, 402, 403, 404, 502, 406, 407, 408, + 0, 409, 410, 0, 411, 0, 413, 414, 415, 416, + 417, 0, 418, 419, 0, 0, 420, 421, 422, 423, + 424, 0, 425, 426, 427, 428, 429, 430, 431, 432, + 0, 0, 433, 434, 435, 436, 437, 0, 0, 438, + 439, 440, 441, 442, 443, 444, 0, 445, 0, 447, + 448, 449, 450, 0, 0, 451, 0, 0, 452, 453, + 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 498, + 0, 579, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 93, 94, 95, 96, 97, + 98, 99, 100, 0, 101, 102, 103, 0, 0, 0, + 0, 0, 0, 0, 104, 105, 0, 106, 107, 108, + 0, 110, 111, 112, 113, 114, 0, 116, 117, 0, + 118, 119, 120, 121, 122, 123, 0, 0, 124, 125, + 126, 127, 128, 0, 129, 130, 131, 132, 133, 0, + 0, 0, 135, 136, 137, 138, 139, 140, 0, 142, + 143, 144, 0, 145, 146, 147, 148, 149, 150, 0, + 0, 152, 153, 154, 0, 0, 0, 0, 0, 0, + 0, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 0, 166, 0, 167, 168, 169, 170, 171, 172, + 0, 173, 174, 175, 176, 177, 0, 0, 178, 179, + 180, 181, 182, 0, 183, 184, 185, 0, 186, 187, + 188, 0, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 0, 199, 0, 200, 201, 202, 203, 0, + 204, 0, 205, 0, 0, 0, 208, 209, 210, 0, + 212, 0, 213, 0, 214, 215, 216, 0, 217, 218, + 219, 220, 221, 621, 223, 0, 225, 226, 227, 228, + 0, 229, 230, 231, 232, 233, 234, 0, 235, 0, + 237, 238, 239, 240, 241, 242, 243, 244, 0, 245, + 0, 246, 0, 0, 249, 0, 251, 252, 253, 254, + 255, 0, 0, 256, 0, 258, 0, 0, 260, 261, + 262, 0, 0, 263, 264, 265, 266, 267, 500, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 287, 0, 289, + 290, 291, 292, 293, 0, 294, 295, 0, 297, 0, + 298, 299, 300, 301, 302, 303, 0, 304, 305, 0, + 0, 306, 307, 308, 0, 0, 309, 310, 0, 312, + 0, 314, 315, 316, 317, 318, 319, 320, 321, 322, + 323, 324, 0, 325, 326, 327, 328, 329, 330, 331, + 332, 333, 0, 334, 335, 336, 337, 338, 339, 0, + 340, 341, 342, 343, 344, 345, 346, 347, 0, 348, + 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, + 359, 360, 0, 361, 362, 0, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, - -1, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 388, 389, 390, 391, 392, 393, -1, 395, 396, -1, - 398, 399, 400, 401, 402, 403, 404, -1, 406, 407, - -1, -1, 410, 411, 412, 413, 414, 415, 416, 417, - 418, 419, 420, 421, 422, 423, -1, -1, 426, 427, - 428, 429, 430, 431, -1, 433, 434, 435, 436, 437, - 438, 439, -1, 441, 442, 443, 444, 445, 446, -1, - -1, 449, -1, -1, 452, 453, 454, 455, 456, 457, + 378, 0, 379, 380, 381, 382, 383, 0, 384, 385, + 386, 387, 388, 0, 390, 391, 392, 393, 0, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 502, 406, 407, 408, 0, 409, 410, 0, 411, 0, + 413, 414, 415, 416, 417, 0, 418, 419, 0, 0, + 420, 421, 422, 423, 424, 0, 425, 426, 427, 428, + 429, 430, 431, 432, 0, 0, 433, 434, 435, 436, + 437, 0, 0, 438, 439, 440, 441, 442, 443, 444, + 0, 445, 0, 447, 448, 449, 450, 0, 0, 451, + 0, 0, 452, 453, 454, 455, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 498, 0, 579, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, + 94, 95, 96, 97, 98, 99, 100, 0, 101, 102, + 103, 0, 0, 0, 0, 0, 0, 0, 104, 105, + 0, 106, 107, 108, 0, 110, 111, 112, 113, 114, + 0, 116, 117, 0, 118, 119, 120, 121, 122, 123, + 0, 0, 124, 125, 126, 127, 128, 0, 129, 130, + 131, 132, 133, 0, 0, 0, 135, 136, 137, 138, + 139, 140, 0, 142, 143, 144, 0, 145, 146, 147, + 148, 149, 150, 0, 0, 152, 153, 154, 0, 0, + 0, 0, 0, 0, 0, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 0, 166, 0, 167, 168, + 169, 170, 171, 172, 0, 173, 174, 175, 176, 177, + 0, 0, 178, 179, 180, 181, 182, 0, 183, 184, + 185, 0, 186, 187, 188, 0, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 0, 199, 0, 200, + 201, 202, 203, 0, 204, 0, 205, 0, 0, 0, + 208, 209, 210, 0, 212, 0, 213, 0, 214, 215, + 216, 0, 217, 218, 219, 220, 221, 625, 223, 0, + 225, 226, 227, 228, 0, 229, 230, 231, 232, 233, + 234, 0, 235, 0, 237, 238, 239, 240, 241, 242, + 243, 244, 0, 245, 0, 246, 0, 0, 249, 0, + 251, 252, 253, 254, 255, 0, 0, 256, 0, 258, + 0, 0, 260, 261, 262, 0, 0, 263, 264, 265, + 266, 267, 500, 269, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, + 286, 287, 0, 289, 290, 291, 292, 293, 0, 294, + 295, 0, 297, 0, 298, 299, 300, 301, 302, 303, + 0, 304, 305, 0, 0, 306, 307, 308, 0, 0, + 309, 310, 0, 312, 0, 314, 315, 316, 317, 318, + 319, 320, 321, 322, 323, 324, 0, 325, 326, 327, + 328, 329, 330, 331, 332, 333, 0, 334, 335, 336, + 337, 338, 339, 0, 340, 341, 342, 343, 344, 345, + 346, 347, 0, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 0, 361, 362, 0, + 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 0, 379, 380, 381, 382, + 383, 0, 384, 385, 386, 387, 388, 0, 390, 391, + 392, 393, 0, 394, 395, 396, 397, 398, 399, 400, + 401, 402, 403, 404, 502, 406, 407, 408, 0, 409, + 410, 0, 411, 0, 413, 414, 415, 416, 417, 0, + 418, 419, 0, 0, 420, 421, 422, 423, 424, 0, + 425, 426, 427, 428, 429, 430, 431, 432, 0, 0, + 433, 434, 435, 436, 437, 0, 0, 438, 439, 440, + 441, 442, 443, 444, 0, 445, 0, 447, 448, 449, + 450, 0, 0, 451, 0, 0, 452, 453, 454, 455, + 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 498, 0, 579, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 93, 94, 95, 96, 97, 98, 99, + 100, 0, 101, 102, 103, 0, 0, 0, 0, 0, + 0, 0, 104, 105, 0, 106, 107, 108, 0, 110, + 111, 112, 113, 114, 0, 116, 117, 0, 118, 119, + 120, 121, 122, 123, 0, 0, 124, 125, 126, 127, + 128, 0, 129, 130, 131, 132, 133, 0, 0, 0, + 135, 136, 137, 138, 139, 140, 0, 142, 143, 144, + 0, 145, 146, 147, 148, 149, 150, 0, 0, 152, + 153, 154, 0, 0, 0, 0, 0, 0, 0, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 0, + 166, 0, 167, 168, 169, 170, 171, 172, 0, 173, + 174, 175, 176, 177, 0, 0, 178, 179, 180, 181, + 182, 0, 183, 184, 185, 0, 186, 187, 188, 0, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 0, 199, 0, 200, 201, 202, 203, 0, 204, 0, + 205, 0, 0, 0, 208, 209, 210, 0, 212, 0, + 213, 0, 214, 215, 216, 0, 217, 218, 219, 220, + 221, 222, 223, 0, 225, 226, 227, 228, 0, 229, + 230, 231, 232, 233, 234, 0, 235, 0, 237, 238, + 239, 240, 241, 242, 243, 244, 0, 245, 0, 246, + 0, 0, 249, 0, 251, 252, 253, 254, 255, 0, + 0, 256, 0, 258, 0, 0, 260, 261, 262, 0, + 0, 263, 264, 265, 266, 267, 500, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 287, 0, 289, 290, 291, + 292, 293, 0, 294, 295, 0, 297, 0, 298, 299, + 300, 301, 302, 303, 0, 304, 305, 0, 0, 306, + 307, 308, 0, 0, 309, 310, 0, 312, 0, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 0, 325, 326, 327, 328, 329, 330, 331, 332, 333, + 0, 334, 335, 336, 337, 338, 339, 0, 340, 341, + 342, 343, 344, 345, 346, 347, 0, 348, 349, 350, + 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, + 0, 361, 362, 0, 364, 365, 366, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 0, + 379, 380, 381, 382, 383, 0, 384, 385, 386, 387, + 388, 0, 390, 391, 392, 393, 0, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, 404, 502, 406, + 407, 408, 0, 409, 410, 0, 411, 0, 413, 414, + 415, 416, 417, 0, 418, 419, 0, 0, 420, 421, + 422, 423, 424, 0, 425, 426, 427, 428, 429, 430, + 431, 432, 0, 0, 433, 434, 435, 436, 437, 0, + 0, 438, 439, 440, 441, 442, 443, 444, 0, 445, + 0, 447, 448, 449, 450, 0, 0, 451, 0, 0, + 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 498, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 93, 94, 95, + 96, 97, 98, 99, 100, 653, 101, 102, 103, 0, + 0, 0, 0, 0, 0, 0, 104, 105, 0, 106, + 107, 108, 0, 110, 111, 112, 113, 114, 0, 116, + 117, 0, 118, 119, 120, 121, 122, 123, 0, 0, + 124, 125, 126, 127, 128, 0, 129, 130, 131, 132, + 133, 0, 0, 0, 135, 136, 137, 138, 139, 140, + 0, 142, 143, 144, 0, 145, 146, 147, 148, 149, + 150, 0, 0, 152, 153, 154, 0, 0, 0, 0, + 0, 0, 0, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 0, 166, 0, 167, 168, 169, 170, + 171, 172, 0, 173, 174, 175, 176, 177, 0, 0, + 178, 179, 180, 181, 182, 0, 183, 184, 185, 0, + 186, 187, 188, 0, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 0, 199, 0, 200, 201, 202, + 203, 0, 204, 0, 205, 0, 0, 0, 208, 209, + 210, 0, 212, 0, 213, 0, 214, 215, 216, 0, + 217, 218, 219, 220, 221, 222, 223, 0, 225, 226, + 227, 228, 0, 229, 230, 231, 232, 233, 234, 0, + 235, 0, 237, 238, 239, 240, 241, 242, 243, 244, + 0, 245, 0, 246, 0, 0, 249, 0, 251, 252, + 253, 254, 255, 0, 0, 256, 0, 258, 0, 0, + 260, 261, 262, 0, 0, 263, 264, 265, 266, 267, + 500, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 0, 289, 290, 291, 292, 293, 0, 294, 295, 0, + 297, 0, 298, 299, 300, 301, 302, 303, 0, 304, + 305, 0, 0, 306, 307, 308, 0, 0, 309, 310, + 0, 312, 0, 314, 315, 316, 317, 318, 319, 320, + 321, 322, 323, 324, 0, 325, 326, 327, 328, 329, + 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, + 339, 0, 340, 341, 342, 343, 344, 345, 346, 347, + 0, 348, 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 0, 361, 362, 0, 364, 365, + 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 0, 379, 380, 381, 382, 383, 0, + 384, 385, 386, 387, 388, 0, 390, 391, 392, 393, + 0, 394, 395, 396, 397, 398, 399, 400, 401, 402, + 403, 404, 502, 406, 407, 408, 0, 409, 410, 0, + 411, 0, 413, 414, 415, 416, 417, 0, 418, 419, + 0, 0, 420, 421, 422, 423, 424, 0, 425, 426, + 427, 428, 429, 430, 431, 432, 0, 0, 433, 434, + 435, 436, 437, 0, 0, 438, 439, 440, 441, 442, + 443, 444, 0, 445, 0, 447, 448, 449, 450, 0, + 0, 451, 0, 0, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 471, 472, 473, -1, -1, -1, -1, - -1, -1, 480, 481, -1, -1, -1, -1, -1, 487, - -1, 489, 490, -1, -1, -1, 494, -1, 496, 497, - 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, - -1, -1, -1, -1, -1, -1, 19, 20, 21, 22, - 23, 24, 25, 26, -1, 28, 29, 30, -1, -1, - -1, -1, 35, -1, -1, 38, 39, -1, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - -1, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, -1, 68, 69, 70, 71, 72, - -1, 74, -1, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, -1, 87, 88, 89, 90, 91, 92, - -1, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, -1, 118, 119, 120, 121, 122, - 123, -1, 125, 126, 127, 128, 129, -1, -1, 132, - 133, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, -1, 146, 147, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, -1, 159, 160, 161, 162, - -1, 164, -1, 166, 167, -1, 169, 170, 171, 172, - 173, 174, -1, 176, -1, 178, 179, 180, -1, 182, - 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - -1, 194, 195, 196, 197, 198, 199, -1, 201, 202, - 203, 204, 205, 206, 207, 208, 209, -1, 211, -1, - 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, - -1, -1, 225, 226, 227, 228, -1, 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, -1, -1, - 283, 284, 285, -1, -1, 288, 289, 290, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, - 303, -1, 305, 306, 307, 308, 309, 310, 311, 312, - 313, -1, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, -1, 330, 331, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, -1, - 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 360, -1, 362, - 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, -1, 379, 380, 381, 382, - 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, - 393, -1, 395, 396, -1, 398, 399, 400, 401, 402, - 403, 404, -1, 406, 407, -1, -1, 410, 411, 412, - 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, - 423, -1, -1, 426, 427, 428, 429, 430, 431, -1, - 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, - 443, 444, 445, 446, -1, -1, 449, -1, -1, 452, - 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, - 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, - 473, -1, -1, -1, -1, -1, -1, 480, 481, -1, - -1, -1, -1, -1, 487, -1, 489, -1, -1, -1, - -1, 494, -1, 496, 497, 3, 4, 5, 6, 7, - 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, - -1, 19, 20, 21, 22, 23, 24, 25, 26, -1, - 28, 29, 30, -1, -1, -1, -1, 35, -1, -1, - 38, 39, -1, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, -1, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, -1, - 68, 69, 70, 71, 72, -1, 74, -1, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, -1, 87, - 88, 89, 90, 91, 92, -1, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, -1, - 118, 119, 120, 121, 122, 123, -1, 125, 126, 127, - 128, 129, -1, -1, 132, 133, 134, 135, 136, -1, - 138, 139, 140, -1, 142, 143, 144, -1, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, - -1, 159, 160, 161, 162, -1, 164, -1, 166, 167, - 168, 169, 170, 171, 172, 173, 174, -1, 176, -1, - 178, 179, 180, -1, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, -1, 194, 195, 196, 197, - 198, 199, -1, 201, 202, 203, 204, 205, 206, 207, - 208, 209, -1, 211, -1, 213, 214, 215, 216, 217, - 218, 219, 220, 221, 222, -1, -1, 225, 226, 227, - 228, -1, 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, -1, -1, 283, 284, 285, -1, -1, - 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, - 298, 299, 300, 301, 302, 303, -1, 305, 306, 307, - 308, 309, 310, 311, 312, 313, -1, 315, 316, 317, - 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, - 328, -1, 330, 331, 332, 333, 334, 335, 336, 337, - 338, 339, 340, 341, -1, 343, 344, 345, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, - 358, 359, 360, -1, 362, 363, 364, 365, 366, 367, + 468, 469, 470, 471, 472, 498, 0, 579, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 93, 94, 95, 96, 97, 98, 99, 100, 0, + 101, 102, 103, 0, 0, 0, 0, 0, 0, 0, + 104, 105, 0, 106, 107, 108, 0, 110, 111, 112, + 113, 114, 0, 116, 117, 0, 118, 119, 120, 121, + 122, 123, 0, 0, 124, 125, 126, 127, 128, 0, + 129, 130, 131, 132, 133, 0, 0, 0, 135, 136, + 137, 138, 139, 140, 0, 142, 143, 144, 0, 145, + 146, 147, 148, 149, 150, 0, 0, 152, 153, 154, + 0, 0, 0, 0, 0, 0, 0, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 0, 166, 0, + 167, 168, 169, 170, 171, 172, 0, 173, 174, 175, + 176, 177, 0, 0, 178, 179, 180, 181, 182, 0, + 183, 184, 185, 0, 186, 187, 188, 0, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 0, 199, + 0, 200, 201, 202, 203, 0, 204, 0, 205, 0, + 0, 0, 208, 209, 210, 0, 212, 0, 213, 0, + 214, 215, 216, 0, 217, 218, 219, 220, 221, 1147, + 223, 0, 225, 226, 227, 228, 0, 229, 230, 231, + 232, 233, 234, 0, 235, 0, 237, 238, 239, 240, + 241, 242, 243, 244, 0, 245, 0, 246, 0, 0, + 249, 0, 251, 252, 253, 254, 255, 0, 0, 256, + 0, 258, 0, 0, 260, 261, 262, 0, 0, 263, + 264, 265, 266, 267, 500, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + 284, 285, 286, 287, 0, 289, 290, 291, 292, 293, + 0, 294, 295, 0, 297, 0, 298, 299, 300, 301, + 302, 303, 0, 304, 305, 0, 0, 306, 307, 308, + 0, 0, 309, 310, 0, 312, 0, 314, 315, 316, + 317, 318, 319, 320, 321, 322, 323, 324, 0, 325, + 326, 327, 328, 329, 330, 331, 332, 333, 0, 334, + 335, 336, 337, 338, 339, 0, 340, 341, 342, 343, + 344, 345, 346, 347, 0, 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 0, 361, + 362, 0, 364, 365, 366, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 0, 379, 380, + 381, 382, 383, 0, 384, 385, 386, 387, 388, 0, + 390, 391, 392, 393, 0, 394, 395, 396, 397, 398, + 399, 400, 401, 402, 403, 404, 502, 406, 407, 408, + 0, 409, 410, 0, 411, 0, 413, 414, 415, 416, + 417, 0, 418, 419, 0, 0, 420, 421, 422, 423, + 424, 0, 425, 426, 427, 428, 429, 430, 431, 432, + 0, 0, 433, 434, 435, 436, 437, 0, 0, 438, + 439, 440, 441, 442, 443, 444, 0, 445, 0, 447, + 448, 449, 450, 0, 0, 451, 0, 0, 452, 453, + 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 498, + 0, 579, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 93, 94, 95, 96, 97, + 98, 99, 100, 0, 101, 102, 103, 0, 0, 0, + 0, 0, 0, 0, 104, 105, 0, 106, 107, 108, + 0, 110, 111, 112, 113, 114, 0, 116, 117, 0, + 118, 119, 120, 121, 122, 123, 0, 0, 124, 125, + 126, 127, 128, 0, 129, 130, 131, 132, 133, 0, + 0, 0, 135, 136, 137, 138, 139, 140, 0, 142, + 143, 144, 0, 145, 146, 147, 148, 149, 150, 0, + 0, 152, 153, 154, 0, 0, 0, 0, 0, 0, + 0, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 0, 166, 0, 167, 168, 169, 170, 171, 172, + 0, 173, 174, 175, 176, 177, 0, 0, 178, 179, + 180, 181, 182, 0, 183, 184, 185, 0, 186, 187, + 188, 0, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 0, 199, 0, 200, 201, 202, 203, 0, + 204, 0, 205, 0, 0, 0, 208, 209, 210, 0, + 212, 0, 213, 0, 214, 215, 216, 0, 217, 218, + 219, 220, 221, 1149, 223, 0, 225, 226, 227, 228, + 0, 229, 230, 231, 232, 233, 234, 0, 235, 0, + 237, 238, 239, 240, 241, 242, 243, 244, 0, 245, + 0, 246, 0, 0, 249, 0, 251, 252, 253, 254, + 255, 0, 0, 256, 0, 258, 0, 0, 260, 261, + 262, 0, 0, 263, 264, 265, 266, 267, 500, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 287, 0, 289, + 290, 291, 292, 293, 0, 294, 295, 0, 297, 0, + 298, 299, 300, 301, 302, 303, 0, 304, 305, 0, + 0, 306, 307, 308, 0, 0, 309, 310, 0, 312, + 0, 314, 315, 316, 317, 318, 319, 320, 321, 322, + 323, 324, 0, 325, 326, 327, 328, 329, 330, 331, + 332, 333, 0, 334, 335, 336, 337, 338, 339, 0, + 340, 341, 342, 343, 344, 345, 346, 347, 0, 348, + 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, + 359, 360, 0, 361, 362, 0, 364, 365, 366, 367, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 0, 379, 380, 381, 382, 383, 0, 384, 385, + 386, 387, 388, 0, 390, 391, 392, 393, 0, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 502, 406, 407, 408, 0, 409, 410, 0, 411, 0, + 413, 414, 415, 416, 417, 0, 418, 419, 0, 0, + 420, 421, 422, 423, 424, 0, 425, 426, 427, 428, + 429, 430, 431, 432, 0, 0, 433, 434, 435, 436, + 437, 0, 0, 438, 439, 440, 441, 442, 443, 444, + 0, 445, 0, 447, 448, 449, 450, 0, 0, 451, + 0, 0, 452, 453, 454, 455, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 498, 0, 579, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, + 94, 95, 96, 97, 98, 99, 100, 0, 101, 102, + 103, 0, 0, 0, 0, 0, 0, 0, 104, 105, + 0, 106, 107, 108, 0, 110, 111, 112, 113, 114, + 0, 116, 117, 0, 118, 119, 120, 121, 122, 123, + 0, 0, 124, 125, 126, 127, 128, 0, 129, 130, + 131, 132, 133, 0, 0, 0, 135, 136, 137, 138, + 139, 140, 0, 142, 143, 144, 0, 145, 146, 147, + 148, 149, 150, 0, 0, 152, 153, 154, 0, 0, + 0, 0, 0, 0, 0, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 0, 166, 0, 167, 168, + 169, 170, 171, 172, 0, 173, 174, 175, 176, 177, + 0, 0, 178, 179, 180, 181, 182, 0, 183, 184, + 185, 0, 186, 187, 188, 0, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 0, 199, 0, 200, + 201, 202, 203, 0, 204, 0, 205, 0, 0, 0, + 208, 209, 210, 0, 212, 0, 213, 0, 214, 215, + 216, 0, 217, 218, 219, 220, 221, 1559, 223, 0, + 225, 226, 227, 228, 0, 229, 230, 231, 232, 233, + 234, 0, 235, 0, 237, 238, 239, 240, 241, 242, + 243, 244, 0, 245, 0, 246, 0, 0, 249, 0, + 251, 252, 253, 254, 255, 0, 0, 256, 0, 258, + 0, 0, 260, 261, 262, 0, 0, 263, 264, 265, + 266, 267, 500, 269, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, + 286, 287, 0, 289, 290, 291, 292, 293, 0, 294, + 295, 0, 297, 0, 298, 299, 300, 301, 302, 303, + 0, 304, 305, 0, 0, 306, 307, 308, 0, 0, + 309, 310, 0, 312, 0, 314, 315, 316, 317, 318, + 319, 320, 321, 322, 323, 324, 0, 325, 326, 327, + 328, 329, 330, 331, 332, 333, 0, 334, 335, 336, + 337, 338, 339, 0, 340, 341, 342, 343, 344, 345, + 346, 347, 0, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 0, 361, 362, 0, + 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 0, 379, 380, 381, 382, + 383, 0, 384, 385, 386, 387, 388, 0, 390, 391, + 392, 393, 0, 394, 395, 396, 397, 398, 399, 400, + 401, 402, 403, 404, 502, 406, 407, 408, 0, 409, + 410, 0, 411, 0, 413, 414, 415, 416, 417, 0, + 418, 419, 0, 0, 420, 421, 422, 423, 424, 0, + 425, 426, 427, 428, 429, 430, 431, 432, 0, 0, + 433, 434, 435, 436, 437, 0, 0, 438, 439, 440, + 441, 442, 443, 444, 0, 445, 0, 447, 448, 449, + 450, 0, 0, 451, 0, 0, 452, 453, 454, 455, + 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 498, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 93, 94, 95, 96, 97, 98, 99, + 100, 0, 101, 102, 103, 0, 0, 0, 0, 0, + 2311, 0, 104, 105, 0, 106, 107, 108, 0, 110, + 111, 112, 113, 114, 0, 116, 117, 0, 118, 119, + 120, 121, 122, 123, 0, 0, 124, 125, 126, 127, + 128, 0, 129, 130, 131, 132, 133, 0, 0, 0, + 135, 136, 137, 138, 139, 140, 0, 142, 143, 144, + 0, 145, 146, 147, 148, 149, 150, 0, 0, 152, + 153, 154, 0, 0, 0, 0, 0, 0, 0, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 0, + 166, 0, 167, 168, 169, 170, 171, 172, 0, 173, + 174, 175, 176, 177, 0, 0, 178, 179, 180, 181, + 182, 0, 183, 184, 185, 0, 186, 187, 188, 0, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 0, 199, 0, 200, 201, 202, 203, 0, 204, 0, + 205, 0, 0, 0, 208, 209, 210, 0, 212, 0, + 213, 0, 214, 215, 216, 0, 217, 218, 219, 220, + 221, 222, 223, 0, 225, 226, 227, 228, 0, 229, + 230, 231, 232, 233, 234, 0, 235, 0, 237, 238, + 239, 240, 241, 242, 243, 244, 0, 245, 0, 246, + 0, 0, 249, 0, 251, 252, 253, 254, 255, 0, + 0, 256, 0, 258, 0, 0, 260, 261, 262, 0, + 0, 263, 264, 265, 266, 267, 500, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 287, 0, 289, 290, 291, + 292, 293, 0, 294, 295, 0, 297, 0, 298, 299, + 300, 301, 302, 303, 0, 304, 305, 0, 0, 306, + 307, 308, 0, 0, 309, 310, 0, 312, 0, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 0, 325, 326, 327, 328, 329, 330, 331, 332, 333, + 0, 334, 335, 336, 337, 338, 339, 0, 340, 341, + 342, 343, 344, 345, 346, 347, 0, 348, 349, 350, + 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, + 0, 361, 362, 0, 364, 365, 366, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 0, + 379, 380, 381, 382, 383, 0, 384, 385, 386, 387, + 388, 0, 390, 391, 392, 393, 0, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, 404, 502, 406, + 407, 408, 0, 409, 410, 0, 411, 0, 413, 414, + 415, 416, 417, 0, 418, 419, 0, 0, 420, 421, + 422, 423, 424, 0, 425, 426, 427, 428, 429, 430, + 431, 432, 0, 0, 433, 434, 435, 436, 437, 0, + 0, 438, 439, 440, 441, 442, 443, 444, 0, 445, + 0, 447, 448, 449, 450, 0, 0, 451, 0, 0, + 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 498, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 93, 94, 95, + 96, 97, 98, 99, 100, 0, 101, 102, 103, 0, + 0, 0, 0, 0, 2325, 0, 104, 105, 0, 106, + 107, 108, 0, 110, 111, 112, 113, 114, 0, 116, + 117, 0, 118, 119, 120, 121, 122, 123, 0, 0, + 124, 125, 126, 127, 128, 0, 129, 130, 131, 132, + 133, 0, 0, 0, 135, 136, 137, 138, 139, 140, + 0, 142, 143, 144, 0, 145, 146, 147, 148, 149, + 150, 0, 0, 152, 153, 154, 0, 0, 0, 0, + 0, 0, 0, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 0, 166, 0, 167, 168, 169, 170, + 171, 172, 0, 173, 174, 175, 176, 177, 0, 0, + 178, 179, 180, 181, 182, 0, 183, 184, 185, 0, + 186, 187, 188, 0, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 0, 199, 0, 200, 201, 202, + 203, 0, 204, 0, 205, 0, 0, 0, 208, 209, + 210, 0, 212, 0, 213, 0, 214, 215, 216, 0, + 217, 218, 219, 220, 221, 222, 223, 0, 225, 226, + 227, 228, 0, 229, 230, 231, 232, 233, 234, 0, + 235, 0, 237, 238, 239, 240, 241, 242, 243, 244, + 0, 245, 0, 246, 0, 0, 249, 0, 251, 252, + 253, 254, 255, 0, 0, 256, 0, 258, 0, 0, + 260, 261, 262, 0, 0, 263, 264, 265, 266, 267, + 500, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 0, 289, 290, 291, 292, 293, 0, 294, 295, 0, + 297, 0, 298, 299, 300, 301, 302, 303, 0, 304, + 305, 0, 0, 306, 307, 308, 0, 0, 309, 310, + 0, 312, 0, 314, 315, 316, 317, 318, 319, 320, + 321, 322, 323, 324, 0, 325, 326, 327, 328, 329, + 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, + 339, 0, 340, 341, 342, 343, 344, 345, 346, 347, + 0, 348, 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 0, 361, 362, 0, 364, 365, + 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 0, 379, 380, 381, 382, 383, 0, + 384, 385, 386, 387, 388, 0, 390, 391, 392, 393, + 0, 394, 395, 396, 397, 398, 399, 400, 401, 402, + 403, 404, 502, 406, 407, 408, 0, 409, 410, 0, + 411, 0, 413, 414, 415, 416, 417, 0, 418, 419, + 0, 0, 420, 421, 422, 423, 424, 0, 425, 426, + 427, 428, 429, 430, 431, 432, 0, 0, 433, 434, + 435, 436, 437, 0, 0, 438, 439, 440, 441, 442, + 443, 444, 0, 445, 0, 447, 448, 449, 450, 0, + 0, 451, 0, 0, 452, 453, 454, 455, 456, 457, + 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 498, 0, 579, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 93, 94, 95, 96, 97, 98, 99, 100, 0, + 101, 102, 103, 0, 0, 0, 0, 0, 0, 0, + 104, 105, 0, 106, 107, 108, 0, 110, 111, 112, + 113, 114, 0, 116, 117, 0, 118, 119, 120, 121, + 122, 123, 0, 0, 124, 125, 126, 127, 128, 0, + 129, 130, 131, 132, 133, 0, 0, 0, 135, 136, + 137, 138, 139, 140, 0, 142, 143, 144, 0, 145, + 146, 147, 148, 149, 150, 0, 0, 152, 153, 154, + 0, 0, 0, 0, 0, 0, 0, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 0, 166, 0, + 167, 168, 169, 170, 171, 172, 0, 173, 174, 175, + 176, 177, 0, 0, 178, 179, 180, 181, 182, 0, + 183, 184, 185, 0, 186, 187, 188, 0, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 0, 199, + 0, 200, 201, 202, 203, 0, 204, 0, 205, 0, + 0, 0, 208, 209, 210, 0, 212, 0, 213, 0, + 214, 215, 216, 0, 217, 218, 219, 220, 221, 2459, + 223, 0, 225, 226, 227, 228, 0, 229, 230, 231, + 232, 233, 234, 0, 235, 0, 237, 238, 239, 240, + 241, 242, 243, 244, 0, 245, 0, 246, 0, 0, + 249, 0, 251, 252, 253, 254, 255, 0, 0, 256, + 0, 258, 0, 0, 260, 261, 262, 0, 0, 263, + 264, 265, 266, 267, 500, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + 284, 285, 286, 287, 0, 289, 290, 291, 292, 293, + 0, 294, 295, 0, 297, 0, 298, 299, 300, 301, + 302, 303, 0, 304, 305, 0, 0, 306, 307, 308, + 0, 0, 309, 310, 0, 312, 0, 314, 315, 316, + 317, 318, 319, 320, 321, 322, 323, 324, 0, 325, + 326, 327, 328, 329, 330, 331, 332, 333, 0, 334, + 335, 336, 337, 338, 339, 0, 340, 341, 342, 343, + 344, 345, 346, 347, 0, 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 0, 361, + 362, 0, 364, 365, 366, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 0, 379, 380, + 381, 382, 383, 0, 384, 385, 386, 387, 388, 0, + 390, 391, 392, 393, 0, 394, 395, 396, 397, 398, + 399, 400, 401, 402, 403, 404, 502, 406, 407, 408, + 0, 409, 410, 0, 411, 0, 413, 414, 415, 416, + 417, 0, 418, 419, 0, 0, 420, 421, 422, 423, + 424, 0, 425, 426, 427, 428, 429, 430, 431, 432, + 0, 0, 433, 434, 435, 436, 437, 0, 0, 438, + 439, 440, 441, 442, 443, 444, 0, 445, 0, 447, + 448, 449, 450, 0, 0, 451, 0, 0, 452, 453, + 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 498, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 93, 94, 95, 96, 97, + 98, 99, 100, 0, 101, 102, 103, 0, 0, 0, + 0, 0, 0, 0, 104, 105, 0, 106, 107, 108, + 0, 110, 111, 112, 113, 114, 0, 116, 117, 0, + 118, 119, 120, 121, 122, 123, 0, 0, 124, 125, + 126, 127, 128, 0, 129, 130, 131, 132, 133, 0, + 0, 0, 135, 136, 137, 138, 139, 140, 0, 142, + 143, 144, 0, 145, 146, 147, 148, 149, 150, 0, + 0, 152, 153, 154, 0, 0, 0, 0, 0, 0, + 0, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 0, 166, 0, 167, 168, 169, 170, 171, 172, + 0, 173, 174, 175, 176, 177, 0, 0, 178, 179, + 180, 181, 182, 0, 183, 184, 185, 0, 186, 187, + 188, 0, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 0, 199, 0, 200, 201, 202, 203, 0, + 204, 0, 205, 0, 0, 0, 208, 209, 210, 0, + 212, 0, 213, 0, 214, 215, 216, 0, 217, 218, + 219, 220, 221, 222, 223, 0, 225, 226, 227, 228, + 0, 229, 230, 231, 232, 233, 234, 0, 235, 0, + 237, 238, 239, 240, 241, 242, 243, 244, 0, 245, + 0, 246, 0, 0, 249, 0, 251, 252, 253, 254, + 255, 0, 0, 256, 0, 258, 0, 0, 260, 261, + 262, 0, 0, 263, 264, 265, 266, 267, 500, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 287, 0, 289, + 290, 291, 292, 293, 0, 294, 295, 0, 297, 0, + 298, 299, 300, 301, 302, 303, 0, 304, 305, 0, + 0, 306, 307, 308, 0, 0, 309, 310, 0, 312, + 0, 314, 315, 316, 317, 318, 319, 320, 321, 322, + 323, 324, 0, 325, 326, 327, 328, 329, 330, 331, + 332, 333, 0, 334, 335, 336, 337, 338, 339, 0, + 340, 341, 342, 343, 344, 345, 346, 347, 0, 348, + 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, + 359, 360, 0, 361, 362, 0, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, - -1, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 388, 389, 390, 391, 392, 393, -1, 395, 396, -1, - 398, 399, 400, 401, 402, 403, 404, -1, 406, 407, - -1, -1, 410, 411, 412, 413, 414, 415, 416, 417, - 418, 419, 420, 421, 422, 423, -1, -1, 426, 427, - 428, 429, 430, 431, -1, 433, 434, 435, 436, 437, - 438, 439, -1, 441, 442, 443, 444, 445, 446, -1, - -1, 449, -1, -1, 452, 453, 454, 455, 456, 457, + 378, 0, 379, 380, 381, 382, 383, 0, 384, 385, + 386, 387, 388, 0, 390, 391, 392, 393, 0, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 502, 406, 407, 408, 0, 409, 410, 0, 411, 0, + 413, 414, 415, 416, 417, 0, 418, 419, 0, 0, + 420, 421, 422, 423, 424, 0, 425, 426, 427, 428, + 429, 430, 431, 432, 0, 0, 433, 434, 435, 436, + 437, 0, 0, 438, 439, 440, 441, 442, 443, 444, + 0, 445, 0, 447, 448, 449, 450, 0, 0, 451, + 0, 0, 452, 453, 454, 455, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 498, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, + 94, 95, 96, 97, 98, 99, 100, 0, 101, 102, + 103, 0, 0, 0, 0, 0, 0, 0, 104, 105, + 0, 106, 107, 108, 0, 110, 111, 112, 113, 114, + 0, 116, 117, 0, 118, 119, 120, 121, 122, 123, + 0, 0, 124, 125, 126, 127, 128, 0, 129, 130, + 131, 132, 133, 0, 0, 0, 135, 136, 137, 138, + 139, 140, 0, 142, 143, 144, 0, 145, 146, 147, + 148, 149, 150, 0, 0, 152, 153, 154, 0, 0, + 0, 0, 0, 0, 0, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 0, 166, 0, 167, 168, + 169, 170, 171, 172, 0, 173, 174, 175, 176, 177, + 0, 0, 178, 179, 180, 181, 182, 0, 183, 184, + 185, 0, 186, 187, 188, 0, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 0, 199, 0, 200, + 201, 202, 203, 0, 204, 0, 205, 0, 0, 0, + 208, 209, 210, 0, 566, 0, 213, 0, 214, 215, + 216, 0, 217, 218, 219, 220, 221, 222, 223, 0, + 225, 226, 227, 228, 0, 229, 230, 231, 232, 233, + 234, 0, 235, 0, 237, 238, 239, 240, 241, 242, + 243, 244, 0, 245, 0, 246, 0, 0, 249, 0, + 251, 252, 253, 254, 255, 0, 0, 256, 0, 258, + 0, 0, 260, 261, 567, 0, 0, 263, 264, 265, + 266, 267, 500, 269, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, + 286, 287, 0, 289, 290, 291, 292, 293, 0, 294, + 295, 0, 297, 0, 298, 299, 300, 301, 302, 303, + 0, 304, 305, 0, 0, 306, 307, 308, 0, 0, + 309, 310, 0, 312, 0, 314, 315, 316, 317, 318, + 319, 320, 321, 322, 323, 324, 0, 325, 326, 327, + 328, 329, 330, 331, 332, 333, 0, 334, 335, 336, + 337, 338, 339, 0, 340, 341, 342, 343, 344, 345, + 346, 347, 0, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 0, 361, 362, 0, + 364, 365, 366, 367, 368, 369, 370, 371, 568, 373, + 374, 375, 376, 377, 378, 0, 379, 380, 381, 382, + 569, 0, 384, 385, 386, 387, 388, 0, 390, 391, + 392, 393, 0, 394, 395, 396, 397, 398, 399, 400, + 401, 402, 403, 404, 502, 406, 407, 408, 0, 409, + 410, 0, 411, 0, 413, 414, 415, 416, 417, 0, + 570, 419, 0, 0, 420, 421, 422, 423, 424, 0, + 425, 426, 427, 428, 429, 430, 431, 432, 0, 0, + 433, 434, 435, 436, 437, 0, 0, 438, 439, 440, + 441, 442, 443, 444, 0, 445, 0, 447, 448, 449, + 450, 0, 0, 451, 0, 0, 452, 453, 454, 455, + 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 498, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 93, 94, 95, 96, 97, 98, 99, + 100, 0, 101, 102, 103, 0, 0, 0, 0, 0, + 0, 0, 104, 105, 0, 106, 107, 108, 0, 110, + 111, 112, 113, 114, 0, 116, 117, 0, 118, 119, + 120, 121, 122, 123, 0, 0, 124, 125, 126, 127, + 128, 0, 129, 130, 131, 132, 133, 0, 0, 0, + 135, 136, 137, 138, 139, 140, 0, 142, 143, 144, + 0, 145, 146, 147, 148, 149, 150, 0, 0, 152, + 153, 154, 0, 0, 0, 0, 0, 0, 0, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 0, + 166, 0, 167, 168, 169, 170, 171, 172, 0, 173, + 174, 175, 176, 177, 0, 0, 178, 179, 180, 181, + 182, 0, 183, 184, 185, 0, 186, 187, 188, 0, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 0, 199, 0, 200, 201, 202, 203, 0, 204, 0, + 205, 0, 0, 0, 208, 209, 210, 0, 212, 0, + 213, 0, 214, 215, 216, 0, 217, 218, 219, 220, + 221, 222, 223, 0, 225, 226, 227, 228, 0, 229, + 230, 231, 232, 233, 234, 0, 235, 0, 237, 238, + 239, 240, 241, 242, 243, 244, 0, 245, 0, 246, + 0, 0, 249, 0, 251, 252, 253, 254, 255, 0, + 0, 256, 0, 258, 0, 0, 260, 261, 262, 0, + 0, 263, 264, 265, 266, 267, 500, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 287, 0, 289, 290, 291, + 292, 293, 0, 294, 295, 0, 297, 0, 298, 299, + 300, 301, 302, 303, 0, 304, 305, 0, 0, 306, + 307, 308, 0, 0, 309, 310, 0, 312, 0, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 0, 325, 326, 327, 328, 329, 330, 331, 332, 333, + 0, 334, 335, 336, 337, 338, 339, 0, 340, 341, + 342, 343, 344, 345, 589, 347, 0, 348, 349, 350, + 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, + 0, 361, 362, 0, 364, 365, 366, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 0, + 379, 380, 381, 382, 383, 0, 384, 385, 386, 387, + 388, 0, 390, 391, 392, 393, 0, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, 404, 502, 406, + 407, 408, 0, 409, 410, 0, 411, 0, 413, 414, + 415, 416, 417, 0, 418, 419, 0, 0, 420, 421, + 422, 423, 424, 0, 425, 426, 427, 428, 429, 430, + 431, 432, 0, 0, 433, 434, 435, 436, 437, 0, + 0, 438, 439, 440, 441, 442, 443, 444, 0, 445, + 0, 447, 448, 449, 450, 0, 0, 451, 0, 0, + 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 498, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 93, 94, 95, + 96, 97, 98, 99, 100, 0, 101, 102, 103, 0, + 0, 0, 0, 0, 0, 0, 104, 105, 0, 106, + 107, 108, 0, 110, 111, 112, 113, 114, 0, 116, + 117, 0, 118, 119, 120, 121, 122, 123, 0, 0, + 124, 125, 126, 127, 128, 0, 129, 130, 131, 132, + 133, 0, 0, 0, 135, 136, 137, 138, 139, 140, + 0, 142, 143, 144, 0, 145, 146, 147, 148, 149, + 150, 0, 0, 152, 153, 154, 0, 0, 0, 0, + 0, 0, 0, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 0, 166, 0, 167, 168, 169, 170, + 171, 172, 0, 173, 174, 175, 176, 177, 0, 0, + 178, 179, 180, 181, 182, 0, 183, 184, 185, 0, + 186, 187, 188, 0, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 0, 199, 0, 200, 201, 202, + 203, 0, 204, 0, 205, 0, 0, 0, 208, 209, + 210, 0, 212, 0, 213, 0, 214, 215, 216, 0, + 217, 218, 219, 220, 221, 643, 223, 0, 225, 226, + 227, 228, 0, 229, 230, 231, 232, 233, 234, 0, + 235, 0, 237, 238, 239, 240, 241, 242, 243, 244, + 0, 245, 0, 246, 0, 0, 249, 0, 251, 252, + 253, 254, 255, 0, 0, 256, 0, 258, 0, 0, + 260, 261, 262, 0, 0, 263, 264, 265, 266, 267, + 500, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 0, 289, 290, 291, 292, 293, 0, 294, 295, 0, + 297, 0, 298, 299, 300, 301, 302, 303, 0, 304, + 305, 0, 0, 306, 307, 308, 0, 0, 309, 310, + 0, 312, 0, 314, 315, 316, 317, 318, 319, 320, + 321, 322, 323, 324, 0, 325, 326, 327, 328, 329, + 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, + 339, 0, 340, 341, 342, 343, 344, 345, 346, 347, + 0, 348, 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 0, 361, 362, 0, 364, 365, + 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 0, 379, 380, 381, 382, 383, 0, + 384, 385, 386, 387, 388, 0, 390, 391, 392, 393, + 0, 394, 395, 396, 397, 398, 399, 400, 401, 402, + 403, 404, 502, 406, 407, 408, 0, 409, 410, 0, + 411, 0, 413, 414, 415, 416, 417, 0, 418, 419, + 0, 0, 420, 421, 422, 423, 424, 0, 425, 426, + 427, 428, 429, 430, 431, 432, 0, 0, 433, 434, + 435, 436, 437, 0, 0, 438, 439, 440, 441, 442, + 443, 444, 0, 445, 0, 447, 448, 449, 450, 0, + 0, 451, 0, 0, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 471, 472, 473, -1, -1, -1, -1, - -1, -1, 480, 481, -1, -1, -1, -1, -1, 487, - -1, 489, -1, -1, -1, -1, 494, -1, 496, 497, - 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, - -1, -1, -1, -1, -1, -1, 19, 20, 21, 22, - 23, 24, 25, 26, -1, 28, 29, 30, -1, -1, - -1, -1, 35, -1, -1, 38, 39, -1, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - -1, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, -1, 68, 69, 70, 71, 72, - -1, 74, -1, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, -1, 87, 88, 89, 90, 91, 92, - -1, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, -1, 118, 119, 120, 121, 122, - 123, -1, 125, 126, 127, 128, 129, -1, -1, 132, - 133, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, -1, 146, 147, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, -1, 159, 160, 161, 162, - -1, 164, -1, 166, 167, -1, 169, 170, 171, 172, - 173, 174, -1, 176, -1, 178, 179, 180, -1, 182, - 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - -1, 194, 195, 196, 197, 198, 199, -1, 201, 202, - 203, 204, 205, 206, 207, 208, 209, -1, 211, -1, - 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, - -1, -1, 225, 226, 227, 228, -1, 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, -1, -1, - 283, 284, 285, -1, -1, 288, 289, 290, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, - 303, -1, 305, 306, 307, 308, 309, 310, 311, 312, - 313, -1, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, -1, 330, 331, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, -1, - 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 360, -1, 362, - 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, -1, 379, 380, 381, 382, - 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, - 393, -1, 395, 396, -1, 398, 399, 400, 401, 402, - 403, 404, -1, 406, 407, -1, -1, 410, 411, 412, - 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, - 423, -1, -1, 426, 427, 428, 429, 430, 431, -1, - 433, 434, 435, 436, 437, 438, 439, -1, 441, 442, - 443, 444, 445, 446, -1, -1, 449, -1, -1, 452, - 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, - 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, - 473, -1, -1, -1, -1, -1, -1, 480, 481, -1, - -1, -1, -1, -1, 487, -1, 489, -1, -1, -1, - -1, 494, -1, 496, 497, 3, 4, 5, 6, 7, - 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, - -1, 19, 20, 21, 22, 23, 24, 25, 26, -1, - 28, 29, 30, -1, -1, -1, -1, 35, -1, -1, - 38, 39, -1, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, -1, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, -1, - 68, 69, 70, 71, 72, -1, 74, -1, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, -1, 87, - 88, 89, 90, 91, 92, -1, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, -1, - 118, 119, 120, 121, 122, 123, -1, 125, 126, 127, - 128, 129, -1, -1, 132, 133, 134, 135, 136, -1, - 138, 139, 140, -1, 142, 143, 144, -1, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, - -1, 159, 160, 161, 162, -1, 164, -1, 166, 167, - -1, 169, 170, 171, 172, 173, 174, -1, 176, -1, - 178, 179, 180, -1, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, -1, 194, 195, 196, 197, - 198, 199, -1, 201, 202, 203, 204, 205, 206, 207, - 208, 209, -1, 211, -1, 213, 214, 215, 216, 217, - 218, 219, 220, 221, 222, -1, -1, 225, 226, 227, - 228, -1, 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, -1, -1, 283, 284, 285, -1, -1, - 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, - 298, 299, 300, 301, 302, 303, -1, 305, 306, 307, - 308, 309, 310, 311, 312, 313, -1, 315, 316, 317, - 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, - 328, -1, 330, 331, 332, 333, 334, 335, 336, 337, - 338, 339, 340, 341, -1, 343, 344, 345, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, - 358, 359, 360, -1, 362, 363, 364, 365, 366, 367, + 468, 469, 470, 471, 472, 498, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 93, 94, 95, 96, 97, 98, 99, 100, 0, + 101, 102, 103, 0, 0, 0, 0, 0, 0, 0, + 104, 105, 0, 106, 107, 108, 0, 110, 111, 112, + 113, 114, 0, 116, 117, 0, 118, 119, 120, 121, + 122, 123, 0, 0, 124, 125, 126, 127, 128, 0, + 129, 130, 131, 132, 133, 0, 0, 0, 135, 136, + 137, 138, 139, 140, 0, 142, 143, 144, 0, 145, + 146, 147, 148, 149, 150, 0, 0, 152, 153, 154, + 0, 0, 0, 0, 0, 0, 0, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 0, 166, 0, + 167, 168, 169, 170, 171, 172, 0, 173, 174, 175, + 176, 177, 0, 0, 178, 179, 180, 181, 182, 0, + 183, 184, 185, 0, 186, 187, 188, 0, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 0, 199, + 0, 200, 201, 202, 203, 0, 204, 0, 205, 0, + 0, 0, 208, 209, 210, 0, 212, 0, 213, 0, + 214, 215, 216, 0, 217, 218, 219, 220, 221, 730, + 223, 0, 225, 226, 227, 228, 0, 229, 230, 231, + 232, 233, 234, 0, 235, 0, 237, 238, 239, 240, + 241, 242, 243, 244, 0, 245, 0, 246, 0, 0, + 249, 0, 251, 252, 253, 254, 255, 0, 0, 256, + 0, 258, 0, 0, 260, 261, 262, 0, 0, 263, + 264, 265, 266, 267, 500, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + 284, 285, 286, 287, 0, 289, 290, 291, 292, 293, + 0, 294, 295, 0, 297, 0, 298, 299, 300, 301, + 302, 303, 0, 304, 305, 0, 0, 306, 307, 308, + 0, 0, 309, 310, 0, 312, 0, 314, 315, 316, + 317, 318, 319, 320, 321, 322, 323, 324, 0, 325, + 326, 327, 328, 329, 330, 331, 332, 333, 0, 334, + 335, 336, 337, 338, 339, 0, 340, 341, 342, 343, + 344, 345, 346, 347, 0, 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 0, 361, + 362, 0, 364, 365, 366, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 0, 379, 380, + 381, 382, 383, 0, 384, 385, 386, 387, 388, 0, + 390, 391, 392, 393, 0, 394, 395, 396, 397, 398, + 399, 400, 401, 402, 403, 404, 502, 406, 407, 408, + 0, 409, 410, 0, 411, 0, 413, 414, 415, 416, + 417, 0, 418, 419, 0, 0, 420, 421, 422, 423, + 424, 0, 425, 426, 427, 428, 429, 430, 431, 432, + 0, 0, 433, 434, 435, 436, 437, 0, 0, 438, + 439, 440, 441, 442, 443, 444, 0, 445, 0, 447, + 448, 449, 450, 0, 0, 451, 0, 0, 452, 453, + 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 498, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 93, 94, 95, 96, 97, + 98, 99, 100, 0, 101, 102, 103, 0, 0, 0, + 0, 0, 0, 0, 104, 105, 0, 106, 107, 108, + 0, 110, 111, 112, 113, 114, 0, 116, 117, 0, + 118, 119, 120, 121, 122, 123, 0, 0, 124, 125, + 126, 127, 128, 0, 129, 130, 131, 132, 133, 0, + 0, 0, 135, 136, 137, 138, 139, 140, 0, 142, + 143, 144, 0, 145, 146, 147, 148, 149, 150, 0, + 0, 152, 153, 154, 0, 0, 0, 0, 0, 0, + 0, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 0, 166, 0, 167, 168, 169, 170, 171, 172, + 0, 173, 174, 175, 176, 177, 0, 0, 178, 179, + 180, 181, 182, 0, 183, 184, 185, 0, 186, 187, + 188, 0, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 0, 199, 0, 200, 201, 202, 203, 0, + 204, 0, 205, 0, 0, 0, 208, 209, 210, 0, + 212, 0, 213, 0, 214, 215, 216, 0, 217, 218, + 219, 220, 221, 733, 223, 0, 225, 226, 227, 228, + 0, 229, 230, 231, 232, 233, 234, 0, 235, 0, + 237, 238, 239, 240, 241, 242, 243, 244, 0, 245, + 0, 246, 0, 0, 249, 0, 251, 252, 253, 254, + 255, 0, 0, 256, 0, 258, 0, 0, 260, 261, + 262, 0, 0, 263, 264, 265, 266, 267, 500, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 287, 0, 289, + 290, 291, 292, 293, 0, 294, 295, 0, 297, 0, + 298, 299, 300, 301, 302, 303, 0, 304, 305, 0, + 0, 306, 307, 308, 0, 0, 309, 310, 0, 312, + 0, 314, 315, 316, 317, 318, 319, 320, 321, 322, + 323, 324, 0, 325, 326, 327, 328, 329, 330, 331, + 332, 333, 0, 334, 335, 336, 337, 338, 339, 0, + 340, 341, 342, 343, 344, 345, 346, 347, 0, 348, + 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, + 359, 360, 0, 361, 362, 0, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, - -1, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 388, 389, 390, 391, 392, 393, -1, 395, 396, -1, - 398, 399, 400, 401, 402, 403, 404, -1, 406, 407, - -1, -1, 410, 411, 412, 413, 414, 415, 416, 417, - 418, 419, 420, 421, 422, 423, -1, -1, 426, 427, - 428, 429, 430, 431, -1, 433, 434, 435, 436, 437, - 438, 439, -1, 441, 442, 443, 444, 445, 446, -1, - -1, 449, -1, -1, 452, 453, 454, 455, 456, 457, + 378, 0, 379, 380, 381, 382, 383, 0, 384, 385, + 386, 387, 388, 0, 390, 391, 392, 393, 0, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 502, 406, 407, 408, 0, 409, 410, 0, 411, 0, + 413, 414, 415, 416, 417, 0, 418, 419, 0, 0, + 420, 421, 422, 423, 424, 0, 425, 426, 427, 428, + 429, 430, 431, 432, 0, 0, 433, 434, 435, 436, + 437, 0, 0, 438, 439, 440, 441, 442, 443, 444, + 0, 445, 0, 447, 448, 449, 450, 0, 0, 451, + 0, 0, 452, 453, 454, 455, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 498, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, + 94, 95, 96, 97, 98, 99, 100, 0, 101, 102, + 103, 0, 0, 0, 0, 0, 0, 0, 104, 105, + 0, 106, 107, 108, 0, 110, 111, 112, 113, 114, + 0, 116, 117, 0, 118, 119, 120, 121, 122, 123, + 0, 0, 124, 125, 126, 127, 128, 0, 129, 130, + 131, 132, 133, 0, 0, 0, 135, 136, 137, 138, + 139, 140, 0, 142, 143, 144, 0, 145, 146, 147, + 148, 149, 150, 0, 0, 152, 153, 154, 0, 0, + 0, 0, 0, 0, 0, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 0, 166, 0, 167, 168, + 169, 170, 171, 172, 0, 173, 174, 175, 176, 177, + 0, 0, 178, 179, 180, 181, 182, 0, 183, 184, + 185, 0, 186, 187, 188, 0, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 0, 199, 0, 200, + 201, 202, 203, 0, 204, 0, 205, 0, 0, 0, + 208, 209, 210, 0, 212, 0, 213, 0, 214, 215, + 216, 0, 217, 218, 219, 220, 221, 736, 223, 0, + 225, 226, 227, 228, 0, 229, 230, 231, 232, 233, + 234, 0, 235, 0, 237, 238, 239, 240, 241, 242, + 243, 244, 0, 245, 0, 246, 0, 0, 249, 0, + 251, 252, 253, 254, 255, 0, 0, 256, 0, 258, + 0, 0, 260, 261, 262, 0, 0, 263, 264, 265, + 266, 267, 500, 269, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, + 286, 287, 0, 289, 290, 291, 292, 293, 0, 294, + 295, 0, 297, 0, 298, 299, 300, 301, 302, 303, + 0, 304, 305, 0, 0, 306, 307, 308, 0, 0, + 309, 310, 0, 312, 0, 314, 315, 316, 317, 318, + 319, 320, 321, 322, 323, 324, 0, 325, 326, 327, + 328, 329, 330, 331, 332, 333, 0, 334, 335, 336, + 337, 338, 339, 0, 340, 341, 342, 343, 344, 345, + 346, 347, 0, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 0, 361, 362, 0, + 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 0, 379, 380, 381, 382, + 383, 0, 384, 385, 386, 387, 388, 0, 390, 391, + 392, 393, 0, 394, 395, 396, 397, 398, 399, 400, + 401, 402, 403, 404, 502, 406, 407, 408, 0, 409, + 410, 0, 411, 0, 413, 414, 415, 416, 417, 0, + 418, 419, 0, 0, 420, 421, 422, 423, 424, 0, + 425, 426, 427, 428, 429, 430, 431, 432, 0, 0, + 433, 434, 435, 436, 437, 0, 0, 438, 439, 440, + 441, 442, 443, 444, 0, 445, 0, 447, 448, 449, + 450, 0, 0, 451, 0, 0, 452, 453, 454, 455, + 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 498, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 93, 94, 95, 96, 97, 98, 99, + 100, 0, 101, 102, 103, 0, 0, 0, 0, 0, + 0, 0, 104, 105, 0, 106, 107, 108, 0, 110, + 111, 112, 113, 114, 0, 116, 117, 0, 118, 119, + 120, 121, 122, 123, 0, 0, 124, 125, 126, 127, + 128, 0, 129, 130, 131, 132, 133, 0, 0, 0, + 135, 136, 137, 138, 139, 140, 0, 142, 143, 144, + 0, 145, 146, 147, 148, 149, 150, 0, 0, 152, + 153, 154, 0, 0, 0, 0, 0, 0, 0, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 0, + 166, 0, 167, 168, 169, 170, 171, 172, 0, 173, + 174, 175, 176, 177, 0, 0, 178, 179, 180, 181, + 182, 0, 183, 184, 185, 0, 186, 187, 188, 0, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 0, 199, 0, 200, 201, 202, 203, 0, 204, 0, + 205, 0, 0, 0, 208, 209, 210, 0, 212, 0, + 213, 0, 214, 215, 216, 0, 217, 218, 219, 220, + 221, 222, 223, 0, 225, 226, 227, 228, 0, 229, + 230, 231, 232, 233, 234, 0, 235, 0, 237, 238, + 239, 240, 241, 242, 243, 244, 0, 245, 0, 246, + 0, 0, 249, 0, 251, 252, 253, 254, 255, 0, + 0, 256, 0, 258, 0, 0, 260, 261, 262, 0, + 0, 263, 264, 265, 266, 267, 500, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 287, 0, 289, 290, 291, + 292, 293, 0, 294, 295, 0, 297, 0, 298, 299, + 300, 301, 302, 303, 0, 304, 305, 0, 0, 306, + 307, 308, 0, 0, 309, 310, 0, 312, 0, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 0, 325, 326, 327, 328, 329, 330, 331, 332, 333, + 0, 334, 335, 336, 337, 338, 339, 0, 340, 341, + 342, 343, 344, 345, 346, 347, 0, 348, 349, 350, + 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, + 0, 361, 362, 0, 364, 365, 366, 367, 368, 369, + 370, 371, 568, 373, 374, 375, 376, 377, 378, 0, + 379, 380, 381, 382, 383, 0, 384, 385, 386, 387, + 388, 0, 390, 391, 392, 393, 0, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, 404, 502, 406, + 407, 408, 0, 409, 410, 0, 411, 0, 413, 414, + 415, 416, 417, 0, 570, 419, 0, 0, 420, 421, + 422, 423, 424, 0, 425, 426, 427, 428, 429, 430, + 431, 432, 0, 0, 433, 434, 435, 436, 437, 0, + 0, 438, 439, 440, 441, 442, 443, 444, 0, 445, + 0, 447, 448, 449, 450, 0, 0, 451, 0, 0, + 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 498, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 93, 94, 95, + 96, 97, 98, 99, 100, 0, 101, 102, 103, 0, + 0, 0, 0, 0, 1383, 0, 104, 105, 0, 106, + 107, 108, 0, 110, 111, 112, 113, 114, 0, 116, + 117, 0, 118, 119, 120, 121, 122, 123, 0, 0, + 124, 125, 126, 127, 128, 0, 129, 130, 131, 132, + 133, 0, 0, 0, 135, 136, 137, 138, 139, 140, + 0, 142, 143, 144, 0, 145, 146, 147, 148, 149, + 150, 0, 0, 152, 153, 154, 0, 0, 0, 0, + 0, 0, 0, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 0, 166, 0, 167, 168, 169, 170, + 171, 172, 0, 173, 174, 175, 176, 177, 0, 0, + 178, 179, 180, 181, 182, 0, 183, 184, 185, 0, + 186, 187, 188, 0, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 0, 199, 0, 200, 201, 202, + 203, 0, 204, 0, 205, 0, 0, 0, 208, 209, + 210, 0, 212, 0, 213, 0, 214, 215, 216, 0, + 217, 218, 219, 220, 221, 222, 223, 0, 225, 226, + 227, 228, 0, 229, 230, 231, 232, 233, 234, 0, + 235, 0, 237, 238, 239, 240, 241, 242, 243, 244, + 0, 245, 0, 246, 0, 0, 249, 0, 251, 252, + 253, 254, 255, 0, 0, 256, 0, 258, 0, 0, + 260, 261, 262, 0, 0, 263, 264, 265, 266, 267, + 500, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 0, 289, 290, 291, 292, 293, 0, 294, 295, 0, + 297, 0, 298, 299, 300, 301, 302, 303, 0, 304, + 305, 0, 0, 306, 307, 308, 0, 0, 309, 310, + 0, 312, 0, 314, 315, 316, 317, 318, 319, 320, + 321, 322, 323, 324, 0, 325, 326, 327, 328, 329, + 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, + 339, 0, 340, 341, 342, 343, 344, 345, 346, 347, + 0, 348, 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 0, 361, 362, 0, 364, 365, + 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 0, 379, 380, 381, 382, 383, 0, + 0, 385, 386, 387, 388, 0, 390, 391, 392, 393, + 0, 394, 395, 396, 397, 398, 399, 400, 401, 402, + 403, 404, 502, 406, 407, 408, 0, 409, 410, 0, + 411, 0, 413, 414, 415, 416, 417, 0, 418, 419, + 0, 0, 420, 421, 422, 423, 424, 0, 425, 426, + 427, 428, 429, 430, 431, 432, 0, 0, 433, 434, + 435, 436, 437, 0, 0, 438, 439, 440, 441, 442, + 443, 444, 0, 445, 0, 447, 448, 449, 450, 0, + 0, 451, 0, 0, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 471, 472, 473, -1, -1, -1, -1, - -1, -1, 480, 481, -1, -1, -1, -1, -1, 487, - -1, 489, -1, -1, -1, -1, 494, -1, 496, 497, - 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, - -1, -1, -1, -1, -1, -1, 19, 20, 21, 22, - 23, 24, 25, 26, -1, 28, 29, 30, -1, -1, - -1, -1, 35, -1, -1, 38, 39, -1, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - -1, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, -1, 68, 69, 70, 71, 72, - -1, 74, -1, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, -1, 87, 88, 89, 90, 91, 92, - -1, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, -1, 118, 119, 120, 121, 122, - 123, -1, 125, 126, 127, 128, 129, -1, -1, 132, - 133, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, -1, 146, 147, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, -1, 159, 160, 161, 162, - -1, 164, -1, 166, 167, -1, 169, 170, 171, 172, - 173, 174, -1, 176, -1, 178, 179, 180, -1, 182, - 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - -1, 194, 195, 196, 197, 198, 199, -1, 201, 202, - 203, 204, 205, 206, 207, 208, 209, -1, 211, -1, - 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, - -1, -1, 225, 226, 227, 228, -1, 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, -1, -1, - 283, 284, 285, -1, -1, 288, 289, 290, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, - 303, -1, 305, 306, 307, 308, 309, 310, 311, 312, - 313, -1, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, -1, 330, 331, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, -1, - 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 360, -1, 362, - 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, -1, 379, 380, 381, 382, - 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, - 393, -1, 395, 396, -1, 398, 399, 400, 401, 402, - 403, 404, -1, 406, 407, -1, -1, 410, 411, 412, - 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, - 423, -1, -1, 426, 427, 428, 429, 430, 431, -1, - 433, 434, 435, 436, 437, 438, 439, -1, 441, 442, - 443, 444, 445, 446, -1, -1, 449, -1, -1, 452, - 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, - 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, - 473, -1, -1, -1, -1, -1, -1, 480, 481, -1, - -1, -1, -1, -1, 487, -1, 489, -1, -1, -1, - -1, 494, -1, 496, 497, 3, 4, 5, 6, 7, + 468, 469, 470, 471, 472, 498, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 93, 94, 95, 96, 97, 98, 99, 100, 0, + 101, 102, 103, 0, 0, 0, 0, 0, 0, 0, + 104, 105, 0, 106, 107, 108, 0, 110, 111, 112, + 113, 114, 0, 116, 117, 0, 118, 119, 120, 121, + 122, 123, 0, 0, 124, 125, 126, 127, 128, 0, + 129, 130, 131, 132, 133, 0, 0, 0, 135, 136, + 137, 138, 139, 140, 0, 142, 143, 144, 0, 145, + 146, 147, 148, 149, 150, 0, 0, 152, 153, 154, + 0, 0, 0, 0, 0, 0, 0, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 0, 166, 0, + 167, 168, 169, 170, 171, 172, 0, 173, 174, 175, + 176, 177, 0, 0, 178, 179, 180, 181, 182, 0, + 183, 184, 185, 0, 186, 187, 188, 0, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 0, 199, + 0, 200, 201, 202, 203, 0, 204, 0, 205, 0, + 0, 0, 208, 209, 210, 0, 212, 0, 213, 0, + 214, 215, 216, 0, 217, 218, 219, 220, 221, 1524, + 223, 0, 225, 226, 227, 228, 0, 229, 230, 231, + 232, 233, 234, 0, 235, 0, 237, 238, 239, 240, + 241, 242, 243, 244, 0, 245, 0, 246, 0, 0, + 249, 0, 251, 252, 253, 254, 255, 0, 0, 256, + 0, 258, 0, 0, 260, 261, 262, 0, 0, 263, + 264, 265, 266, 267, 500, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + 284, 285, 286, 287, 0, 289, 290, 291, 292, 293, + 0, 294, 295, 0, 297, 0, 298, 299, 300, 301, + 302, 303, 0, 304, 305, 0, 0, 306, 307, 308, + 0, 0, 309, 310, 0, 312, 0, 314, 315, 316, + 317, 318, 319, 320, 321, 322, 323, 324, 0, 325, + 326, 327, 328, 329, 330, 331, 332, 333, 0, 334, + 335, 336, 337, 338, 339, 0, 340, 341, 342, 343, + 344, 345, 346, 347, 0, 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 0, 361, + 362, 0, 364, 365, 366, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 0, 379, 380, + 381, 382, 383, 0, 384, 385, 386, 387, 388, 0, + 390, 391, 392, 393, 0, 394, 395, 396, 397, 398, + 399, 400, 401, 402, 403, 404, 502, 406, 407, 408, + 0, 409, 410, 0, 411, 0, 413, 414, 415, 416, + 417, 0, 418, 419, 0, 0, 420, 421, 422, 423, + 424, 0, 425, 426, 427, 428, 429, 430, 431, 432, + 0, 0, 433, 434, 435, 436, 437, 0, 0, 438, + 439, 440, 441, 442, 443, 444, 0, 445, 0, 447, + 448, 449, 450, 0, 0, 451, 0, 0, 452, 453, + 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 498, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 93, 94, 95, 96, 97, + 98, 99, 100, 0, 101, 102, 103, 0, 0, 0, + 0, 0, 0, 0, 104, 105, 0, 106, 107, 108, + 0, 110, 111, 112, 113, 114, 0, 116, 117, 0, + 118, 119, 120, 121, 122, 123, 0, 0, 124, 125, + 126, 127, 128, 0, 129, 130, 131, 132, 133, 0, + 0, 0, 135, 136, 137, 138, 139, 140, 0, 142, + 143, 144, 0, 145, 146, 147, 148, 149, 150, 0, + 0, 152, 153, 154, 0, 0, 0, 0, 0, 0, + 0, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 0, 166, 0, 167, 168, 169, 170, 171, 172, + 0, 173, 174, 175, 176, 177, 0, 0, 178, 179, + 180, 181, 182, 0, 183, 184, 185, 0, 186, 187, + 188, 0, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 0, 199, 0, 200, 201, 202, 203, 0, + 204, 0, 205, 0, 0, 0, 208, 209, 210, 0, + 212, 0, 213, 0, 214, 215, 216, 0, 217, 218, + 219, 220, 221, 1804, 223, 0, 225, 226, 227, 228, + 0, 229, 230, 231, 232, 233, 234, 0, 235, 0, + 237, 238, 239, 240, 241, 242, 243, 244, 0, 245, + 0, 246, 0, 0, 249, 0, 251, 252, 253, 254, + 255, 0, 0, 256, 0, 258, 0, 0, 260, 261, + 262, 0, 0, 263, 264, 265, 266, 267, 500, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 287, 0, 289, + 290, 291, 292, 293, 0, 294, 295, 0, 297, 0, + 298, 299, 300, 301, 302, 303, 0, 304, 305, 0, + 0, 306, 307, 308, 0, 0, 309, 310, 0, 312, + 0, 314, 315, 316, 317, 318, 319, 320, 321, 322, + 323, 324, 0, 325, 326, 327, 328, 329, 330, 331, + 332, 333, 0, 334, 335, 336, 337, 338, 339, 0, + 340, 341, 342, 343, 344, 345, 346, 347, 0, 348, + 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, + 359, 360, 0, 361, 362, 0, 364, 365, 366, 367, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 0, 379, 380, 381, 382, 383, 0, 384, 385, + 386, 387, 388, 0, 390, 391, 392, 393, 0, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 502, 406, 407, 408, 0, 409, 410, 0, 411, 0, + 413, 414, 415, 416, 417, 0, 418, 419, 0, 0, + 420, 421, 422, 423, 424, 0, 425, 426, 427, 428, + 429, 430, 431, 432, 0, 0, 433, 434, 435, 436, + 437, 0, 0, 438, 439, 440, 441, 442, 443, 444, + 0, 445, 0, 447, 448, 449, 450, 0, 0, 451, + 0, 0, 452, 453, 454, 455, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 498, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, + 94, 95, 96, 97, 98, 99, 100, 0, 101, 102, + 103, 0, 0, 0, 0, 0, 0, 0, 104, 105, + 0, 106, 107, 108, 0, 110, 111, 112, 113, 114, + 0, 116, 117, 0, 118, 119, 120, 121, 122, 123, + 0, 0, 124, 125, 126, 127, 128, 0, 129, 130, + 131, 132, 133, 0, 0, 0, 135, 136, 137, 138, + 139, 140, 0, 142, 143, 144, 0, 145, 146, 147, + 148, 149, 150, 0, 0, 152, 153, 154, 0, 0, + 0, 0, 0, 0, 0, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 0, 166, 0, 167, 168, + 169, 170, 171, 172, 0, 173, 174, 175, 176, 177, + 0, 0, 178, 179, 180, 181, 182, 0, 183, 184, + 185, 0, 186, 187, 188, 0, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 0, 199, 0, 200, + 201, 202, 203, 0, 204, 0, 205, 0, 0, 0, + 208, 209, 210, 0, 212, 0, 213, 0, 214, 215, + 216, 0, 217, 218, 219, 220, 221, 1816, 223, 0, + 225, 226, 227, 228, 0, 229, 230, 231, 232, 233, + 234, 0, 235, 0, 237, 238, 239, 240, 241, 242, + 243, 244, 0, 245, 0, 246, 0, 0, 249, 0, + 251, 252, 253, 254, 255, 0, 0, 256, 0, 258, + 0, 0, 260, 261, 262, 0, 0, 263, 264, 265, + 266, 267, 500, 269, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, + 286, 287, 0, 289, 290, 291, 292, 293, 0, 294, + 295, 0, 297, 0, 298, 299, 300, 301, 302, 303, + 0, 304, 305, 0, 0, 306, 307, 308, 0, 0, + 309, 310, 0, 312, 0, 314, 315, 316, 317, 318, + 319, 320, 321, 322, 323, 324, 0, 325, 326, 327, + 328, 329, 330, 331, 332, 333, 0, 334, 335, 336, + 337, 338, 339, 0, 340, 341, 342, 343, 344, 345, + 346, 347, 0, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 0, 361, 362, 0, + 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 0, 379, 380, 381, 382, + 383, 0, 384, 385, 386, 387, 388, 0, 390, 391, + 392, 393, 0, 394, 395, 396, 397, 398, 399, 400, + 401, 402, 403, 404, 502, 406, 407, 408, 0, 409, + 410, 0, 411, 0, 413, 414, 415, 416, 417, 0, + 418, 419, 0, 0, 420, 421, 422, 423, 424, 0, + 425, 426, 427, 428, 429, 430, 431, 432, 0, 0, + 433, 434, 435, 436, 437, 0, 0, 438, 439, 440, + 441, 442, 443, 444, 0, 445, 0, 447, 448, 449, + 450, 0, 0, 451, 0, 0, 452, 453, 454, 455, + 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 498, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 93, 94, 95, 96, 97, 98, 99, + 100, 0, 101, 102, 103, 0, 0, 0, 0, 0, + 0, 0, 104, 105, 0, 106, 107, 108, 0, 110, + 111, 112, 113, 114, 0, 116, 117, 0, 118, 119, + 120, 121, 122, 123, 0, 0, 124, 125, 126, 127, + 128, 0, 129, 130, 131, 132, 133, 0, 0, 0, + 135, 136, 137, 138, 139, 140, 0, 142, 143, 144, + 0, 145, 146, 147, 148, 149, 150, 0, 0, 152, + 153, 154, 0, 0, 0, 0, 0, 0, 0, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 0, + 166, 0, 167, 168, 169, 170, 171, 172, 0, 173, + 174, 175, 176, 177, 0, 0, 178, 179, 180, 181, + 182, 0, 183, 184, 185, 0, 186, 187, 188, 0, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 0, 199, 0, 200, 201, 202, 203, 0, 204, 0, + 205, 0, 0, 0, 208, 209, 210, 0, 212, 0, + 213, 0, 214, 215, 216, 0, 217, 218, 219, 220, + 221, 1818, 223, 0, 225, 226, 227, 228, 0, 229, + 230, 231, 232, 233, 234, 0, 235, 0, 237, 238, + 239, 240, 241, 242, 243, 244, 0, 245, 0, 246, + 0, 0, 249, 0, 251, 252, 253, 254, 255, 0, + 0, 256, 0, 258, 0, 0, 260, 261, 262, 0, + 0, 263, 264, 265, 266, 267, 500, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 287, 0, 289, 290, 291, + 292, 293, 0, 294, 295, 0, 297, 0, 298, 299, + 300, 301, 302, 303, 0, 304, 305, 0, 0, 306, + 307, 308, 0, 0, 309, 310, 0, 312, 0, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 0, 325, 326, 327, 328, 329, 330, 331, 332, 333, + 0, 334, 335, 336, 337, 338, 339, 0, 340, 341, + 342, 343, 344, 345, 346, 347, 0, 348, 349, 350, + 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, + 0, 361, 362, 0, 364, 365, 366, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 0, + 379, 380, 381, 382, 383, 0, 384, 385, 386, 387, + 388, 0, 390, 391, 392, 393, 0, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, 404, 502, 406, + 407, 408, 0, 409, 410, 0, 411, 0, 413, 414, + 415, 416, 417, 0, 418, 419, 0, 0, 420, 421, + 422, 423, 424, 0, 425, 426, 427, 428, 429, 430, + 431, 432, 0, 0, 433, 434, 435, 436, 437, 0, + 0, 438, 439, 440, 441, 442, 443, 444, 0, 445, + 0, 447, 448, 449, 450, 0, 0, 451, 0, 0, + 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 498, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 93, 94, 95, + 96, 97, 98, 99, 100, 0, 101, 102, 103, 0, + 0, 0, 0, 0, 0, 0, 104, 105, 0, 106, + 107, 108, 0, 110, 111, 112, 113, 114, 0, 116, + 117, 0, 118, 119, 120, 121, 122, 123, 0, 0, + 124, 125, 126, 127, 128, 0, 129, 130, 131, 132, + 133, 0, 0, 0, 135, 136, 137, 138, 139, 140, + 0, 142, 143, 144, 0, 145, 146, 147, 148, 149, + 150, 0, 0, 152, 153, 154, 0, 0, 0, 0, + 0, 0, 0, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 0, 166, 0, 167, 168, 169, 170, + 171, 172, 0, 173, 174, 175, 176, 177, 0, 0, + 178, 179, 180, 181, 182, 0, 183, 184, 185, 0, + 186, 187, 188, 0, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 0, 199, 0, 200, 201, 202, + 203, 0, 204, 0, 205, 0, 0, 0, 208, 209, + 210, 0, 212, 0, 213, 0, 214, 215, 216, 0, + 217, 218, 219, 220, 221, 222, 223, 0, 225, 226, + 227, 228, 0, 229, 230, 231, 232, 233, 234, 0, + 235, 0, 237, 238, 239, 240, 241, 242, 243, 244, + 0, 245, 0, 246, 0, 0, 249, 0, 251, 252, + 253, 254, 255, 0, 0, 256, 0, 258, 0, 0, + 260, 261, 262, 0, 0, 263, 264, 265, 266, 267, + 500, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 0, 289, 290, 291, 292, 293, 0, 294, 295, 0, + 297, 0, 298, 299, 300, 301, 302, 303, 0, 304, + 305, 0, 0, 306, 307, 308, 0, 0, 309, 310, + 0, 312, 0, 314, 315, 316, 317, 318, 319, 320, + 0, 322, 323, 324, 0, 325, 326, 327, 328, 329, + 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, + 339, 0, 340, 0, 342, 343, 344, 345, 346, 347, + 0, 348, 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 0, 361, 362, 0, 364, 365, + 366, 367, 0, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 0, 379, 380, 381, 382, 383, 0, + 384, 385, 386, 387, 388, 0, 390, 391, 392, 393, + 0, 394, 395, 396, 397, 398, 399, 400, 401, 402, + 403, 404, 502, 406, 407, 408, 0, 409, 410, 0, + 411, 0, 413, 414, 415, 416, 417, 0, 418, 419, + 0, 0, 420, 421, 422, 423, 424, 0, 425, 426, + 427, 428, 429, 430, 431, 432, 0, 0, 433, 434, + 435, 436, 437, 0, 0, 438, 439, 440, 441, 442, + 443, 444, 0, 445, 0, 447, 448, 449, 450, 0, + 0, 451, 0, 0, 452, 453, 454, 455, 456, 457, + 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 661, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 93, 94, 95, 96, 97, 98, 99, 100, 0, + 101, 102, 103, 0, 0, 0, 0, 0, 0, 0, + 104, 105, 0, 106, 107, 108, 662, 110, 111, 112, + 0, 663, 664, 665, 666, 0, 118, 119, 120, 121, + 122, 123, 0, 0, 124, 125, 667, 668, 128, 0, + 129, 130, 131, 132, 0, 0, 669, 0, 135, 136, + 137, 138, 139, 140, 670, 142, 143, 144, 0, 145, + 146, 147, 148, 149, 150, 0, 671, 152, 153, 154, + 0, 0, 0, 672, 0, 0, 0, 156, 157, 158, + 159, 160, 161, 162, 673, 674, 165, 0, 166, 0, + 167, 168, 169, 170, 171, 172, 0, 173, 174, 175, + 176, 177, 0, 0, 178, 179, 675, 181, 182, 0, + 183, 184, 185, 0, 186, 187, 188, 0, 189, 190, + 191, 192, 0, 194, 195, 196, 197, 0, 0, 199, + 0, 200, 201, 676, 203, 0, 204, 0, 205, 677, + 0, 678, 208, 209, 210, 679, 212, 0, 213, 0, + 0, 0, 216, 0, 217, 218, 219, 220, 221, 680, + 223, 681, 225, 226, 227, 228, 0, 229, 230, 231, + 232, 233, 234, 0, 235, 682, 0, 238, 239, 240, + 241, 242, 683, 684, 0, 685, 0, 246, 686, 687, + 249, 688, 251, 252, 253, 254, 255, 0, 0, 256, + 689, 258, 690, 0, 260, 261, 262, 0, 0, 263, + 264, 265, 266, 267, 691, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + 284, 285, 286, 692, 693, 694, 290, 291, 292, 0, + 0, 294, 295, 695, 297, 0, 0, 299, 696, 301, + 302, 303, 0, 304, 305, 0, 0, 306, 307, 308, + 0, 0, 309, 0, 697, 312, 698, 0, 315, 316, + 317, 318, 319, 320, 321, 322, 323, 324, 0, 325, + 326, 0, 328, 329, 0, 331, 332, 333, 0, 334, + 335, 336, 337, 338, 339, 0, 340, 341, 342, 699, + 344, 345, 346, 347, 0, 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 0, 361, + 362, 700, 364, 365, 366, 701, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 0, 379, 380, + 381, 382, 383, 0, 384, 702, 386, 387, 388, 703, + 390, 391, 704, 393, 0, 394, 395, 396, 397, 398, + 399, 400, 401, 402, 403, 404, 705, 406, 0, 408, + 0, 409, 410, 0, 411, 706, 413, 414, 415, 416, + 417, 0, 707, 708, 0, 0, 420, 421, 0, 423, + 0, 0, 425, 426, 709, 428, 429, 430, 431, 432, + 0, 0, 433, 434, 435, 436, 437, 0, 0, 438, + 439, 440, 441, 442, 0, 710, 0, 445, 711, 447, + 448, 449, 450, 0, 0, 451, 0, 0, 452, 453, + 454, 455, 456, 457, 661, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 469, 470, 471, 472, 0, + 93, 94, 95, 96, 97, 98, 99, 100, 0, 101, + 102, 103, 0, 0, 0, 0, 0, 0, 0, 104, + 105, 0, 106, 107, 108, 662, 110, 111, 112, 0, + 663, 664, 665, 666, 0, 118, 119, 120, 121, 122, + 123, 0, 0, 124, 125, 667, 668, 128, 0, 129, + 130, 131, 132, 0, 0, 669, 0, 135, 136, 137, + 138, 139, 140, 670, 142, 143, 144, 0, 145, 146, + 147, 148, 149, 150, 0, 671, 152, 153, 154, 0, + 0, 0, 672, 0, 0, 0, 156, 157, 158, 159, + 160, 161, 162, 673, 674, 165, 0, 166, 0, 167, + 168, 169, 170, 171, 172, 0, 173, 174, 175, 176, + 177, 0, 0, 178, 179, 675, 181, 182, 0, 183, + 184, 185, 0, 186, 187, 188, 0, 189, 190, 191, + 192, 0, 194, 195, 196, 197, 0, 0, 199, 0, + 200, 201, 676, 203, 0, 204, 0, 205, 677, 0, + 678, 208, 209, 210, 679, 212, 0, 213, 0, 0, + 0, 216, 0, 217, 218, 219, 220, 221, 222, 223, + 681, 225, 226, 227, 228, 0, 229, 230, 231, 232, + 233, 234, 0, 235, 682, 0, 238, 239, 240, 241, + 242, 683, 684, 0, 685, 0, 246, 686, 687, 249, + 688, 251, 252, 253, 254, 255, 0, 0, 256, 689, + 258, 690, 0, 260, 261, 262, 0, 0, 263, 264, + 265, 266, 267, 691, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 692, 693, 694, 290, 291, 292, 0, 0, + 294, 295, 695, 297, 0, 0, 299, 696, 301, 302, + 303, 0, 304, 305, 0, 0, 306, 307, 308, 0, + 0, 309, 0, 697, 312, 698, 0, 315, 316, 317, + 318, 319, 320, 321, 322, 323, 324, 0, 325, 326, + 0, 328, 329, 0, 331, 332, 333, 0, 334, 335, + 336, 337, 338, 339, 0, 340, 341, 342, 699, 344, + 345, 346, 347, 0, 348, 349, 350, 351, 352, 353, + 354, 355, 356, 357, 358, 359, 360, 0, 361, 362, + 700, 364, 365, 366, 701, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, 378, 0, 379, 380, 381, + 382, 383, 0, 384, 702, 386, 387, 388, 703, 390, + 391, 704, 393, 0, 394, 395, 396, 397, 398, 399, + 400, 401, 402, 403, 404, 705, 406, 0, 408, 0, + 409, 410, 0, 411, 706, 413, 414, 415, 416, 417, + 0, 707, 708, 0, 0, 420, 421, 0, 423, 0, + 0, 425, 426, 709, 428, 429, 430, 431, 432, 0, + 0, 433, 434, 435, 436, 437, 0, 0, 438, 439, + 440, 441, 442, 0, 710, 0, 445, 711, 447, 448, + 449, 450, 0, 0, 451, 0, 0, 452, 453, 454, + 455, 456, 457, 2397, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 469, 470, 471, 472, 0, 93, + 94, 95, 96, 97, 98, 99, 100, 0, 101, 102, + 103, 0, 0, 0, 0, 0, 0, 0, 104, 105, + 0, 106, 107, 108, 2398, 110, 111, 112, 0, 663, + 2399, 665, 666, 0, 118, 119, 120, 121, 122, 123, + 0, 0, 124, 125, 667, 668, 128, 0, 129, 130, + 131, 132, 0, 0, 2400, 0, 135, 136, 137, 138, + 139, 140, 2401, 142, 143, 144, 0, 145, 146, 147, + 148, 149, 150, 0, 2402, 152, 153, 154, 0, 0, + 0, 2403, 0, 0, 0, 156, 157, 158, 159, 160, + 161, 162, 673, 674, 165, 0, 166, 0, 167, 168, + 169, 170, 171, 172, 0, 173, 174, 175, 176, 177, + 0, 0, 178, 179, 675, 181, 182, 0, 183, 184, + 185, 0, 186, 187, 188, 0, 189, 190, 191, 192, + 0, 194, 195, 196, 197, 0, 0, 199, 0, 200, + 201, 676, 203, 0, 204, 0, 205, 2404, 0, 2405, + 208, 209, 210, 2406, 212, 0, 213, 0, 0, 0, + 216, 0, 217, 218, 219, 220, 221, 222, 223, 2407, + 225, 226, 227, 228, 0, 229, 230, 231, 232, 233, + 234, 0, 235, 2408, 0, 238, 239, 240, 241, 242, + 683, 684, 0, 685, 0, 246, 2409, 2410, 249, 2411, + 251, 252, 253, 254, 255, 0, 0, 256, 2412, 258, + 2413, 0, 260, 261, 262, 0, 0, 263, 264, 265, + 266, 267, 2607, 269, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, + 286, 692, 2415, 694, 290, 291, 292, 0, 0, 294, + 295, 2417, 297, 0, 0, 299, 696, 301, 302, 303, + 0, 304, 305, 0, 0, 306, 307, 308, 0, 0, + 309, 0, 2419, 312, 2420, 0, 315, 316, 317, 318, + 319, 320, 321, 322, 323, 324, 0, 325, 326, 0, + 328, 329, 0, 331, 332, 333, 0, 334, 335, 336, + 337, 338, 339, 0, 340, 341, 342, 699, 344, 345, + 346, 347, 0, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 0, 361, 362, 2421, + 364, 365, 366, 0, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 0, 379, 380, 381, 382, + 383, 0, 384, 0, 386, 387, 388, 2423, 390, 391, + 704, 393, 0, 394, 395, 396, 397, 398, 399, 400, + 401, 402, 403, 404, 2608, 406, 0, 408, 0, 409, + 410, 0, 411, 2425, 413, 414, 415, 416, 417, 0, + 707, 708, 0, 0, 420, 421, 0, 423, 0, 0, + 425, 426, 2426, 428, 429, 430, 431, 432, 0, 0, + 433, 434, 435, 436, 437, 0, 0, 438, 439, 440, + 441, 442, 0, 710, 0, 445, 2427, 447, 448, 449, + 450, 0, 0, 451, 0, 0, 452, 453, 454, 455, + 456, 457, 661, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 469, 470, 471, 472, 0, 93, 94, + 95, 96, 97, 98, 99, 100, 0, 101, 102, 103, + 0, 0, 0, 0, 0, 0, 0, 104, 105, 0, + 106, 107, 108, 662, 110, 111, 112, 0, 663, 664, + 665, 666, 0, 118, 119, 120, 121, 122, 123, 0, + 0, 124, 125, 667, 668, 128, 0, 129, 130, 131, + 132, 0, 0, 669, 0, 135, 136, 137, 138, 139, + 140, 670, 142, 143, 144, 0, 145, 146, 147, 148, + 149, 150, 0, 671, 152, 153, 154, 0, 0, 0, + 672, 0, 0, 0, 156, 157, 158, 159, 160, 161, + 162, 673, 674, 165, 0, 166, 0, 167, 168, 169, + 170, 171, 172, 0, 173, 174, 175, 176, 177, 0, + 0, 178, 179, 675, 181, 182, 0, 183, 184, 185, + 0, 186, 187, 188, 0, 189, 190, 191, 192, 0, + 194, 195, 196, 197, 0, 0, 199, 0, 200, 201, + 676, 203, 0, 204, 0, 205, 677, 0, 678, 208, + 209, 210, 679, 212, 0, 213, 0, 0, 0, 216, + 0, 217, 218, 219, 220, 221, 222, 223, 681, 225, + 226, 227, 228, 0, 229, 230, 231, 232, 233, 234, + 0, 235, 682, 0, 238, 239, 240, 241, 242, 683, + 684, 0, 685, 0, 246, 686, 687, 249, 688, 251, + 252, 253, 254, 255, 0, 0, 256, 689, 258, 690, + 0, 260, 261, 262, 0, 0, 263, 264, 265, 266, + 267, 0, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 692, 693, 694, 290, 291, 292, 0, 0, 294, 295, + 695, 297, 0, 0, 299, 696, 301, 302, 303, 0, + 304, 305, 0, 0, 306, 307, 308, 0, 0, 309, + 0, 697, 312, 698, 0, 315, 316, 317, 318, 319, + 320, 321, 322, 323, 324, 0, 325, 326, 0, 328, + 329, 0, 331, 332, 333, 0, 334, 335, 336, 337, + 338, 339, 0, 340, 341, 342, 699, 344, 345, 346, + 347, 0, 348, 349, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 0, 361, 362, 700, 364, + 365, 366, 0, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 0, 379, 380, 381, 382, 383, + 0, 384, 0, 386, 387, 388, 703, 390, 391, 704, + 393, 0, 394, 395, 396, 397, 398, 399, 400, 401, + 402, 403, 404, 0, 406, 0, 408, 0, 409, 410, + 0, 411, 706, 413, 414, 415, 416, 417, 0, 707, + 708, 0, 0, 420, 421, 0, 423, 0, 0, 425, + 426, 709, 428, 429, 430, 431, 432, 0, 0, 433, + 434, 435, 436, 437, 0, 0, 438, 439, 440, 441, + 442, 0, 710, 0, 445, 711, 447, 448, 449, 450, + 0, 0, 451, 0, 0, 452, 453, 454, 455, 456, + 457, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 469, 470, 471, 472 +}; + +static const yytype_int16 yycheck[] = +{ + 6, 6, 637, 622, 0, 608, 535, 529, 629, 999, + 492, 526, 6, 59, 36, 565, 799, 702, 997, 799, + 583, 0, 1173, 0, 1276, 879, 1389, 0, 1740, 1392, + 0, 708, 588, 972, 30, 16, 1768, 16, 881, 1771, + 977, 1142, 1814, 631, 1142, 1142, 528, 1142, 533, 1229, + 974, 61, 1038, 1820, 897, 1822, 31, 968, 1178, 534, + 2181, 0, 535, 61, 731, 2062, 909, 734, 1278, 1811, + 2182, 622, 1760, 624, 2154, 626, 35, 2154, 1002, 1305, + 1306, 1696, 1257, 79, 1858, 1859, 1860, 2193, 807, 2200, + 21, 0, 5, 5, 2014, 5, 667, 668, 5, 2068, + 11, 0, 5, 5, 5, 5, 50, 9, 5, 9, + 13, 14, 13, 14, 89, 9, 11, 1633, 1634, 2468, + 5, 5, 1638, 694, 5, 5, 58, 5, 13, 14, + 41, 5, 13, 14, 917, 13, 14, 1358, 957, 73, + 5, 5, 540, 1885, 5, 5, 605, 5, 5, 2471, + 605, 2611, 1408, 214, 5, 75, 168, 642, 107, 1143, + 13, 14, 73, 1679, 1680, 0, 86, 3, 4, 5, + 1736, 4, 40, 9, 117, 168, 9, 1410, 9, 1271, + 67, 16, 738, 169, 93, 1751, 1396, 1271, 4, 866, + 40, 2520, 2067, 9, 93, 30, 58, 120, 2002, 75, + 2454, 36, 3, 986, 83, 11, 989, 990, 1950, 1951, + 86, 58, 1271, 27, 58, 27, 27, 58, 15, 281, + 34, 48, 34, 34, 2642, 305, 61, 2556, 220, 2093, + 31, 32, 120, 289, 269, 41, 283, 120, 107, 2542, + 169, 2436, 11, 674, 79, 289, 137, 135, 127, 122, + 117, 2706, 2745, 68, 2384, 826, 827, 27, 272, 2125, + 115, 106, 13, 14, 168, 696, 162, 73, 374, 108, + 799, 305, 41, 2904, 266, 436, 169, 806, 165, 115, + 59, 852, 330, 188, 207, 160, 2813, 414, 67, 145, + 400, 1010, 11, 37, 252, 253, 727, 160, 1017, 118, + 985, 2075, 436, 108, 73, 455, 2628, 115, 11, 158, + 203, 482, 452, 2642, 330, 147, 118, 344, 2315, 882, + 354, 877, 2319, 4, 495, 435, 219, 802, 9, 479, + 482, 458, 493, 365, 326, 228, 924, 2306, 41, 2205, + 2971, 493, 2422, 0, 2465, 372, 173, 910, 2841, 224, + 366, 2463, 2124, 401, 73, 493, 212, 497, 1973, 493, + 130, 1975, 189, 195, 11, 379, 167, 194, 169, 401, + 73, 190, 301, 936, 283, 2107, 2679, 213, 186, 2121, + 124, 2123, 231, 375, 283, 401, 1271, 493, 190, 2003, + 919, 920, 405, 208, 407, 2744, 2923, 266, 234, 434, + 448, 246, 265, 230, 362, 363, 273, 838, 488, 254, + 442, 967, 163, 345, 2609, 311, 11, 939, 273, 412, + 2875, 300, 266, 1633, 1634, 856, 2886, 315, 1638, 316, + 2305, 493, 448, 289, 1153, 2239, 497, 346, 343, 11, + 1043, 497, 434, 15, 1696, 2774, 493, 346, 2941, 378, + 2580, 23, 401, 497, 488, 234, 349, 1549, 1550, 1278, + 268, 493, 34, 35, 1548, 1981, 1982, 1983, 1984, 1679, + 1680, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, + 1996, 2810, 2224, 345, 2902, 497, 482, 2741, 2352, 482, + 1549, 1430, 412, 2842, 2060, 438, 2062, 294, 345, 240, + 1486, 345, 495, 482, 345, 482, 965, 493, 412, 482, + 965, 434, 482, 535, 2620, 87, 1742, 1152, 1770, 1775, + 526, 2843, 1143, 2039, 2040, 1515, 1510, 406, 372, 535, + 398, 2611, 2529, 445, 2611, 933, 412, 2534, 389, 390, + 2537, 1762, 429, 1776, 457, 240, 455, 457, 398, 493, + 377, 434, 2521, 2856, 535, 534, 455, 491, 564, 565, + 451, 495, 608, 436, 497, 497, 479, 577, 382, 479, + 382, 382, 428, 2902, 130, 1750, 2496, 1396, 489, 577, + 493, 493, 588, 493, 491, 494, 493, 496, 495, 2361, + 493, 493, 493, 493, 489, 494, 493, 496, 492, 1585, + 94, 597, 130, 1174, 1175, 586, 496, 2374, 493, 493, + 1166, 353, 493, 493, 545, 493, 446, 358, 597, 493, + 597, 627, 628, 629, 597, 600, 1247, 597, 493, 493, + 589, 2743, 493, 493, 1353, 493, 493, 30, 2749, 455, + 493, 27, 2748, 2324, 340, 446, 2327, 482, 484, 485, + 497, 484, 485, 484, 485, 268, 497, 1172, 597, 325, + 273, 54, 2350, 479, 1549, 1550, 1551, 174, 484, 485, + 115, 488, 1187, 1261, 75, 169, 1459, 2674, 495, 2453, + 486, 487, 488, 489, 2565, 86, 1469, 75, 354, 1472, + 4, 432, 149, 1314, 240, 9, 702, 220, 86, 534, + 535, 1223, 1231, 27, 1260, 2586, 1262, 1887, 457, 203, + 1266, 324, 1300, 1301, 2456, 484, 485, 486, 487, 488, + 489, 1973, 278, 1279, 1280, 219, 1282, 234, 4, 1292, + 479, 493, 738, 9, 228, 1356, 2848, 432, 1220, 1221, + 268, 2356, 577, 266, 130, 1227, 1302, 197, 117, 2315, + 278, 493, 493, 2319, 78, 1230, 8, 1345, 1231, 11, + 247, 158, 597, 87, 16, 17, 18, 1355, 262, 1357, + 240, 1981, 1982, 1983, 1984, 2896, 417, 1987, 1988, 1989, + 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1570, 457, 283, + 1570, 1911, 116, 799, 1309, 2567, 2022, 1917, 493, 1575, + 806, 807, 808, 1579, 23, 1581, 2886, 491, 1662, 2886, + 479, 495, 358, 8, 1633, 1634, 11, 1660, 824, 1638, + 240, 488, 494, 802, 493, 497, 1447, 240, 495, 2039, + 2040, 448, 201, 1744, 231, 1317, 1455, 484, 485, 486, + 487, 488, 489, 361, 4, 2726, 41, 853, 1838, 9, + 493, 296, 375, 48, 158, 349, 878, 240, 2970, 163, + 1679, 1680, 186, 1647, 1531, 1649, 1650, 873, 874, 875, + 23, 877, 878, 493, 198, 1861, 29, 1428, 73, 1482, + 1483, 1484, 5, 280, 2035, 1552, 432, 1554, 358, 1510, + 1557, 486, 487, 488, 489, 901, 36, 266, 405, 268, + 407, 476, 2154, 494, 1455, 197, 497, 158, 365, 218, + 130, 434, 163, 919, 920, 55, 135, 145, 13, 14, + 365, 1764, 1846, 1474, 1439, 432, 495, 231, 1479, 501, + 158, 31, 32, 491, 283, 163, 156, 495, 358, 2711, + 950, 951, 436, 953, 401, 358, 952, 493, 143, 2716, + 956, 957, 950, 951, 2520, 953, 401, 476, 530, 1896, + 330, 967, 432, 2529, 1901, 457, 106, 802, 2534, 944, + 486, 2537, 1528, 2489, 494, 358, 280, 497, 173, 985, + 231, 167, 135, 1465, 212, 442, 497, 479, 1470, 24, + 2556, 64, 65, 93, 189, 30, 366, 442, 455, 194, + 23, 493, 493, 231, 1010, 840, 29, 405, 494, 407, + 455, 1017, 432, 566, 567, 494, 569, 589, 1503, 432, + 168, 494, 479, 493, 497, 93, 1001, 494, 1543, 280, + 497, 401, 1038, 285, 479, 230, 493, 2217, 491, 214, + 493, 1570, 495, 878, 79, 13, 14, 494, 493, 432, + 497, 54, 280, 273, 1583, 493, 196, 494, 278, 476, + 497, 289, 2578, 497, 388, 499, 358, 391, 287, 405, + 150, 407, 1587, 493, 366, 23, 2642, 455, 448, 457, + 493, 29, 2183, 218, 494, 2183, 2183, 497, 2183, 23, + 285, 1647, 1648, 1649, 1650, 29, 338, 2809, 494, 23, + 494, 497, 150, 497, 2356, 29, 246, 150, 2674, 401, + 493, 405, 135, 407, 254, 950, 951, 494, 953, 494, + 497, 494, 497, 342, 497, 344, 266, 494, 1684, 494, + 2646, 2282, 497, 1655, 287, 1738, 494, 1143, 494, 497, + 602, 497, 604, 23, 2320, 2135, 2322, 1153, 494, 29, + 1817, 497, 1819, 372, 150, 2134, 448, 297, 13, 14, + 1166, 1941, 1981, 1982, 1983, 1984, 1172, 1173, 1987, 1988, + 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1731, 1732, + 493, 1187, 377, 2122, 495, 338, 268, 135, 2960, 342, + 36, 2903, 2924, 2925, 13, 14, 2133, 2176, 2135, 419, + 428, 135, 448, 5, 344, 493, 8, 82, 2774, 459, + 430, 135, 14, 494, 2926, 493, 497, 150, 149, 372, + 2039, 2040, 445, 25, 312, 1231, 366, 29, 480, 481, + 482, 493, 484, 485, 486, 487, 488, 489, 1915, 1916, + 494, 1247, 2974, 497, 2810, 1880, 386, 35, 2091, 494, + 1231, 1230, 497, 493, 1260, 135, 1262, 13, 14, 1265, + 1266, 1257, 493, 491, 287, 365, 494, 495, 493, 1275, + 2982, 1277, 1278, 1279, 1280, 1281, 1282, 1283, 1257, 2489, + 1257, 150, 477, 130, 1257, 494, 439, 1257, 497, 484, + 485, 486, 487, 488, 489, 283, 1302, 365, 1304, 13, + 14, 401, 150, 1309, 1310, 1311, 1312, 1313, 1314, 156, + 150, 494, 1318, 1319, 497, 338, 401, 1323, 1939, 342, + 494, 1327, 493, 497, 1330, 1331, 1332, 1333, 1334, 1335, + 1336, 1337, 1338, 401, 36, 1341, 2902, 13, 14, 287, + 1346, 2492, 442, 1349, 229, 1351, 446, 1353, 494, 372, + 1356, 497, 493, 287, 494, 455, 5, 494, 494, 2611, + 497, 497, 494, 287, 491, 497, 938, 23, 2578, 5, + 1376, 2154, 67, 29, 442, 494, 13, 14, 497, 479, + 1895, 526, 163, 494, 493, 1381, 497, 455, 494, 493, + 1396, 497, 1373, 493, 342, 1230, 494, 13, 14, 497, + 2390, 1407, 1408, 494, 338, 5, 497, 287, 342, 5, + 494, 479, 1941, 497, 338, 493, 439, 493, 342, 493, + 115, 268, 1257, 2362, 372, 493, 273, 494, 493, 2017, + 497, 278, 494, 1439, 365, 497, 2646, 494, 372, 1445, + 497, 1447, 494, 494, 493, 497, 497, 1962, 372, 5, + 494, 8, 1934, 497, 2010, 13, 14, 2311, 338, 16, + 17, 18, 342, 494, 494, 1980, 497, 497, 5, 494, + 401, 2325, 497, 494, 146, 494, 497, 172, 497, 135, + 1486, 353, 354, 1489, 1490, 1320, 1492, 493, 20, 21, + 2005, 439, 372, 13, 14, 493, 2647, 2012, 2051, 2052, + 2053, 2054, 184, 185, 1510, 439, 9, 494, 493, 2072, + 497, 442, 2100, 13, 14, 439, 2879, 1523, 2881, 67, + 13, 14, 1528, 1519, 455, 73, 6, 494, 13, 14, + 497, 11, 2153, 494, 2155, 15, 497, 1543, 86, 493, + 20, 21, 22, 23, 24, 456, 1381, 27, 479, 2216, + 30, 31, 15, 494, 34, 35, 497, 702, 494, 439, + 214, 497, 493, 493, 1570, 494, 2169, 115, 497, 117, + 252, 253, 419, 268, 13, 14, 493, 1583, 273, 1585, + 174, 1587, 494, 430, 494, 497, 1592, 497, 497, 494, + 493, 1597, 497, 2956, 13, 14, 13, 14, 2381, 79, + 13, 14, 296, 197, 13, 14, 86, 87, 88, 89, + 90, 13, 14, 1635, 13, 14, 13, 14, 13, 14, + 493, 316, 353, 354, 172, 256, 257, 1633, 1634, 1635, + 493, 287, 1638, 493, 2886, 94, 493, 332, 2617, 2154, + 234, 1647, 1648, 1649, 1650, 362, 363, 353, 354, 353, + 354, 1657, 1224, 201, 1226, 1661, 493, 8, 1664, 493, + 11, 97, 1684, 808, 36, 16, 17, 18, 163, 372, + 2489, 365, 280, 1679, 1680, 163, 365, 278, 1684, 229, + 362, 363, 338, 493, 1519, 412, 342, 493, 145, 919, + 920, 412, 1698, 86, 288, 1701, 497, 1703, 2213, 54, + 54, 158, 412, 2483, 259, 412, 163, 401, 494, 502, + 169, 412, 401, 455, 8, 150, 372, 11, 1724, 93, + 268, 495, 16, 17, 18, 273, 2393, 2394, 285, 268, + 1736, 1736, 142, 1755, 429, 268, 50, 2422, 493, 33, + 36, 436, 1736, 2331, 203, 1751, 1751, 36, 442, 493, + 9, 35, 410, 442, 1750, 212, 491, 1751, 2346, 2578, + 219, 455, 410, 1769, 497, 491, 455, 412, 316, 228, + 412, 1750, 917, 1750, 231, 493, 451, 1750, 1784, 1785, + 1750, 95, 412, 439, 332, 479, 412, 11, 340, 497, + 479, 2341, 492, 502, 273, 410, 493, 1803, 497, 493, + 1635, 493, 412, 262, 493, 168, 177, 121, 494, 159, + 493, 405, 436, 407, 1820, 1821, 1822, 36, 212, 497, + 220, 375, 284, 280, 305, 139, 497, 2646, 2611, 143, + 305, 493, 289, 220, 268, 429, 220, 289, 432, 321, + 985, 281, 448, 194, 150, 150, 493, 493, 455, 1684, + 164, 283, 268, 167, 494, 1861, 491, 476, 476, 1431, + 494, 494, 494, 283, 268, 216, 494, 1702, 182, 1441, + 36, 1443, 36, 494, 1446, 492, 168, 2392, 168, 493, + 1452, 429, 1454, 1718, 495, 494, 476, 412, 436, 1895, + 349, 494, 494, 452, 1466, 494, 494, 494, 493, 1471, + 493, 1736, 494, 1475, 1476, 1477, 1478, 494, 1480, 1481, + 494, 493, 293, 442, 452, 1750, 1751, 283, 482, 284, + 1755, 434, 216, 480, 481, 482, 284, 484, 485, 486, + 487, 488, 489, 1939, 285, 1941, 478, 284, 239, 412, + 268, 1937, 493, 150, 497, 197, 287, 150, 150, 275, + 2940, 412, 412, 1959, 2483, 275, 1962, 412, 412, 273, + 494, 492, 1968, 493, 281, 1971, 494, 281, 1974, 455, + 497, 428, 283, 150, 1980, 1981, 1982, 1983, 1984, 36, + 492, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, + 1996, 285, 2014, 492, 2000, 2001, 150, 273, 141, 2005, + 168, 2047, 11, 483, 2010, 163, 2012, 494, 2014, 489, + 324, 543, 492, 545, 546, 168, 496, 2023, 494, 493, + 2026, 501, 2028, 2045, 494, 494, 452, 1172, 1173, 2035, + 2036, 401, 168, 2039, 2040, 479, 568, 177, 2044, 2045, + 2062, 497, 1187, 36, 494, 494, 346, 84, 528, 529, + 530, 441, 493, 2656, 2060, 2060, 2062, 2062, 284, 150, + 493, 172, 55, 423, 494, 545, 2060, 2073, 2062, 494, + 494, 493, 36, 494, 497, 493, 79, 2083, 492, 436, + 168, 493, 36, 494, 564, 565, 566, 567, 494, 569, + 497, 2712, 2727, 2099, 2576, 493, 2611, 219, 494, 403, + 580, 55, 1937, 2886, 292, 494, 494, 493, 493, 589, + 219, 290, 54, 106, 181, 494, 455, 199, 482, 187, + 600, 273, 273, 482, 412, 412, 495, 495, 495, 480, + 481, 482, 612, 484, 485, 486, 487, 488, 489, 2661, + 36, 268, 495, 2149, 107, 493, 495, 2153, 2154, 2155, + 495, 495, 106, 495, 283, 495, 494, 2679, 495, 495, + 495, 495, 495, 2678, 1309, 495, 2681, 36, 648, 649, + 650, 495, 495, 8, 495, 455, 11, 495, 168, 2014, + 495, 2816, 495, 495, 493, 495, 480, 481, 482, 302, + 484, 485, 486, 487, 488, 489, 495, 86, 495, 88, + 495, 90, 495, 196, 495, 219, 41, 2213, 2204, 454, + 2045, 493, 493, 48, 493, 2771, 86, 131, 172, 494, + 332, 493, 493, 220, 2230, 2060, 81, 2062, 115, 36, + 73, 150, 494, 150, 122, 36, 494, 354, 73, 2795, + 8, 2797, 196, 11, 354, 54, 36, 493, 16, 17, + 18, 2733, 493, 246, 493, 493, 493, 8, 323, 441, + 11, 254, 497, 73, 2885, 2787, 36, 799, 186, 436, + 2276, 2277, 2891, 266, 806, 2281, 2282, 423, 67, 286, + 2286, 67, 493, 2289, 2290, 493, 36, 497, 2294, 436, + 41, 372, 246, 482, 1439, 273, 186, 48, 244, 493, + 254, 36, 423, 493, 297, 286, 286, 493, 143, 2315, + 2315, 494, 266, 2319, 2319, 356, 494, 493, 266, 353, + 9, 2315, 73, 283, 339, 2319, 199, 1899, 283, 2811, + 283, 33, 812, 494, 493, 2341, 120, 434, 173, 9, + 23, 22, 597, 297, 494, 2136, 29, 2343, 2344, 2149, + 1453, 344, 884, 36, 189, 1815, 2345, 2097, 2810, 194, + 2552, 893, 2882, 2189, 2888, 2386, 2963, 2719, 2374, 2204, + 2939, 2886, 55, 366, 906, 2927, 2630, 2383, 1809, 1821, + 2885, 972, 2937, 1873, 2194, 917, 2392, 919, 920, 2153, + 344, 1806, 143, 386, 2883, 230, 1220, 1172, 1543, 879, + 1877, 1939, 2483, 2179, 911, 1769, 1424, 2784, 2805, 2922, + 1784, 960, 366, 959, 938, 1396, 2422, 2077, 2865, 2799, + 2337, 2699, 173, 106, 1423, 1751, 962, 2062, 2675, 2306, + 2060, 2774, 386, 2773, 2791, 2321, 2792, 2548, 189, 1271, + 1271, 921, 1587, 194, 1271, 1271, 2868, 526, 216, 2869, + 285, 2852, 135, 1347, 1662, 1770, 1492, 1262, 938, 939, + 1593, 1702, 1699, 526, 944, 945, 946, 1351, 1739, 2076, + 2466, 2766, 1881, 1231, 1373, 1583, 944, 2483, 1374, 230, + 2315, -1, 2098, 2489, 2319, -1, 2492, -1, -1, -1, + 2496, 971, 972, -1, -1, -1, -1, -1, 2504, 2505, + -1, -1, 2508, -1, 984, -1, -1, -1, 2343, 2344, + -1, -1, -1, 196, 2520, 2520, -1, 285, -1, -1, + -1, 1001, -1, 2529, 2529, 1005, 2520, -1, 2534, 2534, + -1, 2537, 2537, -1, 285, 2529, -1, -1, 2544, 2545, + 2534, -1, 377, 2537, -1, 2117, -1, -1, -1, -1, + 2556, 2556, 2558, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 2556, 246, -1, -1, -1, -1, -1, 2141, + -1, 254, 2578, -1, 170, -1, -1, -1, 174, -1, + -1, -1, -1, 266, 2156, 2157, 2158, 2159, 2160, 2161, + 2162, 2163, 2164, 2165, 483, -1, -1, -1, -1, -1, + -1, 197, -1, -1, 287, 2611, 526, 496, -1, -1, + -1, -1, -1, -1, 297, -1, -1, -1, -1, -1, + -1, -1, -1, 702, -1, 2621, 377, -1, -1, -1, + -1, 2466, -1, -1, -1, -1, 2642, 2642, 234, 702, + 2646, 2647, 477, -1, -1, 241, -1, 2643, 2642, 484, + 485, 486, 487, 488, 489, 338, -1, -1, 1138, 342, + -1, 344, -1, -1, 2670, 2687, 1146, -1, 2674, 2674, + -1, -1, 2678, -1, -1, 2681, 1156, 526, -1, -1, + 2674, 2687, -1, 366, -1, -1, -1, -1, -1, 372, + -1, 580, 288, -1, 2529, -1, 2702, -1, -1, 2534, + -1, -1, 2537, 386, -1, -1, 2712, -1, -1, 1189, + 2716, 2717, 480, 481, 482, -1, 484, 485, 486, 487, + 488, 489, 8, 612, -1, 11, 477, -1, -1, 808, + 16, 17, 18, 484, 485, 486, 487, 488, 489, 1271, + 1220, 1221, -1, 1223, 1224, 808, 1226, 1227, -1, 1229, + 1895, 2747, -1, -1, -1, -1, 439, -1, -1, 648, + 649, 650, 358, -1, -1, 2771, -1, -1, 2774, 2774, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 2774, -1, 702, -1, -1, -1, 2621, -1, -1, 2795, + -1, 2797, -1, 2799, -1, -1, 1276, 2803, -1, -1, + -1, -1, -1, -1, 2810, 2810, -1, 1287, 2643, 405, + 2806, 407, -1, -1, -1, -1, 2810, 1962, -1, -1, + -1, -1, -1, -1, -1, 2831, -1, 423, -1, -1, + -1, 1363, -1, 429, -1, 1980, 432, 1317, -1, 2674, + -1, -1, -1, -1, -1, 2851, 2852, -1, -1, -1, + -1, -1, 2687, 702, -1, -1, -1, -1, -1, 2865, + 2005, -1, -1, -1, -1, -1, -1, 2012, -1, -1, + 1350, 1351, -1, -1, -1, -1, -1, -1, -1, 2885, + 2886, -1, -1, -1, -1, -1, -1, -1, 808, 0, + 2035, -1, 1372, -1, 1374, -1, 2902, 2902, 2904, 2895, + -1, -1, -1, 1383, -1, 1385, 985, -1, 2902, 36, + -1, -1, 2747, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 985, -1, -1, -1, -1, -1, 55, -1, + 216, -1, -1, -1, -1, -1, -1, 109, 110, -1, + -1, 1421, -1, -1, -1, -1, -1, -1, -1, -1, + 1430, 1431, -1, -1, -1, -1, -1, -1, -1, 808, + -1, 1441, 1442, 1443, 1444, 2971, 1446, -1, -1, -1, + -1, 2806, 1452, -1, 1454, -1, -1, -1, -1, 106, + 107, -1, 93, -1, -1, 1465, 1466, -1, 115, -1, + 1470, 1471, -1, -1, -1, 1475, 1476, 1477, 1478, 285, + 1480, 1481, -1, 0, -1, 2577, -1, -1, -1, 2154, + -1, -1, 184, 185, -1, -1, -1, -1, -1, -1, + 1500, 1501, 1502, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 921, -1, 145, -1, -1, 1517, 1570, -1, + 2612, 2613, 1574, -1, -1, 172, -1, 158, -1, -1, + -1, 1583, 163, -1, -1, 2627, 945, 168, -1, -1, + 2895, -1, -1, -1, -1, 985, 177, -1, 2213, 196, + 181, -1, -1, -1, -1, -1, 248, 249, 250, 251, + 252, 253, 971, -1, 256, 257, -1, -1, -1, -1, + -1, -1, -1, 1172, 1173, 984, 93, -1, -1, -1, + -1, 212, -1, -1, -1, -1, -1, -1, 1187, 1172, + 1173, -1, -1, -1, -1, -1, 1005, -1, -1, 246, + 231, -1, -1, -1, 1187, -1, -1, 254, -1, 2701, + -1, -1, -1, -1, -1, -1, 985, 2282, -1, 266, + 526, 268, -1, -1, -1, -1, -1, -1, 145, -1, + -1, -1, -1, -1, -1, -1, -1, 2729, -1, -1, + -1, 158, -1, -1, -1, -1, 163, -1, -1, 280, + 297, 168, 283, -1, -1, 1655, -1, -1, 289, -1, + 177, -1, 1662, -1, 181, -1, -1, -1, -1, -1, + 362, 363, -1, -1, 480, 481, 482, 526, 484, 485, + 486, 487, 488, 489, -1, -1, -1, -1, -1, -1, + -1, -1, 323, -1, -1, 212, 1696, 344, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1309, -1, -1, -1, 231, 346, -1, -1, -1, 366, + -1, -1, -1, -1, -1, -1, 1309, 2392, -1, 1729, + -1, -1, 1172, 1173, -1, -1, 1736, 1146, -1, 386, + -1, 388, -1, -1, 391, -1, -1, 1187, -1, -1, + -1, 1751, 0, -1, -1, 1755, -1, 2422, 1758, 8, + 1760, -1, 11, 280, -1, -1, 283, 16, 17, 18, + 401, -1, 289, -1, 1826, -1, -1, 8, -1, -1, + 11, 473, 474, -1, 33, 16, 17, 18, -1, -1, + -1, -1, -1, -1, -1, -1, 702, 428, -1, -1, + -1, 493, 33, 1172, 1173, 436, 323, -1, -1, -1, + -1, 1811, -1, -1, -1, -1, -1, -1, 1187, 1871, + 1229, 452, -1, 454, 455, -1, -1, 2492, -1, 346, + -1, -1, 1884, -1, -1, -1, -1, -1, -1, -1, + 1439, -1, -1, -1, -1, 93, 493, -1, -1, -1, + -1, -1, -1, 702, -1, -1, 1439, -1, -1, -1, + 491, -1, -1, 494, 495, 496, -1, -1, -1, 1309, + -1, -1, -1, 1873, -1, -1, -1, -1, 1878, -1, + -1, -1, -1, -1, 401, 1885, 1886, 1887, 1888, 1941, + 8, -1, -1, 11, 1946, -1, 1948, 145, -1, 1899, + 1952, 1953, 808, -1, -1, -1, 1906, -1, -1, -1, + 158, 428, -1, -1, -1, 163, -1, -1, 1918, 436, + 168, -1, -1, 41, -1, -1, -1, -1, -1, 177, + 48, -1, -1, 181, 1934, 452, -1, 454, 455, -1, + 1309, 1350, -1, -1, 1543, -1, 2611, -1, -1, -1, + 1950, 1951, -1, -1, -1, 73, -1, -1, -1, 808, + 1543, -1, -1, 1372, 212, 1374, -1, 216, -1, -1, + -1, -1, -1, 1973, 491, -1, -1, 494, 495, 496, + -1, -1, 2647, 231, -1, 216, -1, -1, 1587, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 1439, + -1, -1, -1, -1, 1587, -1, -1, -1, -1, -1, + -1, -1, 1421, 2678, -1, -1, 2681, -1, -1, -1, + -1, -1, -1, -1, -1, 143, -1, -1, -1, 109, + 110, -1, 280, -1, -1, 283, 285, -1, -1, -1, + -1, 289, -1, -1, -1, -1, -1, -1, -1, 2049, + -1, -1, -1, -1, 285, 173, -1, 2057, 2058, 2059, + 2060, -1, 2062, 2063, -1, -1, -1, 2067, 2068, -1, + 1439, 189, -1, -1, -1, 323, 194, -1, -1, 985, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1500, 1501, -1, -1, -1, -1, 2097, 346, -1, + -1, -1, 2154, 1543, 184, 185, -1, -1, -1, -1, + -1, -1, 230, -1, -1, 2115, -1, 2117, -1, -1, + -1, 2121, 2122, 2123, -1, 2125, -1, 2179, -1, -1, + -1, -1, -1, -1, -1, -1, 985, -1, -1, -1, + -1, 2141, -1, 2143, -1, -1, -1, 1587, -1, -1, + -1, -1, -1, 401, -1, -1, 2156, 2157, 2158, 2159, + 2160, 2161, 2162, 2163, 2164, 2165, -1, 285, 248, 249, + 250, 251, 252, 253, 1543, -1, 256, 257, -1, -1, + 428, 2181, -1, -1, 2184, -1, -1, -1, 436, -1, + -1, -1, -1, -1, 2194, -1, -1, -1, -1, 564, + 565, -1, -1, -1, 452, 2205, 454, 455, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 2217, 1587, -1, + -1, 2886, -1, -1, 2224, -1, -1, -1, -1, -1, + -1, 480, 481, 482, -1, 484, 485, 486, 487, 488, + 489, -1, -1, 491, -1, -1, 494, 495, 496, 480, + 481, 482, -1, 484, 485, 486, 487, 488, 489, 377, + -1, -1, 627, 628, -1, -1, 1172, 1173, -1, -1, + -1, -1, 2272, -1, -1, -1, -1, -1, -1, -1, + -1, 1187, 362, 363, -1, -1, 2338, -1, -1, 8, + -1, -1, 11, -1, -1, 2295, 1895, -1, 2298, 2299, + 2300, 2301, -1, -1, -1, 2305, 2306, -1, 2308, -1, + -1, 2311, 1895, -1, -1, 2315, -1, -1, -1, 2319, + 1729, -1, 41, 1172, 1173, 2325, -1, -1, -1, 48, + -1, -1, -1, -1, -1, -1, -1, -1, 1187, -1, + -1, 2341, -1, -1, -1, 2345, -1, -1, -1, -1, + 2350, -1, -1, -1, 73, -1, 2356, -1, -1, 477, + -1, -1, 2362, 1962, -1, -1, 484, 485, 486, 487, + 488, 489, -1, -1, -1, -1, -1, -1, -1, 1962, + -1, 1980, -1, 8, -1, -1, 11, 2387, -1, -1, + -1, -1, -1, 473, 474, -1, -1, 1980, -1, -1, + -1, -1, -1, 1309, -1, -1, 2005, -1, -1, -1, + 2462, -1, -1, 2012, -1, -1, 41, -1, -1, -1, + -1, -1, 2005, 48, 143, -1, -1, -1, -1, 2012, + -1, 2483, -1, -1, -1, -1, 2035, -1, -1, -1, + -1, -1, 807, -1, -1, -1, -1, -1, 73, -1, + -1, -1, 2035, -1, 173, 1895, 2456, -1, -1, 824, + 1309, -1, -1, -1, -1, 2465, -1, -1, -1, 1878, + 189, -1, -1, -1, -1, 194, 2476, 1886, 1887, 1888, + -1, -1, -1, -1, -1, -1, -1, -1, 853, -1, + -1, -1, -1, -1, -1, 2547, -1, 1906, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 873, 874, + 875, 230, -1, 878, -1, -1, -1, -1, 143, -1, + 2520, 2521, 1962, -1, 2524, -1, 1895, 2527, -1, 2529, + -1, -1, -1, 1439, 2534, -1, 901, 2537, -1, 2539, + 1980, -1, 2542, -1, -1, -1, -1, -1, 173, -1, + -1, -1, -1, -1, -1, 2154, 2556, -1, -1, 2611, + -1, -1, -1, -1, 189, 2005, 285, -1, -1, 194, + -1, 2154, 2012, -1, -1, -1, 2576, 2577, -1, -1, + -1, -1, -1, -1, -1, 2585, -1, 952, -1, -1, + 1439, 956, 957, 1962, -1, 2035, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 230, -1, -1, -1, -1, + -1, 1980, 2612, 2613, 2213, -1, -1, -1, -1, -1, + -1, -1, -1, 2623, -1, -1, -1, 2627, -1, -1, + 2213, -1, -1, -1, -1, -1, 2005, 1543, -1, 2639, + -1, -1, 2642, 2012, -1, 1010, -1, -1, 2057, 2058, + 2059, -1, 1017, -1, -1, -1, -1, -1, 377, -1, + 285, 2661, -1, -1, -1, 8, 2035, -1, 11, -1, + -1, -1, -1, 1038, 2674, -1, -1, -1, -1, 2679, + -1, 1587, -1, 2282, -1, -1, -1, -1, -1, -1, + 2742, -1, -1, -1, 1543, -1, 2696, -1, 41, 2282, + -1, 2701, -1, -1, -1, 48, 2115, -1, -1, -1, + 2710, -1, -1, -1, 2154, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 2729, + 73, -1, 8, 2733, -1, 11, -1, -1, 1587, -1, + 16, 17, 18, -1, -1, -1, 2746, -1, -1, -1, + -1, -1, 377, -1, -1, -1, -1, 33, 477, -1, + -1, -1, -1, -1, -1, 484, 485, 486, 487, 488, + 489, -1, -1, 2213, 2774, 2184, -1, -1, -1, -1, + -1, -1, -1, 2783, -1, 2154, -1, 2787, 1153, -1, + -1, 2791, -1, 2392, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 799, 2217, 2392, + 2810, 2811, 2812, 2813, 806, -1, -1, -1, -1, -1, + -1, -1, -1, 2422, -1, -1, -1, -1, -1, -1, + 173, -1, -1, -1, 2886, -1, -1, -1, -1, 2422, + -1, -1, 2282, 3, 2213, 5, 189, -1, -1, -1, + -1, 194, 477, -1, -1, -1, 2856, -1, -1, 484, + 485, 486, 487, 488, 489, -1, -1, -1, 2868, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 2882, -1, -1, -1, -1, 230, -1, 2298, + 2299, 2300, 2301, 2492, -1, -1, 2896, -1, -1, -1, + 1265, 893, 2902, -1, -1, -1, -1, -1, -1, 2492, + 1275, -1, 1277, 2282, -1, 1280, 1281, 1282, 1283, -1, + -1, -1, 2922, 2923, -1, 917, -1, 919, 920, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 1304, + 216, -1, 285, -1, -1, 1310, 1311, 1312, 1313, 109, + 110, -1, 2392, 1318, 1319, -1, -1, -1, 1323, -1, + -1, -1, 1327, -1, -1, 1330, 1331, 1332, 1333, 1334, + 1335, 1336, 1337, 1338, -1, -1, 1341, -1, -1, -1, + -1, 1346, 2422, -1, 1349, -1, 1351, -1, 1353, 1895, + -1, -1, -1, -1, 986, -1, -1, 989, 990, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 285, + -1, 1376, 2611, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 2392, 184, 185, -1, -1, 2611, -1, + -1, -1, -1, -1, 377, -1, -1, -1, -1, -1, + -1, -1, 1407, 1408, -1, -1, 1895, -1, 2647, -1, + -1, -1, 2492, 2422, -1, -1, 1962, -1, -1, -1, + -1, -1, -1, -1, 2647, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 1980, -1, -1, -1, -1, 2678, + -1, -1, 2681, -1, -1, -1, -1, -1, 248, 249, + 250, 251, 252, 253, -1, 2678, 256, 257, 2681, 2005, + -1, -1, -1, -1, -1, -1, 2012, -1, -1, -1, + -1, -1, -1, 1962, -1, -1, -1, -1, -1, -1, + -1, 1486, -1, 2492, 1489, 1490, -1, 1492, -1, 2035, + -1, 1980, -1, -1, 477, -1, -1, -1, -1, -1, + -1, 484, 485, 486, 487, 488, 489, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 2005, -1, 1523, -1, + -1, -1, -1, 2012, -1, -1, -1, -1, -1, -1, + -1, 2611, -1, -1, -1, -1, 2585, -1, 1170, -1, + -1, -1, -1, -1, -1, -1, 2035, -1, -1, 1181, + -1, 1183, -1, -1, -1, -1, -1, -1, -1, -1, + 1192, -1, 362, 363, 480, 481, 482, 2647, 484, 485, + 486, 487, 488, 489, -1, -1, -1, 1209, -1, -1, + 1585, -1, -1, -1, -1, -1, -1, 1592, -1, -1, + 2639, -1, 1597, -1, -1, -1, -1, -1, 2678, -1, + -1, 2681, 2611, -1, 1236, 1237, -1, -1, 2154, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1635, -1, -1, -1, -1, -1, 1268, 1269, 2647, -1, + 1272, 1273, 1647, -1, 1649, 1650, -1, 2886, -1, -1, + -1, -1, 1657, -1, -1, -1, 1661, -1, -1, 1664, + 0, 2710, -1, 2886, -1, 2154, -1, 2213, -1, 2678, + -1, -1, 2681, 473, 474, -1, -1, -1, -1, 19, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 29, + -1, 31, 32, 1698, -1, -1, 1701, 2746, 1703, -1, + -1, -1, -1, -1, -1, -1, -1, 47, -1, -1, + -1, -1, -1, -1, -1, -1, 56, -1, -1, -1, + -1, -1, -1, -1, 2213, -1, -1, -1, 68, -1, + -1, -1, -1, -1, -1, -1, 2282, -1, -1, 79, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 91, -1, 93, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 1769, -1, -1, -1, -1, -1, + -1, 111, -1, -1, -1, 1407, 1408, -1, -1, 1784, + 1785, -1, -1, -1, -1, 125, -1, -1, -1, -1, + -1, -1, 894, 2282, -1, 135, -1, -1, 1803, -1, + -1, 141, -1, -1, -1, -1, 2886, -1, -1, 149, + -1, 151, 152, -1, -1, -1, -1, -1, 21, -1, + -1, -1, -1, -1, 164, -1, -1, 1459, -1, -1, + -1, -1, 934, -1, -1, -1, -1, 1469, -1, -1, + 1472, 8, -1, -1, 11, -1, 2392, -1, -1, 16, + 17, 18, -1, 193, -1, -1, 1861, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 208, -1, + -1, 74, -1, -1, 41, -1, 2422, 2886, -1, -1, + -1, 48, -1, -1, -1, -1, -1, 90, -1, -1, + -1, 8, -1, 233, 11, -1, -1, -1, -1, 16, + 17, 18, -1, 2392, -1, -1, 73, -1, -1, -1, + -1, -1, 1544, 1545, -1, -1, 33, -1, -1, -1, + -1, -1, -1, -1, 41, -1, -1, -1, -1, -1, + -1, 48, -1, 2422, -1, -1, -1, -1, 1570, -1, + 1042, 144, -1, -1, -1, -1, 2492, 1049, -1, -1, + 153, 1583, -1, -1, 1959, -1, 73, -1, -1, -1, + -1, -1, 165, 1968, -1, -1, 1971, 170, -1, 1974, + 310, -1, -1, 313, 3, -1, -1, -1, -1, 8, + -1, -1, 11, -1, -1, -1, -1, 16, 17, 18, + -1, -1, -1, -1, 197, 2000, 2001, -1, -1, -1, + -1, -1, 342, 2492, 33, -1, 173, 36, -1, 2014, + -1, 351, 41, -1, -1, -1, -1, -1, 2023, 48, + -1, 2026, 189, 2028, -1, 365, -1, 194, -1, -1, + -1, 2036, 372, -1, -1, -1, 376, -1, 241, 2044, + 2045, -1, 245, -1, 73, -1, 386, -1, -1, 216, + 217, -1, -1, -1, -1, -1, 173, 397, -1, -1, + -1, 401, -1, 230, -1, 2611, -1, -1, 2073, -1, + -1, -1, 189, -1, -1, -1, -1, 194, 2083, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 2099, -1, -1, 437, -1, 216, + 217, 2647, 442, -1, 271, 308, -1, -1, -1, 1741, + -1, -1, -1, 230, -1, 455, -1, -1, 285, 322, + -1, -1, 2611, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 2678, -1, -1, 2681, -1, -1, -1, 479, + -1, -1, 1774, 1775, 173, -1, -1, -1, -1, -1, + -1, 268, 355, 493, 271, 358, 496, -1, 2647, -1, + 189, 1263, -1, 366, -1, 194, 369, -1, 285, -1, + -1, 288, 1274, -1, -1, -1, 1278, -1, -1, -1, + -1, -1, 1284, 1285, 1286, 388, -1, 216, 217, 2678, + -1, 1293, 2681, -1, -1, -1, -1, -1, 401, -1, + -1, 230, -1, -1, -1, 408, -1, -1, -1, -1, + 377, -1, -1, -1, 417, -1, -1, -1, -1, -1, + 423, -1, -1, -1, -1, 2230, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 268, + -1, -1, 271, -1, -1, 448, 1348, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 285, -1, 8, 288, + 377, 11, -1, -1, -1, -1, 16, 17, 18, -1, + -1, 2276, 2277, -1, -1, -1, 2281, -1, -1, -1, + 1912, 2286, -1, 33, 2289, 2290, 36, -1, -1, 2294, + 1392, 41, -1, -1, -1, -1, -1, -1, 48, -1, + -1, -1, -1, -1, 1406, -1, -1, -1, -1, 1411, + 477, -1, -1, 480, 481, 482, -1, 484, 485, 486, + 487, 488, 489, 73, 23, -1, -1, -1, -1, -1, + 29, -1, -1, -1, -1, -1, 2341, 36, -1, -1, + 2886, -1, -1, -1, -1, -1, -1, -1, 377, -1, + -1, -1, -1, -1, -1, -1, 55, -1, -1, -1, + 477, -1, -1, 480, 481, 482, -1, 484, 485, 486, + 487, 488, 489, -1, -1, -1, -1, -1, 2383, -1, + 497, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 2886, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 106, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 173, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 135, -1, -1, 189, + -1, -1, -1, -1, 194, -1, -1, -1, 477, -1, + -1, 480, 481, 482, -1, 484, 485, 486, 487, 488, + 489, -1, -1, -1, -1, -1, 216, 217, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 230, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 2496, -1, 1595, -1, -1, -1, 196, -1, 2504, + 2505, -1, -1, 2508, -1, -1, -1, -1, -1, -1, + -1, -1, 1614, -1, -1, -1, -1, -1, 268, -1, + -1, 271, 2154, -1, -1, -1, -1, -1, -1, 1631, + -1, 1633, 1634, -1, 1636, 285, 1638, -1, 288, 2544, + 2545, 1643, -1, -1, 1646, -1, -1, 246, -1, 1651, + -1, -1, 1654, 2558, -1, 254, -1, -1, -1, -1, + -1, -1, -1, -1, 1666, -1, -1, 266, 1670, 1671, + 1672, 1673, -1, -1, -1, -1, -1, 1679, 1680, -1, + 1682, 1683, -1, -1, -1, -1, -1, -1, 287, -1, + -1, -1, 1694, -1, -1, 1697, -1, -1, 297, -1, + -1, -1, -1, 1705, 1706, 1707, 1708, 1709, 1710, 1711, + 1712, 1713, 1714, -1, -1, -1, -1, -1, -1, -1, + 1722, -1, -1, -1, 1726, -1, -1, 377, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 338, + -1, -1, -1, 342, 8, 344, 1748, 11, -1, -1, + -1, -1, 16, 17, 18, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 2670, -1, 366, -1, 33, + -1, -1, -1, 372, -1, -1, -1, 41, -1, -1, + -1, -1, 2687, -1, 48, -1, -1, 386, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 2702, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 73, + -1, -1, 2717, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 477, -1, -1, + 480, 481, 482, -1, 484, 485, 486, 487, 488, 489, + 439, -1, -1, -1, 494, -1, -1, -1, -1, 2381, + -1, -1, -1, -1, 2386, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 1866, 1867, 1868, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 2799, -1, 2428, 2429, 2803, -1, + -1, -1, 1904, -1, -1, -1, -1, -1, -1, 173, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 189, 2831, -1, -1, -1, + 194, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 2851, 2852, -1, -1, + -1, -1, 216, 217, -1, -1, 1958, -1, -1, -1, + 2865, -1, 1964, -1, -1, -1, 230, -1, -1, -1, + -1, -1, -1, -1, -1, 1977, 1978, 1979, -1, 1981, + 1982, 1983, 1984, -1, -1, 1987, 1988, 1989, 1990, 1991, + 1992, 1993, 1994, 1995, 1996, 1997, -1, -1, -1, 2904, + -1, -1, -1, -1, 268, -1, -1, 271, -1, -1, + -1, -1, -1, 2015, -1, -1, 2018, -1, 2020, -1, + -1, 285, 2024, 2025, 288, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 2038, 2039, 2040, 2041, + -1, 2043, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 2971, -1, 2600, 2601, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 2611, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8, -1, -1, 11, -1, -1, -1, + -1, 16, 17, 18, -1, -1, -1, -1, -1, -1, + -1, -1, 8, 377, -1, 11, 2118, -1, 33, -1, + 16, 17, 18, -1, -1, -1, 41, -1, -1, -1, + -1, -1, -1, 48, -1, -1, -1, 33, 8, -1, + -1, 11, -1, -1, -1, 41, 16, 17, 18, -1, + -1, -1, 48, -1, -1, -1, -1, -1, 73, -1, + -1, -1, -1, 33, -1, -1, -1, -1, -1, -1, + -1, 41, -1, -1, -1, -1, -1, 73, 48, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 73, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 477, -1, -1, 480, 481, 482, -1, + 484, 485, 486, 487, 488, 489, -1, -1, -1, 2231, + 494, -1, -1, 2235, 2236, 8, 2238, -1, 11, 2241, + 2242, 2243, 2244, 16, 17, 18, 2248, 2249, 2250, 2251, + 2252, 2253, 2254, 2255, 2256, 2257, 2258, 2259, 173, -1, + -1, -1, -1, -1, -1, -1, -1, 2269, 41, -1, + -1, -1, -1, 2275, 189, 48, 2278, 173, 2280, 194, + -1, -1, 2284, -1, -1, 2287, 2288, -1, -1, 2291, + 2292, -1, -1, 189, -1, -1, -1, -1, 194, -1, + 73, 216, 217, 173, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 230, -1, -1, -1, 189, + 216, 217, -1, -1, 194, -1, -1, -1, -1, -1, + 2332, -1, -1, -1, 230, -1, -1, -1, 2340, -1, + -1, -1, -1, -1, -1, -1, 216, 217, -1, -1, + -1, 2353, -1, 268, 2886, -1, 271, -1, -1, -1, + 230, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 285, -1, 268, 288, -1, 271, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 285, + -1, -1, 288, -1, -1, -1, -1, -1, 268, -1, + 173, 271, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 285, 189, -1, 288, -1, + -1, 194, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 230, -1, -1, + -1, -1, 377, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 377, -1, 2485, -1, -1, -1, 2489, -1, -1, + -1, -1, -1, -1, -1, -1, 2498, 2499, 2500, -1, + -1, 2503, -1, -1, 2506, 2507, -1, 377, -1, 2511, + -1, -1, 285, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 477, -1, -1, 480, 481, 482, -1, 484, + 485, 486, 487, 488, 489, -1, 2578, -1, -1, 494, + -1, 477, -1, -1, 480, 481, 482, -1, 484, 485, + 486, 487, 488, 489, -1, 2597, -1, -1, 494, -1, + -1, -1, -1, -1, 377, -1, -1, 477, -1, -1, + 480, 481, 482, -1, 484, 485, 486, 487, 488, 489, + -1, -1, -1, -1, 494, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 2645, 2646, -1, -1, -1, -1, 2651, + 2652, 2653, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 2694, 2695, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 477, -1, 2708, 480, 481, 482, + -1, 484, 485, 486, 487, 488, 489, -1, 2720, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 2768, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 2786, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 2808, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 2822, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 2870, -1, + -1, -1, -1, -1, -1, -1, 3, 4, 5, 6, + 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, + -1, 2893, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, -1, 2907, -1, -1, 35, -1, + -1, 38, 39, -1, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, -1, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + -1, 68, 69, 70, 71, 72, -1, 74, -1, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, -1, + 87, 88, 89, 90, 91, 92, -1, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + -1, 118, 119, 120, 121, 122, 123, -1, 125, 126, + 127, 128, 129, 130, -1, 132, 133, 134, 135, 136, + -1, 138, 139, 140, -1, 142, 143, 144, -1, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, -1, 159, 160, 161, 162, -1, 164, -1, 166, + 167, -1, 169, 170, 171, 172, 173, 174, -1, 176, + -1, 178, 179, 180, -1, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, -1, 195, 196, + 197, 198, 199, 200, -1, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, -1, 213, -1, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, -1, -1, + 227, 228, 229, 230, -1, 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, -1, 281, 282, -1, -1, 285, 286, + 287, -1, -1, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, -1, + 307, 308, 309, 310, 311, 312, 313, 314, 315, -1, + 317, 318, 319, 320, 321, 322, -1, 324, 325, 326, + 327, 328, 329, 330, 331, -1, 333, 334, 335, 336, + 337, 338, 339, 340, 341, 342, 343, 344, 345, -1, + 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, -1, 366, + 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, + 377, 378, 379, 380, 381, -1, 383, 384, 385, 386, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, -1, 399, 400, -1, 402, 403, 404, 405, 406, + 407, 408, -1, 410, 411, -1, -1, 414, 415, 416, + 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, + 427, -1, -1, 430, 431, 432, 433, 434, 435, -1, + 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, + 447, 448, 449, 450, -1, -1, 453, -1, -1, 456, + 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, + 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, + 477, -1, -1, -1, -1, -1, -1, 484, 485, 486, + -1, -1, -1, -1, 491, -1, 493, 494, -1, -1, + -1, 498, -1, 500, 501, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, -1, -1, -1, -1, 35, -1, -1, @@ -225408,40 +240521,240 @@ static const yytype_int16 yycheck[] = -1, 159, 160, 161, 162, -1, 164, -1, 166, 167, -1, 169, 170, 171, 172, 173, 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, -1, 194, 195, 196, 197, - 198, 199, -1, 201, 202, 203, 204, 205, 206, 207, - 208, 209, -1, 211, -1, 213, 214, 215, 216, 217, - 218, 219, 220, 221, 222, -1, -1, 225, 226, 227, - 228, -1, 230, 231, 232, 233, 234, 235, 236, 237, + 188, 189, 190, 191, 192, 193, -1, 195, 196, 197, + 198, 199, 200, -1, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, -1, 213, -1, 215, 216, 217, + 218, 219, 220, 221, 222, 223, 224, -1, -1, 227, + 228, 229, 230, -1, 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, -1, -1, 283, 284, 285, -1, -1, - 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, - 298, 299, 300, 301, 302, 303, -1, 305, 306, 307, - 308, 309, 310, 311, 312, 313, -1, 315, 316, 317, - 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, - 328, -1, 330, 331, 332, 333, 334, 335, 336, 337, - 338, 339, 340, 341, -1, 343, 344, 345, 346, 347, + 278, 279, -1, 281, 282, -1, -1, 285, 286, 287, + -1, -1, 290, 291, 292, 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, -1, 307, + 308, 309, 310, 311, 312, 313, 314, 315, -1, 317, + 318, 319, 320, 321, 322, -1, 324, 325, 326, 327, + 328, 329, 330, 331, -1, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 343, 344, 345, -1, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, - 358, 359, 360, -1, 362, 363, 364, 365, 366, 367, + 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, - -1, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 388, 389, 390, 391, 392, 393, -1, 395, 396, -1, - 398, 399, 400, 401, 402, 403, 404, -1, 406, 407, - -1, -1, 410, 411, 412, 413, 414, 415, 416, 417, - 418, 419, 420, 421, 422, 423, -1, -1, 426, 427, - 428, 429, 430, 431, -1, 433, 434, 435, 436, 437, - 438, 439, -1, 441, 442, 443, 444, 445, 446, -1, - -1, 449, -1, -1, 452, 453, 454, 455, 456, 457, + 378, 379, 380, 381, -1, 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + -1, 399, 400, 401, 402, 403, 404, 405, 406, 407, + 408, -1, 410, 411, -1, -1, 414, 415, 416, 417, + 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, + -1, -1, 430, 431, 432, 433, 434, 435, -1, 437, + 438, 439, 440, 441, 442, 443, -1, 445, 446, 447, + 448, 449, 450, -1, -1, 453, -1, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 471, 472, 473, -1, -1, -1, -1, - -1, -1, 480, 481, -1, -1, -1, -1, -1, 487, - -1, 489, -1, -1, -1, -1, 494, -1, 496, 497, + 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, + -1, 479, -1, -1, -1, -1, 484, 485, -1, -1, + -1, -1, -1, 491, -1, 493, 494, -1, -1, -1, + 498, -1, 500, 501, 3, 4, 5, 6, 7, 8, + 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, + 19, 20, 21, 22, 23, 24, 25, 26, -1, 28, + 29, 30, -1, -1, -1, -1, 35, -1, -1, 38, + 39, -1, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, -1, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, -1, 68, + 69, 70, 71, 72, -1, 74, -1, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, -1, 87, 88, + 89, 90, 91, 92, -1, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, -1, 118, + 119, 120, 121, 122, 123, -1, 125, 126, 127, 128, + 129, -1, -1, 132, 133, 134, 135, 136, -1, 138, + 139, 140, -1, 142, 143, 144, -1, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, -1, + 159, 160, 161, 162, -1, 164, -1, 166, 167, -1, + 169, 170, 171, 172, 173, 174, -1, 176, -1, 178, + 179, 180, -1, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, -1, 195, 196, 197, 198, + 199, 200, -1, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, -1, 213, -1, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, -1, -1, 227, 228, + 229, 230, -1, 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, -1, 281, 282, -1, -1, 285, 286, 287, -1, + -1, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, -1, 307, 308, + 309, 310, 311, 312, 313, 314, 315, -1, 317, 318, + 319, 320, 321, 322, -1, 324, 325, 326, 327, 328, + 329, 330, 331, -1, 333, 334, 335, 336, 337, 338, + 339, 340, 341, 342, 343, 344, 345, -1, 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, -1, 383, 384, 385, 386, 387, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, -1, + 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, + -1, 410, 411, -1, -1, 414, 415, 416, 417, 418, + 419, 420, 421, 422, 423, 424, 425, 426, 427, -1, + -1, 430, 431, 432, 433, 434, 435, -1, 437, 438, + 439, 440, 441, 442, 443, -1, 445, 446, 447, 448, + 449, 450, -1, -1, 453, -1, 455, 456, 457, 458, + 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, + 469, 470, 471, 472, 473, 474, 475, 476, 477, -1, + 479, -1, -1, -1, -1, 484, 485, -1, -1, -1, + -1, -1, 491, -1, 493, -1, -1, -1, -1, 498, + -1, 500, 501, 3, 4, 5, 6, 7, 8, 9, + 10, -1, -1, -1, -1, -1, -1, -1, -1, 19, + 20, 21, 22, 23, 24, 25, 26, -1, 28, 29, + 30, -1, -1, -1, -1, 35, -1, -1, 38, 39, + -1, 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, -1, 68, 69, + 70, 71, 72, -1, 74, -1, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, -1, 87, 88, 89, + 90, 91, 92, -1, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, -1, 118, 119, + 120, 121, 122, 123, -1, 125, 126, 127, 128, 129, + -1, -1, 132, 133, 134, 135, 136, -1, 138, 139, + 140, -1, 142, 143, 144, -1, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, -1, 159, + 160, 161, 162, -1, 164, -1, 166, 167, 168, 169, + 170, 171, 172, 173, 174, -1, 176, -1, 178, 179, + 180, -1, 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 192, 193, -1, 195, 196, 197, 198, 199, + 200, -1, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, -1, 213, -1, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, -1, 226, 227, 228, 229, + 230, -1, 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, + -1, 281, 282, -1, -1, 285, 286, 287, -1, -1, + 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, -1, 307, 308, 309, + 310, 311, 312, 313, 314, 315, -1, 317, 318, 319, + 320, 321, 322, -1, 324, 325, 326, 327, 328, 329, + 330, 331, -1, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 343, 344, 345, -1, 347, 348, 349, + 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, + 360, 361, 362, 363, 364, -1, 366, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, + 380, 381, -1, 383, 384, 385, 386, 387, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, -1, 399, + 400, -1, 402, 403, 404, 405, 406, 407, 408, -1, + 410, 411, -1, 413, 414, 415, 416, 417, 418, 419, + 420, 421, 422, 423, 424, 425, 426, 427, -1, -1, + 430, 431, 432, 433, 434, 435, -1, 437, 438, 439, + 440, 441, 442, 443, -1, 445, 446, 447, 448, 449, + 450, -1, -1, 453, -1, -1, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 473, 474, 475, 476, 477, -1, -1, + -1, -1, -1, -1, 484, 485, -1, -1, -1, -1, + -1, 491, -1, 493, -1, -1, -1, -1, 498, -1, + 500, 501, 3, 4, 5, 6, 7, 8, 9, 10, + -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + -1, -1, -1, 34, 35, -1, -1, 38, 39, -1, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, -1, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, -1, 68, 69, 70, + 71, 72, -1, 74, -1, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, -1, 87, 88, 89, 90, + 91, 92, -1, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, -1, 118, 119, 120, + 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, + -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, + -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, -1, 159, 160, + 161, 162, -1, 164, -1, 166, 167, -1, 169, 170, + 171, 172, 173, 174, -1, 176, -1, 178, 179, 180, + -1, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 191, 192, 193, -1, 195, 196, 197, 198, 199, 200, + -1, 202, 203, 204, 205, 206, 207, 208, 209, 210, + 211, -1, 213, -1, 215, 216, 217, 218, 219, 220, + 221, 222, 223, 224, -1, -1, 227, 228, 229, 230, + -1, 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, -1, + 281, 282, -1, -1, 285, 286, 287, -1, -1, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 305, -1, 307, 308, 309, 310, + 311, 312, 313, 314, 315, -1, 317, 318, 319, 320, + 321, 322, -1, 324, 325, 326, 327, 328, 329, 330, + 331, -1, 333, 334, 335, 336, 337, 338, 339, 340, + 341, 342, 343, 344, 345, -1, 347, 348, 349, 350, + 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, + 361, 362, 363, 364, -1, 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, -1, 399, 400, + -1, 402, 403, 404, 405, 406, 407, 408, -1, 410, + 411, -1, -1, 414, 415, 416, 417, 418, 419, 420, + 421, 422, 423, 424, 425, 426, 427, -1, -1, 430, + 431, 432, 433, 434, 435, -1, 437, 438, 439, 440, + 441, 442, 443, -1, 445, 446, 447, 448, 449, 450, + -1, -1, 453, -1, -1, 456, 457, 458, 459, 460, + 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, + 471, 472, 473, 474, 475, 476, 477, -1, -1, -1, + -1, -1, -1, 484, 485, -1, -1, -1, -1, -1, + 491, -1, 493, -1, -1, -1, -1, 498, -1, 500, + 501, 3, 4, 5, 6, 7, 8, 9, 10, -1, + -1, -1, -1, -1, -1, -1, -1, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, -1, + -1, -1, -1, 35, -1, -1, 38, 39, -1, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, -1, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, -1, 68, 69, 70, 71, + 72, -1, 74, -1, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, -1, 87, 88, 89, 90, 91, + 92, -1, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, -1, 118, 119, 120, 121, + 122, 123, -1, 125, 126, 127, 128, 129, -1, -1, + 132, 133, 134, 135, 136, -1, 138, 139, 140, -1, + 142, 143, 144, -1, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, -1, 159, 160, 161, + 162, -1, 164, -1, 166, 167, -1, 169, 170, 171, + 172, 173, 174, -1, 176, -1, 178, 179, 180, -1, + 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, -1, 195, 196, 197, 198, 199, 200, -1, + 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, + -1, 213, -1, 215, 216, 217, 218, 219, 220, 221, + 222, 223, 224, -1, -1, 227, 228, 229, 230, -1, + 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, -1, 281, + 282, -1, -1, 285, 286, 287, -1, -1, 290, 291, + 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, -1, 307, 308, 309, 310, 311, + 312, 313, 314, 315, -1, 317, 318, 319, 320, 321, + 322, -1, 324, 325, 326, 327, 328, 329, 330, 331, + -1, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 343, 344, 345, -1, 347, 348, 349, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, -1, 366, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, + -1, 383, 384, 385, 386, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, -1, 399, 400, -1, + 402, 403, 404, 405, 406, 407, 408, -1, 410, 411, + -1, -1, 414, 415, 416, 417, 418, 419, 420, 421, + 422, 423, 424, 425, 426, 427, -1, -1, 430, 431, + 432, 433, 434, 435, -1, 437, 438, 439, 440, 441, + 442, 443, -1, 445, 446, 447, 448, 449, 450, -1, + -1, 453, -1, -1, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 473, 474, 475, 476, 477, -1, -1, -1, -1, + -1, -1, 484, 485, 486, -1, -1, -1, -1, 491, + -1, 493, -1, -1, -1, -1, 498, -1, 500, 501, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, 21, 22, - 23, 24, 25, 26, -1, 28, 29, 30, -1, -1, + 23, 24, 25, 26, 27, 28, 29, 30, -1, -1, -1, -1, 35, -1, -1, 38, 39, -1, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, -1, 54, 55, 56, 57, 58, 59, 60, 61, 62, @@ -225458,37 +240771,237 @@ static const yytype_int16 yycheck[] = -1, 164, -1, 166, 167, -1, 169, 170, 171, 172, 173, 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - -1, 194, 195, 196, 197, 198, 199, -1, 201, 202, - 203, 204, 205, 206, 207, 208, 209, -1, 211, -1, - 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, - -1, -1, 225, 226, 227, 228, -1, 230, 231, 232, + 193, -1, 195, 196, 197, 198, 199, 200, -1, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 211, -1, + 213, -1, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, -1, -1, 227, 228, 229, 230, -1, 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, -1, -1, - 283, 284, 285, -1, -1, 288, 289, 290, 291, 292, + 273, 274, 275, 276, 277, 278, 279, -1, 281, 282, + -1, -1, 285, 286, 287, -1, -1, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, - 303, -1, 305, 306, 307, 308, 309, 310, 311, 312, - 313, -1, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, -1, 330, 331, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, -1, - 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 360, -1, 362, - 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, -1, 379, 380, 381, 382, + 303, 304, 305, -1, 307, 308, 309, 310, 311, 312, + 313, 314, 315, -1, 317, 318, 319, 320, 321, 322, + -1, 324, 325, 326, 327, 328, 329, 330, 331, -1, + 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, + 343, 344, 345, -1, 347, 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, -1, 366, 367, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, 378, 379, 380, 381, -1, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, - 393, -1, 395, 396, -1, 398, 399, 400, 401, 402, - 403, 404, -1, 406, 407, -1, -1, 410, 411, 412, - 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, - 423, -1, -1, 426, 427, 428, 429, 430, 431, -1, - 433, 434, 435, 436, 437, 438, 439, -1, 441, 442, - 443, 444, 445, 446, -1, -1, 449, -1, -1, 452, - 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, + 393, 394, 395, 396, 397, -1, 399, 400, -1, 402, + 403, 404, 405, 406, 407, 408, -1, 410, 411, -1, + -1, 414, 415, 416, 417, 418, 419, 420, 421, 422, + 423, 424, 425, 426, 427, -1, -1, 430, 431, 432, + 433, 434, 435, -1, 437, 438, 439, 440, 441, 442, + 443, -1, 445, 446, 447, 448, 449, 450, -1, -1, + 453, -1, -1, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, - 473, -1, -1, -1, -1, -1, -1, 480, 481, -1, - -1, -1, -1, -1, 487, -1, 489, -1, -1, -1, - -1, 494, -1, 496, 497, 3, 4, 5, 6, 7, + 473, 474, 475, 476, 477, -1, -1, -1, -1, -1, + -1, 484, 485, 486, -1, -1, -1, -1, 491, -1, + 493, -1, -1, -1, -1, 498, -1, 500, 501, 3, + 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, + -1, -1, -1, -1, -1, 19, 20, 21, 22, 23, + 24, 25, 26, -1, 28, 29, 30, -1, -1, -1, + -1, 35, -1, -1, 38, 39, -1, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, -1, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, -1, 68, 69, 70, 71, 72, -1, + 74, -1, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, -1, 87, 88, 89, 90, 91, 92, -1, + 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, -1, 118, 119, 120, 121, 122, 123, + -1, 125, 126, 127, 128, 129, -1, -1, 132, 133, + 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, + 144, -1, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 157, -1, 159, 160, 161, 162, -1, + 164, -1, 166, 167, -1, 169, 170, 171, 172, 173, + 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, + -1, 195, 196, 197, 198, 199, 200, -1, 202, 203, + 204, 205, 206, 207, 208, 209, 210, 211, -1, 213, + -1, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, -1, -1, 227, 228, 229, 230, -1, 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, -1, 281, 282, -1, + -1, 285, 286, 287, -1, -1, 290, 291, 292, 293, + 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, -1, 307, 308, 309, 310, 311, 312, 313, + 314, 315, -1, 317, 318, 319, 320, 321, 322, -1, + 324, 325, 326, 327, 328, 329, 330, 331, -1, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, + 344, 345, -1, 347, 348, 349, 350, 351, 352, 353, + 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, + 364, -1, 366, 367, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 379, 380, 381, -1, 383, + 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, -1, 399, 400, -1, 402, 403, + 404, 405, 406, 407, 408, -1, 410, 411, -1, -1, + 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, + 424, 425, 426, 427, -1, -1, 430, 431, 432, 433, + 434, 435, -1, 437, 438, 439, 440, 441, 442, 443, + -1, 445, 446, 447, 448, 449, 450, -1, -1, 453, + -1, -1, 456, 457, 458, 459, 460, 461, 462, 463, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, + 474, 475, 476, 477, -1, -1, -1, -1, -1, -1, + 484, 485, 486, -1, -1, -1, -1, 491, -1, 493, + -1, -1, -1, -1, 498, -1, 500, 501, 3, 4, + 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, + -1, -1, -1, -1, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, -1, -1, -1, -1, + 35, -1, -1, 38, 39, -1, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, -1, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, -1, 68, 69, 70, 71, 72, -1, 74, + -1, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, -1, 87, 88, 89, 90, 91, 92, -1, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, -1, 118, 119, 120, 121, 122, 123, -1, + 125, 126, 127, 128, 129, -1, -1, 132, 133, 134, + 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, + -1, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, -1, 159, 160, 161, 162, -1, 164, + -1, 166, 167, -1, 169, 170, 171, 172, 173, 174, + -1, 176, -1, 178, 179, 180, -1, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, -1, + 195, 196, 197, 198, 199, 200, -1, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, -1, 213, -1, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + -1, -1, 227, 228, 229, 230, -1, 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, -1, 281, 282, -1, -1, + 285, 286, 287, -1, -1, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, -1, 307, 308, 309, 310, 311, 312, 313, 314, + 315, -1, 317, 318, 319, 320, 321, 322, -1, 324, + 325, 326, 327, 328, 329, 330, 331, -1, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 345, -1, 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + -1, 366, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 380, 381, -1, 383, 384, + 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, -1, 399, 400, -1, 402, 403, 404, + 405, 406, 407, 408, -1, 410, 411, -1, -1, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 426, 427, -1, -1, 430, 431, 432, 433, 434, + 435, -1, 437, 438, 439, 440, 441, 442, 443, -1, + 445, 446, 447, 448, 449, 450, -1, -1, 453, -1, + -1, 456, 457, 458, 459, 460, 461, 462, 463, 464, + 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, + 475, 476, 477, -1, -1, -1, -1, -1, -1, 484, + 485, -1, -1, -1, -1, -1, 491, -1, 493, -1, + -1, -1, -1, 498, -1, 500, 501, 3, 4, 5, + 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, + -1, -1, -1, 19, 20, 21, 22, 23, 24, 25, + 26, -1, 28, 29, 30, -1, -1, -1, -1, 35, + -1, -1, 38, 39, -1, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, -1, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, -1, 68, 69, 70, 71, 72, -1, 74, -1, + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + -1, 87, 88, 89, 90, 91, 92, -1, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, -1, 118, 119, 120, 121, 122, 123, -1, 125, + 126, 127, 128, 129, -1, -1, 132, 133, 134, 135, + 136, -1, 138, 139, 140, -1, 142, 143, 144, -1, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, + 156, 157, -1, 159, 160, 161, 162, -1, 164, -1, + 166, 167, -1, 169, 170, 171, 172, 173, 174, -1, + 176, -1, 178, 179, 180, -1, 182, 183, 184, 185, + 186, 187, 188, 189, 190, 191, 192, 193, -1, 195, + 196, 197, 198, 199, 200, -1, 202, 203, 204, 205, + 206, 207, 208, 209, 210, 211, -1, 213, -1, 215, + 216, 217, 218, 219, 220, 221, 222, 223, 224, -1, + -1, 227, 228, 229, 230, -1, 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, -1, 281, 282, -1, -1, 285, + 286, 287, -1, -1, 290, 291, 292, 293, 294, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + -1, 307, 308, 309, 310, 311, 312, 313, 314, 315, + -1, 317, 318, 319, 320, 321, 322, -1, 324, 325, + 326, 327, 328, 329, 330, 331, -1, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, + -1, 347, 348, 349, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 361, 362, 363, 364, -1, + 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 379, 380, 381, -1, 383, 384, 385, + 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, -1, 399, 400, -1, 402, 403, 404, 405, + 406, 407, 408, -1, 410, 411, -1, -1, 414, 415, + 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, + 426, 427, -1, -1, 430, 431, 432, 433, 434, 435, + -1, 437, 438, 439, 440, 441, 442, 443, -1, 445, + 446, 447, 448, 449, 450, -1, -1, 453, -1, -1, + 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, + 476, 477, -1, -1, -1, -1, -1, -1, 484, 485, + -1, -1, -1, -1, -1, 491, -1, 493, 494, -1, + -1, -1, 498, -1, 500, 501, 3, 4, 5, 6, + 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, + -1, -1, 19, 20, 21, 22, 23, 24, 25, 26, + -1, 28, 29, 30, -1, -1, -1, -1, 35, -1, + -1, 38, 39, -1, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, -1, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + -1, 68, 69, 70, 71, 72, -1, 74, -1, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, -1, + 87, 88, 89, 90, 91, 92, -1, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + -1, 118, 119, 120, 121, 122, 123, -1, 125, 126, + 127, 128, 129, -1, -1, 132, 133, 134, 135, 136, + -1, 138, 139, 140, -1, 142, 143, 144, -1, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, -1, 159, 160, 161, 162, -1, 164, -1, 166, + 167, -1, 169, 170, 171, 172, 173, 174, -1, 176, + -1, 178, 179, 180, -1, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, -1, 195, 196, + 197, 198, 199, 200, -1, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, -1, 213, -1, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, -1, -1, + 227, 228, 229, 230, -1, 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, -1, 281, 282, -1, -1, 285, 286, + 287, -1, -1, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, -1, + 307, 308, 309, 310, 311, 312, 313, 314, 315, -1, + 317, 318, 319, 320, 321, 322, -1, 324, 325, 326, + 327, 328, 329, 330, 331, -1, 333, 334, 335, 336, + 337, 338, 339, 340, 341, 342, 343, 344, 345, -1, + 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, -1, 366, + 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, + 377, 378, 379, 380, 381, -1, 383, 384, 385, 386, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, -1, 399, 400, -1, 402, 403, 404, 405, 406, + 407, 408, -1, 410, 411, -1, -1, 414, 415, 416, + 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, + 427, -1, -1, 430, 431, 432, 433, 434, 435, -1, + 437, 438, 439, 440, 441, 442, 443, -1, 445, 446, + 447, 448, 449, 450, -1, -1, 453, -1, -1, 456, + 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, + 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, + 477, -1, -1, -1, -1, -1, -1, 484, 485, -1, + -1, -1, -1, -1, 491, -1, 493, 494, -1, -1, + -1, 498, -1, 500, 501, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, -1, -1, -1, -1, 35, -1, -1, @@ -225507,37 +241020,237 @@ static const yytype_int16 yycheck[] = -1, 159, 160, 161, 162, -1, 164, -1, 166, 167, -1, 169, 170, 171, 172, 173, 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, -1, 194, 195, 196, 197, - 198, 199, -1, 201, 202, 203, 204, 205, 206, 207, - 208, 209, -1, 211, -1, 213, 214, 215, 216, 217, - 218, 219, 220, 221, 222, -1, -1, 225, 226, 227, - 228, -1, 230, 231, 232, 233, 234, 235, 236, 237, + 188, 189, 190, 191, 192, 193, -1, 195, 196, 197, + 198, 199, 200, -1, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, -1, 213, -1, 215, 216, 217, + 218, 219, 220, 221, 222, 223, 224, -1, -1, 227, + 228, 229, 230, -1, 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, -1, -1, 283, 284, 285, -1, -1, - 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, - 298, 299, 300, 301, 302, 303, -1, 305, 306, 307, - 308, 309, 310, 311, 312, 313, -1, 315, 316, 317, - 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, - 328, -1, 330, 331, 332, 333, 334, 335, 336, 337, - 338, 339, 340, 341, -1, 343, 344, 345, 346, 347, + 278, 279, -1, 281, 282, -1, -1, 285, 286, 287, + -1, -1, 290, 291, 292, 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, -1, 307, + 308, 309, 310, 311, 312, 313, 314, 315, -1, 317, + 318, 319, 320, 321, 322, -1, 324, 325, 326, 327, + 328, 329, 330, 331, -1, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 343, 344, 345, -1, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, - 358, 359, 360, -1, 362, 363, 364, 365, 366, 367, + 358, 359, 360, 361, 362, 363, 364, -1, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, - -1, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 388, 389, 390, 391, 392, 393, -1, 395, 396, -1, - 398, 399, 400, 401, 402, 403, 404, -1, 406, 407, - -1, -1, 410, 411, 412, 413, 414, 415, 416, 417, - 418, 419, 420, 421, 422, 423, -1, -1, 426, 427, - 428, 429, 430, 431, -1, 433, 434, 435, 436, 437, - 438, 439, -1, 441, 442, 443, 444, 445, 446, -1, - -1, 449, -1, -1, 452, 453, 454, 455, 456, 457, + 378, 379, 380, 381, -1, 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + -1, 399, 400, -1, 402, 403, 404, 405, 406, 407, + 408, -1, 410, 411, -1, -1, 414, 415, 416, 417, + 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, + -1, -1, 430, 431, 432, 433, 434, 435, -1, 437, + 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, + 448, 449, 450, -1, -1, 453, -1, -1, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 471, 472, 473, -1, -1, -1, -1, - -1, -1, 480, 481, -1, -1, -1, -1, -1, 487, - -1, 489, -1, -1, -1, -1, 494, -1, 496, 497, + 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, + -1, -1, -1, -1, -1, -1, 484, 485, -1, -1, + -1, -1, -1, 491, -1, 493, -1, -1, -1, -1, + 498, -1, 500, 501, 3, 4, 5, 6, 7, 8, + 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, + 19, 20, 21, 22, 23, 24, 25, 26, -1, 28, + 29, 30, -1, -1, -1, -1, 35, -1, -1, 38, + 39, -1, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, -1, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, -1, 68, + 69, 70, 71, 72, -1, 74, -1, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, -1, 87, 88, + 89, 90, 91, 92, -1, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, -1, 118, + 119, 120, 121, 122, 123, -1, 125, 126, 127, 128, + 129, -1, -1, 132, 133, 134, 135, 136, -1, 138, + 139, 140, -1, 142, 143, 144, -1, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, -1, + 159, 160, 161, 162, -1, 164, -1, 166, 167, 168, + 169, 170, 171, 172, 173, 174, -1, 176, -1, 178, + 179, 180, -1, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, -1, 195, 196, 197, 198, + 199, 200, -1, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, -1, 213, -1, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, -1, -1, 227, 228, + 229, 230, -1, 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, -1, 281, 282, -1, -1, 285, 286, 287, -1, + -1, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, -1, 307, 308, + 309, 310, 311, 312, 313, 314, 315, -1, 317, 318, + 319, 320, 321, 322, -1, 324, 325, 326, 327, 328, + 329, 330, 331, -1, 333, 334, 335, 336, 337, 338, + 339, 340, 341, 342, 343, 344, 345, -1, 347, 348, + 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, + 359, 360, 361, 362, 363, 364, -1, 366, 367, 368, + 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, + 379, 380, 381, -1, 383, 384, 385, 386, 387, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, -1, + 399, 400, -1, 402, 403, 404, 405, 406, 407, 408, + -1, 410, 411, -1, -1, 414, 415, 416, 417, 418, + 419, 420, 421, 422, 423, 424, 425, 426, 427, -1, + -1, 430, 431, 432, 433, 434, 435, -1, 437, 438, + 439, 440, 441, 442, 443, -1, 445, 446, 447, 448, + 449, 450, -1, -1, 453, -1, -1, 456, 457, 458, + 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, + 469, 470, 471, 472, 473, 474, 475, 476, 477, -1, + -1, -1, -1, -1, -1, 484, 485, -1, -1, -1, + -1, -1, 491, -1, 493, -1, -1, -1, -1, 498, + -1, 500, 501, 3, 4, 5, 6, 7, 8, 9, + 10, -1, -1, -1, -1, -1, -1, -1, -1, 19, + 20, 21, 22, 23, 24, 25, 26, -1, 28, 29, + 30, -1, -1, -1, -1, 35, -1, -1, 38, 39, + -1, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, -1, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, -1, 68, 69, + 70, 71, 72, -1, 74, -1, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, -1, 87, 88, 89, + 90, 91, 92, -1, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, -1, 118, 119, + 120, 121, 122, 123, -1, 125, 126, 127, 128, 129, + -1, -1, 132, 133, 134, 135, 136, -1, 138, 139, + 140, -1, 142, 143, 144, -1, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, -1, 159, + 160, 161, 162, -1, 164, -1, 166, 167, -1, 169, + 170, 171, 172, 173, 174, -1, 176, -1, 178, 179, + 180, -1, 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 192, 193, -1, 195, 196, 197, 198, 199, + 200, -1, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, -1, 213, -1, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, -1, -1, 227, 228, 229, + 230, -1, 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, + -1, 281, 282, -1, -1, 285, 286, 287, -1, -1, + 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, -1, 307, 308, 309, + 310, 311, 312, 313, 314, 315, -1, 317, 318, 319, + 320, 321, 322, -1, 324, 325, 326, 327, 328, 329, + 330, 331, -1, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 343, 344, 345, -1, 347, 348, 349, + 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, + 360, 361, 362, 363, 364, -1, 366, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, + 380, 381, -1, 383, 384, 385, 386, 387, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, -1, 399, + 400, -1, 402, 403, 404, 405, 406, 407, 408, -1, + 410, 411, -1, -1, 414, 415, 416, 417, 418, 419, + 420, 421, 422, 423, 424, 425, 426, 427, -1, -1, + 430, 431, 432, 433, 434, 435, -1, 437, 438, 439, + 440, 441, 442, 443, -1, 445, 446, 447, 448, 449, + 450, -1, -1, 453, -1, -1, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 473, 474, 475, 476, 477, -1, -1, + -1, -1, -1, -1, 484, 485, -1, -1, -1, -1, + -1, 491, -1, 493, -1, -1, -1, -1, 498, -1, + 500, 501, 3, 4, 5, 6, 7, 8, 9, 10, + -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, + 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, + -1, -1, -1, -1, 35, -1, -1, 38, 39, -1, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, -1, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, -1, 68, 69, 70, + 71, 72, -1, 74, -1, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, -1, 87, 88, 89, 90, + 91, 92, -1, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, -1, 118, 119, 120, + 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, + -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, + -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, -1, 159, 160, + 161, 162, -1, 164, -1, 166, 167, -1, 169, 170, + 171, 172, 173, 174, -1, 176, -1, 178, 179, 180, + -1, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 191, 192, 193, -1, 195, 196, 197, 198, 199, 200, + -1, 202, 203, 204, 205, 206, 207, 208, 209, 210, + 211, -1, 213, -1, 215, 216, 217, 218, 219, 220, + 221, 222, 223, 224, -1, -1, 227, 228, 229, 230, + -1, 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, -1, + 281, 282, -1, -1, 285, 286, 287, -1, -1, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 305, -1, 307, 308, 309, 310, + 311, 312, 313, 314, 315, -1, 317, 318, 319, 320, + 321, 322, -1, 324, 325, 326, 327, 328, 329, 330, + 331, -1, 333, 334, 335, 336, 337, 338, 339, 340, + 341, 342, 343, 344, 345, -1, 347, 348, 349, 350, + 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, + 361, 362, 363, 364, -1, 366, 367, 368, 369, 370, + 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, + 381, -1, 383, 384, 385, 386, 387, 388, 389, 390, + 391, 392, 393, 394, 395, 396, 397, -1, 399, 400, + -1, 402, 403, 404, 405, 406, 407, 408, -1, 410, + 411, -1, -1, 414, 415, 416, 417, 418, 419, 420, + 421, 422, 423, 424, 425, 426, 427, -1, -1, 430, + 431, 432, 433, 434, 435, -1, 437, 438, 439, 440, + 441, 442, 443, -1, 445, 446, 447, 448, 449, 450, + -1, -1, 453, -1, -1, 456, 457, 458, 459, 460, + 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, + 471, 472, 473, 474, 475, 476, 477, -1, -1, -1, + -1, -1, -1, 484, 485, -1, -1, -1, -1, -1, + 491, -1, 493, -1, -1, -1, -1, 498, -1, 500, + 501, 3, 4, 5, 6, 7, 8, 9, 10, -1, + -1, -1, -1, -1, -1, -1, -1, 19, 20, 21, + 22, 23, 24, 25, 26, -1, 28, 29, 30, -1, + -1, -1, -1, 35, -1, -1, 38, 39, -1, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, -1, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, -1, 68, 69, 70, 71, + 72, -1, 74, -1, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, -1, 87, 88, 89, 90, 91, + 92, -1, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, -1, 118, 119, 120, 121, + 122, 123, -1, 125, 126, 127, 128, 129, -1, -1, + 132, 133, 134, 135, 136, -1, 138, 139, 140, -1, + 142, 143, 144, -1, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, -1, 159, 160, 161, + 162, -1, 164, -1, 166, 167, -1, 169, 170, 171, + 172, 173, 174, -1, 176, -1, 178, 179, 180, -1, + 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, -1, 195, 196, 197, 198, 199, 200, -1, + 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, + -1, 213, -1, 215, 216, 217, 218, 219, 220, 221, + 222, 223, 224, -1, -1, 227, 228, 229, 230, -1, + 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, -1, 281, + 282, -1, -1, 285, 286, 287, -1, -1, 290, 291, + 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, -1, 307, 308, 309, 310, 311, + 312, 313, 314, 315, -1, 317, 318, 319, 320, 321, + 322, -1, 324, 325, 326, 327, 328, 329, 330, 331, + -1, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 343, 344, 345, -1, 347, 348, 349, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, -1, 366, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, + -1, 383, 384, 385, 386, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, -1, 399, 400, -1, + 402, 403, 404, 405, 406, 407, 408, -1, 410, 411, + -1, -1, 414, 415, 416, 417, 418, 419, 420, 421, + 422, 423, 424, 425, 426, 427, -1, -1, 430, 431, + 432, 433, 434, 435, -1, 437, 438, 439, 440, 441, + 442, 443, -1, 445, 446, 447, 448, 449, 450, -1, + -1, 453, -1, -1, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 473, 474, 475, 476, 477, -1, -1, -1, -1, + -1, -1, 484, 485, -1, -1, -1, -1, -1, 491, + -1, 493, -1, -1, -1, -1, 498, -1, 500, 501, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, -1, -1, @@ -225557,37 +241270,237 @@ static const yytype_int16 yycheck[] = -1, 164, -1, 166, 167, -1, 169, 170, 171, 172, 173, 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - -1, 194, 195, 196, 197, 198, 199, -1, 201, 202, - 203, 204, 205, 206, 207, 208, 209, -1, 211, -1, - 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, - -1, -1, 225, 226, 227, 228, -1, 230, 231, 232, + 193, -1, 195, 196, 197, 198, 199, 200, -1, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 211, -1, + 213, -1, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, -1, -1, 227, 228, 229, 230, -1, 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, -1, -1, - 283, 284, 285, -1, -1, 288, 289, 290, 291, 292, + 273, 274, 275, 276, 277, 278, 279, -1, 281, 282, + -1, -1, 285, 286, 287, -1, -1, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, - 303, -1, 305, 306, 307, 308, 309, 310, 311, 312, - 313, -1, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, -1, 330, 331, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, -1, - 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 360, -1, 362, - 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, -1, 379, 380, 381, 382, + 303, 304, 305, -1, 307, 308, 309, 310, 311, 312, + 313, 314, 315, -1, 317, 318, 319, 320, 321, 322, + -1, 324, 325, 326, 327, 328, 329, 330, 331, -1, + 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, + 343, 344, 345, -1, 347, 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, -1, 366, 367, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, 378, 379, 380, 381, -1, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, - 393, -1, 395, 396, -1, 398, 399, 400, 401, 402, - 403, 404, -1, 406, 407, -1, -1, 410, 411, 412, - 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, - 423, -1, -1, 426, 427, 428, 429, 430, 431, -1, - 433, 434, 435, 436, 437, 438, 439, -1, 441, 442, - 443, 444, 445, 446, -1, -1, 449, -1, -1, 452, - 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, + 393, 394, 395, 396, 397, -1, 399, 400, -1, 402, + 403, 404, 405, 406, 407, 408, -1, 410, 411, -1, + -1, 414, 415, 416, 417, 418, 419, 420, 421, 422, + 423, 424, 425, 426, 427, -1, -1, 430, 431, 432, + 433, 434, 435, -1, 437, 438, 439, 440, 441, 442, + 443, -1, 445, 446, 447, 448, 449, 450, -1, -1, + 453, -1, -1, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, - 473, -1, -1, -1, -1, -1, -1, 480, 481, -1, - -1, -1, -1, -1, 487, -1, 489, -1, -1, -1, - -1, 494, -1, 496, 497, 3, 4, 5, 6, 7, + 473, 474, 475, 476, 477, -1, -1, -1, -1, -1, + -1, 484, 485, -1, -1, -1, -1, -1, 491, -1, + 493, -1, -1, -1, -1, 498, -1, 500, 501, 3, + 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, + -1, -1, -1, -1, -1, 19, 20, 21, 22, 23, + 24, 25, 26, -1, 28, 29, 30, -1, -1, -1, + -1, 35, -1, -1, 38, 39, -1, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, -1, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, -1, 68, 69, 70, 71, 72, -1, + 74, -1, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, -1, 87, 88, 89, 90, 91, 92, -1, + 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, -1, 118, 119, 120, 121, 122, 123, + -1, 125, 126, 127, 128, 129, -1, -1, 132, 133, + 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, + 144, -1, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 157, -1, 159, 160, 161, 162, -1, + 164, -1, 166, 167, -1, 169, 170, 171, 172, 173, + 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, + -1, 195, 196, 197, 198, 199, 200, -1, 202, 203, + 204, 205, 206, 207, 208, 209, 210, 211, -1, 213, + -1, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, -1, -1, 227, 228, 229, 230, -1, 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, -1, 281, 282, -1, + -1, 285, 286, 287, -1, -1, 290, 291, 292, 293, + 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, -1, 307, 308, 309, 310, 311, 312, 313, + 314, 315, -1, 317, 318, 319, 320, 321, 322, -1, + 324, 325, 326, 327, 328, 329, 330, 331, -1, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, + 344, 345, -1, 347, 348, 349, 350, 351, 352, 353, + 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, + 364, -1, 366, 367, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 379, 380, 381, -1, 383, + 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, -1, 399, 400, -1, 402, 403, + 404, 405, 406, 407, 408, -1, 410, 411, -1, -1, + 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, + 424, 425, 426, 427, -1, -1, 430, 431, 432, 433, + 434, 435, -1, 437, 438, 439, 440, 441, 442, 443, + -1, 445, 446, 447, 448, 449, 450, -1, -1, 453, + -1, -1, 456, 457, 458, 459, 460, 461, 462, 463, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, + 474, 475, 476, 477, -1, -1, -1, -1, -1, -1, + 484, 485, -1, -1, -1, -1, -1, 491, -1, 493, + -1, -1, -1, -1, 498, -1, 500, 501, 3, 4, + 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, + -1, -1, -1, -1, 19, 20, 21, 22, 23, 24, + 25, 26, -1, 28, 29, 30, -1, -1, -1, -1, + 35, -1, -1, 38, 39, -1, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, -1, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, -1, 68, 69, 70, 71, 72, -1, 74, + -1, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, -1, 87, 88, 89, 90, 91, 92, -1, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, -1, 118, 119, 120, 121, 122, 123, -1, + 125, 126, 127, 128, 129, -1, -1, 132, 133, 134, + 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, + -1, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, -1, 159, 160, 161, 162, -1, 164, + -1, 166, 167, -1, 169, 170, 171, 172, 173, 174, + -1, 176, -1, 178, 179, 180, -1, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, -1, + 195, 196, 197, 198, 199, 200, -1, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, -1, 213, -1, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + -1, -1, 227, 228, 229, 230, -1, 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, -1, 281, 282, -1, -1, + 285, 286, 287, -1, -1, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, -1, 307, 308, 309, 310, 311, 312, 313, 314, + 315, -1, 317, 318, 319, 320, 321, 322, -1, 324, + 325, 326, 327, 328, 329, 330, 331, -1, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 345, -1, 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + -1, 366, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 380, 381, -1, 383, 384, + 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, -1, 399, 400, -1, 402, 403, 404, + 405, 406, 407, 408, -1, 410, 411, -1, -1, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 426, 427, -1, -1, 430, 431, 432, 433, 434, + 435, -1, 437, 438, 439, 440, 441, 442, 443, -1, + 445, 446, 447, 448, 449, 450, -1, -1, 453, -1, + -1, 456, 457, 458, 459, 460, 461, 462, 463, 464, + 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, + 475, 476, 477, -1, -1, -1, -1, -1, -1, 484, + 485, -1, -1, -1, -1, -1, 491, -1, 493, -1, + -1, -1, -1, 498, -1, 500, 501, 3, 4, 5, + 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, + -1, -1, -1, 19, 20, 21, 22, 23, 24, 25, + 26, -1, 28, 29, 30, -1, -1, -1, -1, 35, + -1, -1, 38, 39, -1, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, -1, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, -1, 68, 69, 70, 71, 72, -1, 74, -1, + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + -1, 87, 88, 89, 90, 91, 92, -1, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, -1, 118, 119, 120, 121, 122, 123, -1, 125, + 126, 127, 128, 129, -1, -1, 132, 133, 134, 135, + 136, -1, 138, 139, 140, -1, 142, 143, 144, -1, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, + 156, 157, -1, 159, 160, 161, 162, -1, 164, -1, + 166, 167, -1, 169, 170, 171, 172, 173, 174, -1, + 176, -1, 178, 179, 180, -1, 182, 183, 184, 185, + 186, 187, 188, 189, 190, 191, 192, 193, -1, 195, + 196, 197, 198, 199, 200, -1, 202, 203, 204, 205, + 206, 207, 208, 209, 210, 211, -1, 213, -1, 215, + 216, 217, 218, 219, 220, 221, 222, 223, 224, -1, + -1, 227, 228, 229, 230, -1, 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, -1, 281, 282, -1, -1, 285, + 286, 287, -1, -1, 290, 291, 292, 293, 294, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + -1, 307, 308, 309, 310, 311, 312, 313, 314, 315, + -1, 317, 318, 319, 320, 321, 322, -1, 324, 325, + 326, 327, 328, 329, 330, 331, -1, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, + -1, 347, 348, 349, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 361, 362, 363, 364, -1, + 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 379, 380, 381, -1, 383, 384, 385, + 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, -1, 399, 400, -1, 402, 403, 404, 405, + 406, 407, 408, -1, 410, 411, -1, -1, 414, 415, + 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, + 426, 427, -1, -1, 430, 431, 432, 433, 434, 435, + -1, 437, 438, 439, 440, 441, 442, 443, -1, 445, + 446, 447, 448, 449, 450, -1, -1, 453, -1, -1, + 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, + 476, 477, -1, -1, -1, -1, -1, -1, 484, 485, + -1, -1, -1, -1, -1, 491, -1, 493, -1, -1, + -1, -1, 498, -1, 500, 501, 3, 4, 5, 6, + 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, + -1, -1, 19, 20, 21, 22, 23, 24, 25, 26, + -1, 28, 29, 30, -1, -1, -1, -1, 35, -1, + -1, 38, 39, -1, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, -1, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + -1, 68, 69, 70, 71, 72, -1, 74, -1, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, -1, + 87, 88, 89, 90, 91, 92, -1, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + -1, 118, 119, 120, 121, 122, 123, -1, 125, 126, + 127, 128, 129, -1, -1, 132, 133, 134, 135, 136, + -1, 138, 139, 140, -1, 142, 143, 144, -1, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, -1, 159, 160, 161, 162, -1, 164, -1, 166, + 167, -1, 169, 170, 171, 172, 173, 174, -1, 176, + -1, 178, 179, 180, -1, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, -1, 195, 196, + 197, 198, 199, 200, -1, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, -1, 213, -1, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, -1, -1, + 227, 228, 229, 230, -1, 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, -1, 281, 282, -1, -1, 285, 286, + 287, -1, -1, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, -1, + 307, 308, 309, 310, 311, 312, 313, 314, 315, -1, + 317, 318, 319, 320, 321, 322, -1, 324, 325, 326, + 327, 328, 329, 330, 331, -1, 333, 334, 335, 336, + 337, 338, 339, 340, 341, 342, 343, 344, 345, -1, + 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, -1, 366, + 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, + 377, 378, 379, 380, 381, -1, 383, 384, 385, 386, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, -1, 399, 400, -1, 402, 403, 404, 405, 406, + 407, 408, -1, 410, 411, -1, -1, 414, 415, 416, + 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, + 427, -1, -1, 430, 431, 432, 433, 434, 435, -1, + 437, 438, 439, 440, 441, 442, 443, -1, 445, 446, + 447, 448, 449, 450, -1, -1, 453, -1, -1, 456, + 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, + 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, + 477, -1, -1, -1, -1, -1, -1, 484, 485, -1, + -1, -1, -1, -1, 491, -1, 493, -1, -1, -1, + -1, 498, -1, 500, 501, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, -1, -1, -1, -1, 35, -1, -1, @@ -225606,141 +241519,288 @@ static const yytype_int16 yycheck[] = -1, 159, 160, 161, 162, -1, 164, -1, 166, 167, -1, 169, 170, 171, 172, 173, 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, -1, 194, 195, 196, 197, - 198, 199, -1, 201, 202, 203, 204, 205, 206, 207, - 208, 209, -1, 211, -1, 213, 214, 215, 216, 217, - 218, 219, 220, 221, 222, -1, -1, 225, 226, 227, - 228, -1, 230, 231, 232, 233, 234, 235, 236, 237, + 188, 189, 190, 191, 192, 193, -1, 195, 196, 197, + 198, 199, 200, -1, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, -1, 213, -1, 215, -1, -1, + 218, 219, 220, 221, 222, 223, 224, -1, -1, 227, + 228, 229, 230, -1, 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, -1, -1, 283, 284, 285, -1, -1, - 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, - 298, 299, 300, 301, 302, 303, -1, 305, 306, 307, - 308, 309, 310, 311, 312, 313, -1, 315, 316, 317, - 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, - 328, -1, 330, 331, 332, 333, 334, 335, 336, 337, - 338, 339, 340, 341, -1, 343, 344, 345, 346, 347, + -1, 269, 270, -1, 272, 273, 274, 275, 276, 277, + 278, 279, -1, 281, 282, -1, -1, 285, 286, 287, + -1, -1, 290, 291, 292, 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, -1, 307, + 308, 309, 310, 311, 312, 313, 314, 315, -1, 317, + 318, 319, 320, 321, 322, -1, 324, 325, 326, 327, + 328, 329, 330, 331, -1, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 343, 344, 345, -1, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, - 358, 359, 360, -1, 362, 363, 364, 365, 366, 367, + 358, 359, 360, 361, 362, 363, 364, -1, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, - -1, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 388, 389, 390, 391, 392, 393, -1, 395, 396, -1, - 398, 399, 400, 401, 402, 403, 404, -1, 406, 407, - -1, -1, 410, 411, 412, 413, 414, 415, 416, 417, - 418, 419, 420, 421, 422, 423, -1, -1, 426, 427, - 428, 429, 430, 431, -1, 433, 434, 435, 436, 437, - 438, 439, -1, 441, 442, 443, 444, 445, 446, -1, - -1, 449, -1, -1, 452, 453, 454, 455, 456, 457, + 378, 379, 380, 381, -1, 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + -1, 399, 400, -1, 402, 403, 404, 405, 406, 407, + 408, -1, 410, 411, -1, -1, 414, 415, 416, 417, + 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, + -1, -1, 430, 431, 432, 433, 434, 435, -1, 437, + 438, 439, 440, 441, 442, 443, -1, 445, 446, 447, + 448, 449, 450, -1, -1, 453, -1, -1, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 471, 472, 473, -1, -1, -1, -1, - -1, -1, 480, 481, -1, -1, -1, -1, -1, 487, - -1, 489, -1, -1, -1, -1, 494, -1, 496, 497, - 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, - -1, -1, -1, -1, -1, -1, 19, 20, 21, 22, + 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, + -1, -1, -1, -1, -1, -1, 484, 485, -1, -1, + -1, -1, -1, 491, -1, 493, -1, -1, -1, -1, + 498, -1, 500, 501, 3, 4, 5, 6, 7, 8, + 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, + 19, 20, 21, 22, 23, 24, 25, 26, -1, 28, + 29, 30, -1, -1, -1, -1, -1, -1, -1, 38, + 39, -1, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, -1, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, -1, 68, + 69, 70, 71, 72, -1, 74, -1, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, -1, 87, 88, + 89, 90, 91, 92, -1, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, -1, 116, -1, 118, + 119, 120, 121, 122, 123, -1, 125, 126, 127, 128, + 129, -1, -1, 132, 133, 134, 135, 136, -1, 138, + 139, 140, -1, 142, 143, 144, -1, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, -1, + 159, 160, 161, 162, -1, 164, -1, 166, 167, -1, + 169, 170, 171, 172, 173, 174, -1, 176, -1, 178, + 179, 180, -1, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, -1, 195, 196, 197, 198, + 199, 200, -1, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, -1, 213, -1, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, -1, -1, 227, 228, + 229, 230, -1, 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, -1, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, -1, 281, 282, -1, -1, 285, 286, 287, -1, + -1, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, -1, 307, 308, + 309, 310, 311, 312, 313, 314, 315, -1, 317, 318, + 319, 320, 321, 322, -1, 324, 325, 326, 327, 328, + 329, 330, 331, -1, 333, 334, 335, 336, 337, 338, + 339, 340, 341, 342, 343, 344, 345, -1, 347, 348, + 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, + 359, 360, 361, 362, 363, 364, -1, 366, 367, 368, + 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, + 379, 380, 381, -1, 383, 384, 385, 386, 387, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, -1, + 399, 400, -1, 402, 403, 404, 405, 406, 407, 408, + -1, 410, 411, -1, -1, 414, 415, 416, 417, 418, + 419, 420, 421, 422, 423, 424, 425, 426, 427, -1, + -1, 430, 431, 432, 433, 434, 435, -1, 437, 438, + 439, 440, 441, 442, 443, -1, 445, 446, 447, 448, + 449, 450, -1, -1, 453, -1, -1, 456, 457, 458, + 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, + 469, 470, 471, 472, 473, 474, 475, 476, -1, -1, + -1, -1, -1, -1, -1, 484, 485, -1, -1, 3, + 4, 5, 6, 7, 493, 9, 10, -1, -1, -1, + -1, 500, 501, -1, -1, 19, 20, 21, 22, 23, + 24, 25, 26, -1, 28, 29, 30, -1, -1, -1, + -1, -1, -1, -1, 38, 39, -1, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, -1, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, -1, 68, 69, 70, 71, 72, -1, + 74, -1, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, -1, 87, 88, 89, 90, 91, 92, -1, + 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, -1, 116, -1, 118, 119, 120, 121, 122, 123, + -1, 125, 126, 127, 128, 129, -1, -1, 132, 133, + 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, + 144, -1, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 157, -1, 159, 160, 161, 162, -1, + 164, -1, 166, 167, -1, 169, 170, 171, 172, 173, + 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, + -1, 195, 196, 197, 198, 199, 200, -1, 202, 203, + 204, 205, 206, 207, 208, 209, 210, 211, -1, 213, + -1, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, -1, -1, 227, 228, 229, 230, -1, 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, -1, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, -1, 281, 282, -1, + -1, 285, 286, 287, -1, -1, 290, 291, 292, 293, + 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, -1, 307, 308, 309, 310, 311, 312, 313, + 314, 315, -1, 317, 318, 319, 320, 321, 322, -1, + 324, 325, 326, 327, 328, 329, 330, 331, -1, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, + 344, 345, -1, 347, 348, 349, 350, 351, 352, 353, + 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, + 364, -1, 366, 367, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 379, 380, 381, -1, 383, + 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, -1, 399, 400, -1, 402, 403, + 404, 405, 406, 407, 408, -1, 410, 411, -1, -1, + 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, + 424, 425, 426, 427, -1, -1, 430, 431, 432, 433, + 434, 435, -1, 437, 438, 439, 440, 441, 442, 443, + -1, 445, 446, 447, 448, 449, 450, -1, -1, 453, + -1, -1, 456, 457, 458, 459, 460, 461, 462, 463, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, + 474, 475, 476, -1, -1, -1, -1, -1, -1, -1, + 484, 485, -1, -1, -1, -1, -1, -1, -1, 493, + -1, -1, -1, -1, -1, -1, 500, 501, 3, 4, + 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, + -1, -1, -1, -1, 19, 20, 21, 22, 23, 24, + 25, 26, -1, 28, 29, 30, -1, -1, -1, -1, + -1, -1, -1, 38, 39, -1, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, -1, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, -1, 68, 69, 70, 71, 72, -1, 74, + -1, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, -1, 87, 88, 89, 90, 91, 92, -1, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + -1, 116, -1, 118, 119, 120, 121, 122, 123, -1, + 125, 126, 127, 128, 129, -1, -1, 132, 133, 134, + 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, + -1, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, -1, 159, 160, 161, 162, -1, 164, + -1, 166, 167, -1, 169, 170, 171, 172, 173, 174, + -1, 176, -1, 178, 179, 180, -1, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, -1, + 195, 196, 197, 198, 199, 200, -1, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, -1, 213, -1, + 215, -1, 217, 218, 219, 220, 221, 222, 223, 224, + -1, -1, 227, 228, 229, 230, -1, 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, -1, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, -1, 281, 282, -1, -1, + 285, 286, 287, -1, -1, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, -1, 307, 308, 309, 310, 311, 312, 313, 314, + 315, -1, 317, 318, 319, 320, 321, 322, -1, 324, + 325, 326, 327, 328, 329, 330, 331, -1, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 345, -1, 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + -1, 366, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 380, 381, -1, 383, 384, + 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, -1, 399, 400, -1, 402, 403, 404, + 405, 406, 407, 408, -1, 410, 411, -1, -1, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 426, 427, -1, -1, 430, 431, 432, 433, 434, + 435, -1, 437, 438, 439, 440, 441, 442, 443, -1, + 445, 446, 447, 448, 449, 450, -1, -1, 453, -1, + -1, 456, 457, 458, 459, 460, 461, 462, 463, 464, + 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, + 475, 476, -1, -1, -1, -1, -1, -1, -1, 484, + 485, -1, -1, -1, -1, -1, -1, -1, 493, -1, + -1, -1, -1, -1, -1, 500, 501, 3, 4, 5, + 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, + -1, -1, -1, 19, 20, 21, 22, 23, 24, 25, + 26, -1, 28, 29, 30, -1, -1, -1, -1, 35, + -1, -1, 38, 39, -1, 41, 42, 43, 44, 45, + 46, 47, -1, 49, 50, 51, 52, -1, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, -1, 68, 69, 70, 71, 72, -1, 74, -1, + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + -1, 87, 88, 89, 90, 91, 92, -1, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, -1, 118, 119, 120, 121, 122, 123, -1, 125, + 126, 127, 128, 129, -1, -1, 132, 133, 134, 135, + 136, -1, 138, 139, 140, -1, 142, -1, 144, -1, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, + 156, 157, -1, 159, 160, 161, 162, -1, 164, -1, + 166, 167, -1, 169, 170, 171, 172, -1, 174, -1, + 176, -1, 178, 179, 180, -1, 182, 183, 184, 185, + 186, 187, 188, -1, 190, 191, 192, 193, -1, 195, + 196, 197, 198, 199, 200, -1, 202, 203, 204, 205, + 206, 207, 208, 209, 210, 211, -1, 213, -1, 215, + -1, -1, 218, 219, 220, 221, 222, 223, 224, -1, + -1, 227, 228, 229, -1, -1, 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, -1, 269, 270, -1, 272, 273, 274, 275, + 276, 277, 278, 279, -1, 281, 282, -1, -1, 285, + 286, 287, -1, -1, 290, 291, 292, 293, 294, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + -1, 307, 308, 309, 310, 311, 312, 313, 314, 315, + -1, 317, 318, 319, 320, 321, 322, -1, 324, 325, + 326, 327, 328, 329, 330, 331, -1, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, + -1, 347, 348, 349, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 361, 362, 363, 364, -1, + 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, -1, 378, 379, 380, 381, -1, 383, 384, 385, + 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, -1, 399, 400, -1, 402, 403, 404, 405, + 406, 407, 408, -1, 410, 411, -1, -1, 414, 415, + 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, + 426, 427, -1, -1, 430, 431, 432, 433, 434, 435, + -1, 437, 438, 439, 440, 441, 442, 443, -1, 445, + 446, 447, 448, 449, 450, -1, -1, 453, -1, -1, + 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, + 476, -1, -1, -1, -1, -1, -1, -1, 484, 485, + 3, -1, -1, -1, -1, 491, -1, 493, -1, -1, + -1, -1, 498, -1, 500, 501, 19, 20, 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, -1, -1, - -1, -1, 35, -1, -1, 38, 39, -1, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - -1, 54, 55, 56, 57, 58, 59, 60, 61, 62, + -1, -1, -1, 36, -1, 38, 39, -1, 41, 42, + 43, -1, 45, 46, 47, 48, 49, -1, 51, 52, + -1, 54, 55, 56, 57, 58, 59, -1, -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, 71, 72, - -1, 74, -1, 76, 77, 78, 79, 80, 81, 82, + -1, -1, -1, 76, 77, 78, 79, 80, 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, 91, 92, - -1, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, -1, 118, 119, 120, 121, 122, + -1, 94, 95, 96, 97, -1, -1, -1, -1, -1, + -1, -1, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, -1, 116, -1, 118, 119, 120, 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, -1, 159, 160, 161, 162, - -1, 164, -1, 166, 167, -1, 169, 170, 171, 172, - 173, 174, -1, 176, -1, 178, 179, 180, -1, 182, - 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - -1, 194, 195, 196, 197, 198, 199, -1, 201, 202, - 203, 204, 205, 206, 207, 208, 209, -1, 211, -1, - 213, -1, -1, 216, 217, 218, 219, 220, 221, 222, - -1, -1, 225, 226, 227, 228, -1, 230, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, + 153, 154, 155, -1, 157, -1, 159, 160, 161, 162, + -1, 164, -1, 166, -1, -1, 169, 170, 171, 172, + -1, 174, -1, 176, -1, 178, 179, 180, -1, 182, + 183, 184, 185, 186, 187, 188, -1, 190, 191, 192, + 193, -1, 195, 196, 197, 198, 199, 200, -1, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 211, -1, + 213, -1, 215, -1, -1, 218, 219, 220, 221, 222, + 223, 224, -1, -1, 227, 228, 229, -1, -1, 232, + 233, 234, -1, -1, 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, -1, 267, 268, -1, 270, 271, 272, - 273, 274, 275, 276, 277, -1, 279, 280, -1, -1, - 283, 284, 285, -1, -1, 288, 289, 290, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, - 303, -1, 305, 306, 307, 308, 309, 310, 311, 312, - 313, -1, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, -1, 330, 331, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, -1, - 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 360, -1, 362, - 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, -1, 379, 380, 381, 382, + 263, 264, 265, 266, 267, -1, 269, 270, -1, 272, + -1, 274, 275, 276, 277, 278, 279, -1, 281, 282, + -1, -1, 285, 286, 287, -1, -1, 290, 291, -1, + 293, -1, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, -1, 307, 308, 309, 310, 311, 312, + 313, 314, 315, -1, 317, 318, 319, 320, 321, 322, + -1, 324, 325, 326, 327, 328, 329, 330, 331, -1, + 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, + 343, 344, 345, -1, 347, 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, -1, 366, 367, 368, 369, 370, -1, 372, + 373, 374, 375, 376, -1, 378, 379, 380, 381, -1, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, - 393, -1, 395, 396, -1, 398, 399, 400, 401, 402, - 403, 404, -1, 406, 407, -1, -1, 410, 411, 412, - 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, - 423, -1, -1, 426, 427, 428, 429, 430, 431, -1, - 433, 434, 435, 436, 437, 438, 439, -1, 441, 442, - 443, 444, 445, 446, -1, -1, 449, -1, -1, 452, - 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, + 393, 394, 395, 396, 397, -1, 399, 400, -1, 402, + 403, 404, 405, 406, 407, 408, -1, 410, 411, -1, + -1, 414, 415, 416, 417, 418, -1, 420, 421, 422, + 423, 424, 425, 426, 427, -1, -1, 430, 431, 432, + 433, 434, -1, -1, 437, 438, 439, 440, 441, 442, + 443, -1, 445, -1, 447, 448, 449, 450, -1, -1, + 453, -1, -1, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, - 473, -1, -1, -1, -1, -1, -1, 480, 481, -1, - -1, -1, -1, -1, 487, -1, 489, -1, -1, -1, - -1, 494, -1, 496, 497, 3, 4, 5, 6, 7, - 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, - -1, 19, 20, 21, 22, 23, 24, 25, 26, -1, - 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, - 38, 39, -1, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, -1, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, -1, - 68, 69, 70, 71, 72, -1, 74, -1, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, -1, 87, - 88, 89, 90, 91, 92, -1, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, -1, 116, -1, - 118, 119, 120, 121, 122, 123, -1, 125, 126, 127, - 128, 129, -1, -1, 132, 133, 134, 135, 136, -1, - 138, 139, 140, -1, 142, 143, 144, -1, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, - -1, 159, 160, 161, 162, -1, 164, -1, 166, 167, - -1, 169, 170, 171, 172, 173, 174, -1, 176, -1, - 178, 179, 180, -1, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, -1, 194, 195, 196, 197, - 198, 199, -1, 201, 202, 203, 204, 205, 206, 207, - 208, 209, -1, 211, -1, 213, 214, 215, 216, 217, - 218, 219, 220, 221, 222, -1, -1, 225, 226, 227, - 228, -1, 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, -1, 267, - 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, - -1, 279, 280, -1, -1, 283, 284, 285, -1, -1, - 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, - 298, 299, 300, 301, 302, 303, -1, 305, 306, 307, - 308, 309, 310, 311, 312, 313, -1, 315, 316, 317, - 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, - 328, -1, 330, 331, 332, 333, 334, 335, 336, 337, - 338, 339, 340, 341, -1, 343, 344, 345, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, - 358, 359, 360, -1, 362, 363, 364, 365, 366, 367, - 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, - -1, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 388, 389, 390, 391, 392, 393, -1, 395, 396, -1, - 398, 399, 400, 401, 402, 403, 404, -1, 406, 407, - -1, -1, 410, 411, 412, 413, 414, 415, 416, 417, - 418, 419, 420, 421, 422, 423, -1, -1, 426, 427, - 428, 429, 430, 431, -1, 433, 434, 435, 436, 437, - 438, 439, -1, 441, 442, 443, 444, 445, 446, -1, - -1, 449, -1, -1, 452, 453, 454, 455, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 471, 472, -1, -1, -1, -1, -1, - -1, -1, 480, 481, -1, -1, 3, 4, 5, 6, - 7, 489, 9, 10, -1, -1, -1, -1, 496, 497, - -1, -1, 19, 20, 21, 22, 23, 24, 25, 26, + 473, 474, 475, 476, -1, -1, 3, -1, 5, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 494, 19, 20, 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, -1, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 57, 58, 59, -1, 61, 62, 63, 64, 65, 66, -1, 68, 69, 70, 71, 72, -1, 74, -1, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, -1, 87, 88, 89, 90, 91, 92, -1, 94, 95, 96, @@ -225749,47 +241809,45 @@ static const yytype_int16 yycheck[] = -1, 118, 119, 120, 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, -1, 146, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 147, 148, 149, 150, 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, 161, 162, -1, 164, -1, 166, 167, -1, 169, 170, 171, 172, 173, 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, -1, 194, 195, 196, - 197, 198, 199, -1, 201, 202, 203, 204, 205, 206, - 207, 208, 209, -1, 211, -1, 213, 214, 215, 216, - 217, 218, 219, 220, 221, 222, -1, -1, 225, 226, - 227, 228, -1, 230, 231, 232, 233, 234, 235, 236, + 187, 188, 189, 190, 191, 192, 193, -1, 195, 196, + 197, 198, 199, 200, -1, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, -1, 213, -1, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 225, -1, + 227, 228, 229, 230, -1, 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, -1, - 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, - 277, -1, 279, 280, -1, -1, 283, 284, 285, -1, - -1, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, -1, 305, 306, - 307, 308, 309, 310, 311, 312, 313, -1, 315, 316, - 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, -1, 330, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, -1, 343, 344, 345, 346, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, -1, 269, 270, 271, 272, -1, 274, 275, 276, + 277, 278, 279, -1, 281, 282, -1, 284, 285, 286, + 287, -1, -1, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, -1, + 307, 308, 309, 310, 311, 312, 313, 314, 315, -1, + 317, 318, 319, 320, 321, 322, -1, 324, 325, 326, + 327, 328, 329, 330, 331, -1, 333, 334, 335, 336, + 337, 338, 339, 340, 341, 342, 343, 344, 345, -1, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, - 357, 358, 359, 360, -1, 362, 363, 364, 365, 366, + 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, -1, 379, 380, 381, 382, 383, 384, 385, 386, - 387, 388, 389, 390, 391, 392, 393, -1, 395, 396, - -1, 398, 399, 400, 401, 402, 403, 404, -1, 406, - 407, -1, -1, 410, 411, 412, 413, 414, 415, 416, - 417, 418, 419, 420, 421, 422, 423, -1, -1, 426, - 427, 428, 429, 430, 431, -1, 433, 434, 435, 436, - 437, 438, 439, -1, 441, 442, 443, 444, 445, 446, - -1, -1, 449, -1, -1, 452, 453, 454, 455, 456, + 377, 378, 379, 380, 381, -1, 383, 384, 385, 386, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, -1, 399, 400, 401, 402, 403, 404, 405, 406, + 407, 408, -1, 410, 411, -1, -1, 414, 415, 416, + 417, 418, -1, 420, 421, 422, 423, 424, 425, 426, + 427, -1, -1, 430, 431, 432, 433, 434, 435, -1, + 437, 438, 439, 440, 441, 442, 443, -1, 445, 446, + 447, 448, 449, 450, -1, -1, 453, -1, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 469, 470, 471, 472, -1, -1, -1, -1, - -1, -1, -1, 480, 481, -1, -1, -1, -1, -1, - -1, -1, 489, -1, -1, -1, -1, -1, -1, 496, - 497, 3, 4, 5, 6, 7, 8, 9, 10, -1, - -1, -1, -1, -1, -1, -1, -1, 19, 20, 21, + 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, + -1, 3, 479, 5, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 493, 19, 20, 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, -1, 54, 55, 56, 57, 58, 59, 60, 61, + 52, -1, 54, 55, 56, 57, 58, 59, -1, 61, 62, 63, 64, 65, 66, -1, 68, 69, 70, 71, 72, -1, 74, -1, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, -1, 87, 88, 89, 90, 91, @@ -225799,326 +241857,373 @@ static const yytype_int16 yycheck[] = 122, 123, -1, 125, 126, 127, 128, 129, -1, -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, -1, 159, 160, 161, + 152, 153, 154, 155, -1, 157, -1, 159, 160, 161, 162, -1, 164, -1, 166, 167, -1, 169, 170, 171, 172, 173, 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, - 192, -1, 194, 195, 196, 197, 198, 199, -1, 201, - 202, 203, 204, 205, 206, 207, 208, 209, -1, 211, + 192, 193, -1, 195, 196, 197, 198, 199, 200, -1, + 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, -1, 213, -1, 215, 216, 217, 218, 219, 220, 221, - 222, -1, -1, 225, 226, 227, 228, -1, 230, 231, + 222, 223, 224, 225, -1, 227, 228, 229, 230, -1, 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, -1, 267, 268, 269, 270, 271, - 272, 273, 274, 275, 276, 277, -1, 279, 280, -1, - -1, 283, 284, 285, -1, -1, 288, 289, 290, 291, + 262, 263, 264, 265, 266, 267, -1, 269, 270, 271, + 272, -1, 274, 275, 276, 277, 278, 279, -1, 281, + 282, -1, 284, 285, 286, 287, -1, -1, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, - 302, 303, -1, 305, 306, 307, 308, 309, 310, 311, - 312, 313, -1, 315, 316, 317, 318, 319, 320, 321, - 322, 323, 324, 325, 326, 327, 328, -1, 330, 331, - 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, - -1, 343, 344, 345, 346, 347, 348, 349, 350, 351, - 352, 353, 354, 355, 356, 357, 358, 359, 360, -1, - 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, - 372, 373, 374, 375, 376, 377, -1, 379, 380, 381, - 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, - 392, 393, -1, 395, 396, -1, 398, 399, 400, 401, - 402, 403, 404, -1, 406, 407, -1, -1, 410, 411, - 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, - 422, 423, -1, -1, 426, 427, 428, 429, 430, 431, - -1, 433, 434, 435, 436, 437, 438, 439, -1, 441, - 442, 443, 444, 445, 446, -1, -1, 449, -1, -1, - 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, + 302, 303, 304, 305, -1, 307, 308, 309, 310, 311, + 312, 313, 314, 315, -1, 317, 318, 319, 320, 321, + 322, -1, 324, 325, 326, 327, 328, 329, 330, 331, + -1, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 343, 344, 345, -1, 347, 348, 349, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, -1, 366, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, + -1, 383, 384, 385, 386, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, -1, 399, 400, -1, + 402, 403, 404, 405, 406, 407, 408, -1, 410, 411, + -1, -1, 414, 415, 416, 417, 418, -1, 420, 421, + 422, 423, 424, 425, 426, 427, -1, -1, 430, 431, + 432, 433, 434, 435, -1, 437, 438, 439, 440, 441, + 442, 443, -1, 445, 446, 447, 448, 449, 450, -1, + -1, 453, -1, -1, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, - 472, -1, -1, -1, -1, -1, -1, -1, 480, 481, - -1, -1, -1, -1, -1, -1, -1, 489, -1, -1, - -1, -1, -1, -1, 496, 497, 3, 4, 5, 6, - 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, - -1, -1, 19, 20, 21, 22, 23, 24, 25, 26, - -1, 28, 29, 30, -1, -1, -1, -1, 35, -1, + 472, 473, 474, 475, 476, -1, 3, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 493, 19, 20, 21, 22, 23, 24, 25, 26, + -1, 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, 41, 42, 43, 44, 45, 46, - 47, -1, 49, 50, 51, 52, -1, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 47, 48, 49, 50, 51, 52, -1, 54, 55, 56, + 57, 58, 59, -1, 61, 62, 63, 64, 65, 66, -1, 68, 69, 70, 71, 72, -1, 74, -1, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, -1, 87, 88, 89, 90, 91, 92, -1, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 107, 108, 109, 110, 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, -1, 132, 133, 134, 135, 136, - -1, 138, 139, 140, -1, 142, -1, 144, -1, 146, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + -1, 138, 139, 140, -1, 142, 143, 144, -1, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, 161, 162, -1, 164, -1, 166, - 167, -1, 169, 170, 171, 172, -1, 174, -1, 176, + 167, -1, 169, 170, 171, 172, 173, 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, 184, 185, 186, - 187, -1, 189, 190, 191, 192, -1, 194, 195, 196, - 197, 198, 199, -1, 201, 202, 203, 204, 205, 206, - 207, 208, 209, -1, 211, -1, 213, -1, -1, 216, - 217, 218, 219, 220, 221, 222, -1, -1, 225, 226, - 227, -1, -1, 230, 231, 232, 233, 234, 235, 236, + 187, 188, 189, 190, 191, 192, 193, -1, 195, 196, + 197, 198, 199, 200, -1, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, -1, 213, -1, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, -1, -1, + 227, 228, 229, 230, -1, 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, -1, - 267, 268, -1, 270, 271, 272, 273, 274, 275, 276, - 277, -1, 279, 280, -1, -1, 283, 284, 285, -1, - -1, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, -1, 305, 306, - 307, 308, 309, 310, 311, 312, 313, -1, 315, 316, - 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, -1, 330, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, -1, 343, 344, 345, 346, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, -1, 269, 270, 271, 272, -1, 274, 275, 276, + 277, 278, 279, -1, 281, 282, -1, -1, 285, 286, + 287, -1, -1, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, -1, + 307, 308, 309, 310, 311, 312, 313, 314, 315, -1, + 317, 318, 319, 320, 321, 322, -1, 324, 325, 326, + 327, 328, 329, 330, 331, -1, 333, 334, 335, 336, + 337, 338, 339, 340, 341, 342, 343, 344, 345, -1, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, - 357, 358, 359, 360, -1, 362, 363, 364, 365, 366, - 367, 368, 369, 370, 371, 372, -1, 374, 375, 376, - 377, -1, 379, 380, 381, 382, 383, 384, 385, 386, - 387, 388, 389, 390, 391, 392, 393, -1, 395, 396, - -1, 398, 399, 400, 401, 402, 403, 404, -1, 406, - 407, -1, -1, 410, 411, 412, 413, 414, 415, 416, - 417, 418, 419, 420, 421, 422, 423, -1, -1, 426, - 427, 428, 429, 430, 431, -1, 433, 434, 435, 436, - 437, 438, 439, -1, 441, 442, 443, 444, 445, 446, - -1, -1, 449, -1, -1, 452, 453, 454, 455, 456, + 357, 358, 359, 360, 361, 362, 363, 364, -1, 366, + 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, + 377, 378, 379, 380, 381, -1, 383, 384, 385, 386, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, -1, 399, 400, -1, 402, 403, 404, 405, 406, + 407, 408, -1, 410, 411, -1, -1, 414, 415, 416, + 417, 418, -1, 420, 421, 422, 423, 424, 425, 426, + 427, -1, -1, 430, 431, 432, 433, 434, 435, -1, + 437, 438, 439, 440, 441, 442, 443, -1, 445, 446, + 447, 448, 449, 450, -1, -1, 453, -1, -1, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 469, 470, 471, 472, -1, -1, -1, -1, - -1, -1, -1, 480, 481, 3, -1, -1, -1, -1, - 487, -1, 489, -1, -1, -1, -1, 494, -1, 496, - 497, 19, 20, 21, 22, 23, 24, 25, 26, -1, - 28, 29, 30, -1, -1, -1, -1, -1, 36, -1, - 38, 39, -1, 41, 42, 43, -1, 45, 46, 47, - 48, 49, -1, 51, 52, -1, 54, 55, 56, 57, - 58, 59, -1, -1, 62, 63, 64, 65, 66, -1, - 68, 69, 70, 71, 72, -1, -1, -1, 76, 77, - 78, 79, 80, 81, -1, 83, 84, 85, -1, 87, - 88, 89, 90, 91, 92, -1, 94, 95, 96, 97, - -1, -1, -1, -1, -1, -1, -1, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, -1, 116, -1, - 118, 119, 120, 121, 122, 123, -1, 125, 126, 127, - 128, 129, -1, -1, 132, 133, 134, 135, 136, -1, - 138, 139, 140, -1, 142, 143, 144, -1, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, -1, 157, - -1, 159, 160, 161, 162, -1, 164, -1, 166, -1, - -1, 169, 170, 171, 172, -1, 174, -1, 176, -1, - 178, 179, 180, -1, 182, 183, 184, 185, 186, 187, - -1, 189, 190, 191, 192, -1, 194, 195, 196, 197, - 198, 199, -1, 201, 202, 203, 204, 205, 206, 207, - 208, 209, -1, 211, -1, 213, -1, -1, 216, 217, - 218, 219, 220, 221, 222, -1, -1, 225, 226, 227, - -1, -1, 230, 231, 232, -1, -1, 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, -1, 267, - 268, -1, 270, -1, 272, 273, 274, 275, 276, 277, - -1, 279, 280, -1, -1, 283, 284, 285, -1, -1, - 288, 289, -1, 291, -1, 293, 294, 295, 296, 297, - 298, 299, 300, 301, 302, 303, -1, 305, 306, 307, - 308, 309, 310, 311, 312, 313, -1, 315, 316, 317, - 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, - 328, -1, 330, 331, 332, 333, 334, 335, 336, 337, - 338, 339, 340, 341, -1, 343, 344, 345, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, - 358, 359, 360, -1, 362, 363, 364, 365, 366, -1, - 368, 369, 370, 371, 372, -1, 374, 375, 376, 377, - -1, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 388, 389, 390, 391, 392, 393, -1, 395, 396, -1, - 398, 399, 400, 401, 402, 403, 404, -1, 406, 407, - -1, -1, 410, 411, 412, 413, 414, -1, 416, 417, - 418, 419, 420, 421, 422, 423, -1, -1, 426, 427, - 428, 429, 430, -1, -1, 433, 434, 435, 436, 437, - 438, 439, -1, 441, -1, 443, 444, 445, 446, -1, - -1, 449, -1, -1, 452, 453, 454, 455, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 471, 472, -1, -1, 3, -1, 5, + 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, + -1, 3, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 493, 19, 20, 21, + 22, 23, 24, 25, 26, -1, 28, 29, 30, -1, + -1, -1, -1, -1, -1, -1, 38, 39, -1, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, -1, 54, 55, 56, 57, 58, 59, -1, 61, + 62, 63, 64, 65, 66, -1, 68, 69, 70, 71, + 72, -1, 74, -1, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, -1, 87, 88, 89, 90, 91, + 92, -1, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, -1, 116, -1, 118, 119, 120, 121, + 122, 123, -1, 125, 126, 127, 128, 129, -1, -1, + 132, 133, 134, 135, 136, -1, 138, 139, 140, -1, + 142, 143, 144, -1, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, -1, 157, -1, 159, 160, 161, + 162, -1, 164, -1, 166, 167, -1, 169, 170, 171, + 172, 173, 174, -1, 176, -1, 178, 179, 180, -1, + 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, -1, 195, 196, 197, 198, 199, 200, -1, + 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, + -1, 213, -1, 215, 216, 217, 218, 219, 220, 221, + 222, 223, 224, -1, -1, 227, 228, 229, 230, -1, + 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, -1, 269, 270, 271, + 272, -1, 274, 275, 276, 277, 278, 279, -1, 281, + 282, -1, -1, 285, 286, 287, -1, -1, 290, 291, + 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, -1, 307, 308, 309, 310, 311, + 312, 313, 314, 315, -1, 317, 318, 319, 320, 321, + 322, -1, 324, 325, 326, 327, 328, 329, 330, 331, + -1, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 343, 344, 345, -1, 347, 348, 349, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, -1, 366, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, + -1, 383, 384, 385, 386, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, -1, 399, 400, -1, + 402, 403, 404, 405, 406, 407, 408, -1, 410, 411, + -1, -1, 414, 415, 416, 417, 418, -1, 420, 421, + 422, 423, 424, 425, 426, 427, -1, -1, 430, 431, + 432, 433, 434, 435, -1, 437, 438, 439, 440, 441, + 442, 443, -1, 445, 446, 447, 448, 449, 450, -1, + -1, 453, -1, -1, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 473, 474, 475, 476, -1, 3, 4, 5, -1, + -1, -1, 9, -1, -1, -1, -1, -1, -1, -1, + -1, 493, 19, 20, 21, 22, 23, 24, 25, 26, + -1, 28, 29, 30, -1, -1, -1, -1, -1, -1, + -1, 38, 39, -1, 41, 42, 43, -1, 45, 46, + 47, 48, 49, -1, 51, 52, -1, 54, 55, 56, + 57, 58, 59, -1, -1, 62, 63, 64, 65, 66, + -1, 68, 69, 70, 71, 72, -1, -1, -1, 76, + 77, 78, 79, 80, 81, -1, 83, 84, 85, -1, + 87, 88, 89, 90, 91, 92, -1, -1, 95, 96, + 97, -1, -1, -1, -1, -1, -1, -1, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, -1, 116, + -1, 118, 119, 120, 121, 122, 123, -1, 125, 126, + 127, 128, 129, -1, -1, 132, 133, 134, 135, 136, + -1, 138, 139, 140, -1, 142, 143, 144, -1, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, -1, 159, 160, 161, 162, -1, 164, -1, 166, + -1, -1, -1, 170, 171, 172, -1, 174, -1, 176, + -1, 178, 179, 180, -1, 182, 183, 184, 185, 186, + 187, 188, -1, 190, 191, 192, 193, -1, 195, 196, + 197, 198, 199, 200, -1, 202, -1, 204, 205, 206, + 207, 208, 209, 210, 211, -1, 213, -1, 215, -1, + -1, 218, -1, 220, 221, 222, 223, 224, -1, -1, + 227, -1, 229, -1, -1, 232, 233, 234, -1, -1, + 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, -1, 263, 264, 265, 266, + 267, -1, 269, 270, -1, 272, -1, 274, 275, 276, + 277, 278, 279, -1, 281, 282, 283, -1, 285, 286, + 287, -1, -1, 290, 291, -1, 293, -1, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, -1, + 307, 308, 309, 310, 311, 312, 313, 314, 315, -1, + 317, 318, 319, 320, 321, 322, -1, 324, 325, 326, + 327, 328, 329, 330, 331, -1, 333, 334, 335, 336, + 337, 338, 339, 340, 341, 342, 343, 344, 345, -1, + 347, 348, -1, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, -1, 366, + 367, 368, 369, 370, -1, 372, 373, 374, 375, 376, + -1, 378, 379, 380, 381, -1, 383, 384, 385, 386, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, -1, 399, 400, -1, 402, -1, 404, 405, 406, + 407, 408, -1, 410, 411, -1, -1, 414, 415, 416, + 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, + 427, -1, -1, 430, 431, 432, 433, 434, -1, -1, + 437, 438, 439, 440, 441, 442, 443, -1, 445, -1, + 447, 448, 449, 450, -1, -1, 453, -1, -1, 456, + 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, + 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, + -1, 3, -1, -1, -1, -1, -1, 484, 485, 486, + -1, -1, -1, -1, -1, -1, 493, 19, 20, 21, + 22, 23, 24, 25, 26, -1, 28, 29, 30, 31, + 32, -1, -1, -1, -1, -1, 38, 39, -1, 41, + 42, 43, -1, 45, 46, 47, 48, 49, -1, 51, + 52, -1, 54, 55, 56, 57, 58, 59, -1, -1, + 62, 63, 64, 65, 66, -1, 68, 69, 70, 71, + 72, -1, -1, -1, 76, 77, 78, 79, 80, 81, + -1, 83, 84, 85, -1, 87, 88, 89, 90, 91, + 92, -1, -1, 95, 96, 97, -1, -1, -1, -1, + -1, -1, -1, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, -1, 116, -1, 118, 119, 120, 121, + 122, 123, -1, 125, 126, 127, 128, 129, -1, -1, + 132, 133, 134, 135, 136, -1, 138, 139, 140, -1, + 142, 143, 144, -1, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, -1, 157, -1, 159, 160, 161, + 162, -1, 164, -1, 166, -1, -1, -1, 170, 171, + 172, -1, 174, -1, 176, -1, 178, 179, 180, -1, + 182, 183, 184, 185, 186, 187, 188, -1, 190, 191, + 192, 193, -1, 195, 196, 197, 198, 199, 200, -1, + 202, -1, 204, 205, 206, 207, 208, 209, 210, 211, + -1, 213, -1, 215, -1, -1, 218, -1, 220, 221, + 222, 223, 224, -1, -1, 227, -1, 229, -1, -1, + 232, 233, 234, -1, -1, 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, + -1, 263, 264, 265, 266, 267, -1, 269, 270, -1, + 272, -1, 274, 275, 276, 277, 278, 279, -1, 281, + 282, -1, -1, 285, 286, 287, -1, -1, 290, 291, + -1, 293, -1, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, -1, 307, 308, 309, 310, 311, + 312, 313, 314, 315, -1, 317, 318, 319, 320, 321, + 322, -1, 324, 325, 326, 327, 328, 329, 330, 331, + -1, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 343, 344, 345, -1, 347, 348, -1, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, 365, 366, 367, 368, 369, 370, -1, + 372, 373, 374, 375, 376, -1, 378, 379, 380, 381, + -1, 383, 384, 385, 386, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, -1, 399, 400, 401, + 402, -1, 404, 405, 406, 407, 408, -1, 410, 411, + -1, -1, 414, 415, 416, 417, 418, -1, 420, 421, + 422, 423, 424, 425, 426, 427, -1, -1, 430, 431, + 432, 433, 434, -1, -1, 437, 438, 439, 440, 441, + 442, 443, -1, 445, -1, 447, 448, 449, 450, -1, + -1, 453, -1, 455, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 473, 474, 475, 476, -1, 3, 479, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 490, 19, 20, 21, 22, 23, 24, 25, - 26, -1, 28, 29, 30, -1, -1, -1, -1, -1, - -1, -1, 38, 39, -1, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, -1, 54, 55, - 56, 57, 58, 59, -1, 61, 62, 63, 64, 65, - 66, -1, 68, 69, 70, 71, 72, -1, 74, -1, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - -1, 87, 88, 89, 90, 91, 92, -1, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, -1, - 116, -1, 118, 119, 120, 121, 122, 123, -1, 125, - 126, 127, 128, 129, -1, -1, 132, 133, 134, 135, - 136, -1, 138, 139, 140, -1, 142, 143, 144, -1, - 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, - -1, 157, -1, 159, 160, 161, 162, -1, 164, -1, - 166, 167, -1, 169, 170, 171, 172, 173, 174, -1, - 176, -1, 178, 179, 180, -1, 182, 183, 184, 185, - 186, 187, 188, 189, 190, 191, 192, -1, 194, 195, - 196, 197, 198, 199, -1, 201, 202, 203, 204, 205, - 206, 207, 208, 209, -1, 211, -1, 213, 214, 215, - 216, 217, 218, 219, 220, 221, 222, 223, -1, 225, - 226, 227, 228, -1, 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, - -1, 267, 268, 269, 270, -1, 272, 273, 274, 275, - 276, 277, -1, 279, 280, -1, 282, 283, 284, 285, - -1, -1, 288, 289, 290, 291, 292, 293, 294, 295, - 296, 297, 298, 299, 300, 301, 302, 303, -1, 305, - 306, 307, 308, 309, 310, 311, 312, 313, -1, 315, - 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, - 326, 327, 328, -1, 330, 331, 332, 333, 334, 335, - 336, 337, 338, 339, 340, 341, -1, 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, -1, 379, 380, 381, 382, 383, 384, 385, - 386, 387, 388, 389, 390, 391, 392, 393, -1, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, -1, - 406, 407, -1, -1, 410, 411, 412, 413, 414, -1, - 416, 417, 418, 419, 420, 421, 422, 423, -1, -1, - 426, 427, 428, 429, 430, 431, -1, 433, 434, 435, - 436, 437, 438, 439, -1, 441, 442, 443, 444, 445, - 446, -1, -1, 449, -1, 451, 452, 453, 454, 455, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, -1, 3, 475, - 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 489, 19, 20, 21, 22, 23, 24, - 25, 26, -1, 28, 29, 30, -1, -1, -1, -1, - -1, -1, -1, 38, 39, -1, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, -1, 54, - 55, 56, 57, 58, 59, -1, 61, 62, 63, 64, - 65, 66, -1, 68, 69, 70, 71, 72, -1, 74, - -1, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 85, -1, 87, 88, 89, 90, 91, 92, -1, 94, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - -1, 116, -1, 118, 119, 120, 121, 122, 123, -1, - 125, 126, 127, 128, 129, -1, -1, 132, 133, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - -1, 146, 147, 148, 149, 150, 151, 152, 153, 154, - 155, -1, 157, -1, 159, 160, 161, 162, -1, 164, - -1, 166, 167, -1, 169, 170, 171, 172, 173, 174, - -1, 176, -1, 178, 179, 180, -1, 182, 183, 184, - 185, 186, 187, 188, 189, 190, 191, 192, -1, 194, - 195, 196, 197, 198, 199, -1, 201, 202, 203, 204, - 205, 206, 207, 208, 209, -1, 211, -1, 213, 214, - 215, 216, 217, 218, 219, 220, 221, 222, 223, -1, - 225, 226, 227, 228, -1, 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, -1, 267, 268, 269, 270, -1, 272, 273, 274, - 275, 276, 277, -1, 279, 280, -1, 282, 283, 284, - 285, -1, -1, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, -1, - 305, 306, 307, 308, 309, 310, 311, 312, 313, -1, - 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, -1, 330, 331, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, -1, 343, 344, - 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 359, 360, -1, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, -1, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 388, 389, 390, 391, 392, 393, -1, - 395, 396, -1, 398, 399, 400, 401, 402, 403, 404, - -1, 406, 407, -1, -1, 410, 411, 412, 413, 414, - -1, 416, 417, 418, 419, 420, 421, 422, 423, -1, - -1, 426, 427, 428, 429, 430, 431, -1, 433, 434, - 435, 436, 437, 438, 439, -1, 441, 442, 443, 444, - 445, 446, -1, -1, 449, -1, -1, 452, 453, 454, - 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, - 465, 466, 467, 468, 469, 470, 471, 472, -1, 3, + -1, 493, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, -1, -1, -1, -1, -1, -1, + -1, 38, 39, -1, 41, 42, 43, -1, 45, 46, + 47, 48, 49, -1, 51, 52, -1, 54, 55, 56, + 57, 58, 59, -1, -1, 62, 63, 64, 65, 66, + -1, 68, 69, 70, 71, 72, -1, -1, -1, 76, + 77, 78, 79, 80, 81, -1, 83, 84, 85, -1, + 87, 88, 89, 90, 91, 92, -1, -1, 95, 96, + 97, -1, -1, -1, -1, -1, -1, -1, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, -1, 116, + -1, 118, 119, 120, 121, 122, 123, -1, 125, 126, + 127, 128, 129, -1, -1, 132, 133, 134, 135, 136, + -1, 138, 139, 140, -1, 142, 143, 144, -1, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, -1, + 157, -1, 159, 160, 161, 162, -1, 164, -1, 166, + -1, -1, -1, 170, 171, 172, -1, 174, -1, 176, + -1, 178, 179, 180, -1, 182, 183, 184, 185, 186, + 187, 188, -1, 190, 191, 192, 193, -1, 195, 196, + 197, 198, 199, 200, -1, 202, -1, 204, 205, 206, + 207, 208, 209, 210, 211, -1, 213, -1, 215, -1, + -1, 218, -1, 220, 221, 222, 223, 224, -1, -1, + 227, -1, 229, -1, -1, 232, 233, 234, -1, -1, + 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, -1, 263, 264, 265, 266, + 267, -1, 269, 270, -1, 272, -1, 274, 275, 276, + 277, 278, 279, -1, 281, 282, -1, -1, 285, 286, + 287, -1, -1, 290, 291, -1, 293, -1, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, -1, + 307, 308, 309, 310, 311, 312, 313, 314, 315, -1, + 317, 318, 319, 320, 321, 322, -1, 324, 325, 326, + 327, 328, 329, 330, 331, -1, 333, 334, 335, 336, + 337, 338, 339, 340, 341, 342, 343, 344, 345, -1, + 347, 348, -1, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, + 367, 368, 369, 370, -1, 372, 373, 374, 375, 376, + -1, 378, 379, 380, 381, -1, 383, 384, 385, 386, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, -1, 399, 400, 401, 402, -1, 404, 405, 406, + 407, 408, -1, 410, 411, -1, -1, 414, 415, 416, + 417, 418, -1, 420, 421, 422, 423, 424, 425, 426, + 427, -1, -1, 430, 431, 432, 433, 434, -1, -1, + 437, 438, 439, 440, 441, 442, 443, -1, 445, -1, + 447, 448, 449, 450, -1, -1, 453, -1, 455, 456, + 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, + 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, + -1, 3, 479, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 493, 19, 20, 21, + 22, 23, 24, 25, 26, -1, 28, 29, 30, -1, + -1, -1, -1, -1, -1, -1, 38, 39, -1, 41, + 42, 43, -1, 45, 46, 47, 48, 49, -1, 51, + 52, -1, 54, 55, 56, 57, 58, 59, -1, -1, + 62, 63, 64, 65, 66, -1, 68, 69, 70, 71, + 72, -1, -1, -1, 76, 77, 78, 79, 80, 81, + -1, 83, 84, 85, -1, 87, 88, 89, 90, 91, + 92, -1, -1, 95, 96, 97, -1, -1, -1, -1, + -1, -1, -1, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, -1, 116, -1, 118, 119, 120, 121, + 122, 123, -1, 125, 126, 127, 128, 129, -1, -1, + 132, 133, 134, 135, 136, -1, 138, 139, 140, -1, + 142, 143, 144, -1, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, -1, 157, -1, 159, 160, 161, + 162, -1, 164, -1, 166, -1, -1, -1, 170, 171, + 172, -1, 174, -1, 176, -1, 178, 179, 180, -1, + 182, 183, 184, 185, 186, 187, 188, -1, 190, 191, + 192, 193, -1, 195, 196, 197, 198, 199, 200, -1, + 202, -1, 204, 205, 206, 207, 208, 209, 210, 211, + -1, 213, -1, 215, -1, -1, 218, -1, 220, 221, + 222, 223, 224, -1, -1, 227, -1, 229, -1, -1, + 232, 233, 234, -1, -1, 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, + -1, 263, 264, 265, 266, 267, -1, 269, 270, -1, + 272, -1, 274, 275, 276, 277, 278, 279, -1, 281, + 282, -1, -1, 285, 286, 287, -1, -1, 290, 291, + -1, 293, -1, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, -1, 307, 308, 309, 310, 311, + 312, 313, 314, 315, -1, 317, 318, 319, 320, 321, + 322, -1, 324, 325, 326, 327, 328, 329, 330, 331, + -1, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 343, 344, 345, -1, 347, 348, -1, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, 365, 366, 367, 368, 369, 370, -1, + 372, 373, 374, 375, 376, -1, 378, 379, 380, 381, + -1, 383, 384, 385, 386, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, -1, 399, 400, 401, + 402, -1, 404, 405, 406, 407, 408, -1, 410, 411, + -1, -1, 414, 415, 416, 417, 418, -1, 420, 421, + 422, 423, 424, 425, 426, 427, -1, -1, 430, 431, + 432, 433, 434, -1, -1, 437, 438, 439, 440, 441, + 442, 443, -1, 445, -1, 447, 448, 449, 450, -1, + -1, 453, -1, 455, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 473, 474, 475, 476, -1, 3, 479, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 489, 19, 20, 21, 22, 23, - 24, 25, 26, -1, 28, 29, 30, -1, -1, -1, - -1, -1, -1, -1, 38, 39, -1, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, -1, - 54, 55, 56, 57, 58, 59, -1, 61, 62, 63, - 64, 65, 66, -1, 68, 69, 70, 71, 72, -1, - 74, -1, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 85, -1, 87, 88, 89, 90, 91, 92, -1, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - 114, -1, 116, -1, 118, 119, 120, 121, 122, 123, - -1, 125, 126, 127, 128, 129, -1, -1, 132, 133, - 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, - 144, -1, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, -1, 157, -1, 159, 160, 161, 162, -1, - 164, -1, 166, 167, -1, 169, 170, 171, 172, 173, - 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, - 184, 185, 186, 187, 188, 189, 190, 191, 192, -1, - 194, 195, 196, 197, 198, 199, -1, 201, 202, 203, - 204, 205, 206, 207, 208, 209, -1, 211, -1, 213, - 214, 215, 216, 217, 218, 219, 220, 221, 222, -1, - -1, 225, 226, 227, 228, -1, 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, -1, 267, 268, 269, 270, -1, 272, 273, - 274, 275, 276, 277, -1, 279, 280, -1, -1, 283, - 284, 285, -1, -1, 288, 289, 290, 291, 292, 293, - 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, - -1, 305, 306, 307, 308, 309, 310, 311, 312, 313, - -1, 315, 316, 317, 318, 319, 320, 321, 322, 323, - 324, 325, 326, 327, 328, -1, 330, 331, 332, 333, - 334, 335, 336, 337, 338, 339, 340, 341, -1, 343, - 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, - 354, 355, 356, 357, 358, 359, 360, -1, 362, 363, - 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, - 374, 375, 376, 377, -1, 379, 380, 381, 382, 383, - 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, - -1, 395, 396, -1, 398, 399, 400, 401, 402, 403, - 404, -1, 406, 407, -1, -1, 410, 411, 412, 413, - 414, -1, 416, 417, 418, 419, 420, 421, 422, 423, - -1, -1, 426, 427, 428, 429, 430, 431, -1, 433, - 434, 435, 436, 437, 438, 439, -1, 441, 442, 443, - 444, 445, 446, -1, -1, 449, -1, -1, 452, 453, - 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 471, 472, -1, - 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 489, 19, 20, 21, 22, - 23, 24, 25, 26, -1, 28, 29, 30, -1, -1, - -1, -1, -1, -1, -1, 38, 39, -1, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - -1, 54, 55, 56, 57, 58, 59, -1, 61, 62, - 63, 64, 65, 66, -1, 68, 69, 70, 71, 72, - -1, 74, -1, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, -1, 87, 88, 89, 90, 91, 92, - -1, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, -1, 116, -1, 118, 119, 120, 121, 122, - 123, -1, 125, 126, 127, 128, 129, -1, -1, 132, - 133, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, -1, 146, 147, 148, 149, 150, 151, 152, - 153, 154, 155, -1, 157, -1, 159, 160, 161, 162, - -1, 164, -1, 166, 167, -1, 169, 170, 171, 172, - 173, 174, -1, 176, -1, 178, 179, 180, -1, 182, - 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - -1, 194, 195, 196, 197, 198, 199, -1, 201, 202, - 203, 204, 205, 206, 207, 208, 209, -1, 211, -1, - 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, - -1, -1, 225, 226, 227, 228, -1, 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, -1, 267, 268, 269, 270, -1, 272, - 273, 274, 275, 276, 277, -1, 279, 280, -1, -1, - 283, 284, 285, -1, -1, 288, 289, 290, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, - 303, -1, 305, 306, 307, 308, 309, 310, 311, 312, - 313, -1, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, -1, 330, 331, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, -1, - 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 360, -1, 362, - 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, -1, 379, 380, 381, 382, - 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, - 393, -1, 395, 396, -1, 398, 399, 400, 401, 402, - 403, 404, -1, 406, 407, -1, -1, 410, 411, 412, - 413, 414, -1, 416, 417, 418, 419, 420, 421, 422, - 423, -1, -1, 426, 427, 428, 429, 430, 431, -1, - 433, 434, 435, 436, 437, 438, 439, -1, 441, 442, - 443, 444, 445, 446, -1, -1, 449, -1, -1, 452, - 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, - 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, - -1, 3, 4, 5, -1, -1, -1, 9, -1, -1, - -1, -1, -1, -1, -1, -1, 489, 19, 20, 21, + -1, 493, 19, 20, 21, 22, 23, 24, 25, 26, + -1, 28, 29, 30, -1, -1, -1, -1, -1, -1, + -1, 38, 39, -1, 41, 42, 43, -1, 45, 46, + 47, 48, 49, -1, 51, 52, -1, 54, 55, 56, + 57, 58, 59, -1, -1, 62, 63, 64, 65, 66, + -1, 68, 69, 70, 71, 72, -1, -1, -1, 76, + 77, 78, 79, 80, 81, -1, 83, 84, 85, -1, + 87, 88, 89, 90, 91, 92, -1, -1, 95, 96, + 97, -1, -1, -1, -1, -1, -1, -1, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, -1, 116, + -1, 118, 119, 120, 121, 122, 123, -1, 125, 126, + 127, 128, 129, -1, -1, 132, 133, 134, 135, 136, + -1, 138, 139, 140, -1, 142, 143, 144, -1, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, -1, + 157, -1, 159, 160, 161, 162, -1, 164, -1, 166, + -1, -1, -1, 170, 171, 172, -1, 174, -1, 176, + -1, 178, 179, 180, -1, 182, 183, 184, 185, 186, + 187, 188, -1, 190, 191, 192, 193, -1, 195, 196, + 197, 198, 199, 200, -1, 202, -1, 204, 205, 206, + 207, 208, 209, 210, 211, -1, 213, -1, 215, -1, + -1, 218, -1, 220, 221, 222, 223, 224, -1, -1, + 227, -1, 229, -1, -1, 232, 233, 234, -1, -1, + 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, -1, 263, 264, 265, 266, + 267, -1, 269, 270, -1, 272, -1, 274, 275, 276, + 277, 278, 279, -1, 281, 282, -1, -1, 285, 286, + 287, -1, -1, 290, 291, -1, 293, -1, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, -1, + 307, 308, 309, 310, 311, 312, 313, 314, 315, -1, + 317, 318, 319, 320, 321, 322, -1, 324, 325, 326, + 327, 328, 329, 330, 331, -1, 333, 334, 335, 336, + 337, 338, 339, 340, 341, 342, 343, 344, 345, -1, + 347, 348, -1, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, -1, 366, + 367, 368, 369, 370, -1, 372, 373, 374, 375, 376, + -1, 378, 379, 380, 381, -1, 383, 384, 385, 386, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, -1, 399, 400, -1, 402, -1, 404, 405, 406, + 407, 408, -1, 410, 411, -1, -1, 414, 415, 416, + 417, 418, -1, 420, 421, 422, 423, 424, 425, 426, + 427, -1, -1, 430, 431, 432, 433, 434, -1, -1, + 437, 438, 439, 440, 441, 442, 443, -1, 445, -1, + 447, 448, 449, 450, -1, -1, 453, -1, -1, 456, + 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, + 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, + -1, 3, -1, 5, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 493, 19, 20, 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, 51, @@ -226132,229 +242237,136 @@ static const yytype_int16 yycheck[] = 122, 123, -1, 125, 126, 127, 128, 129, -1, -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, -1, 159, 160, 161, + 152, 153, 154, 155, -1, 157, -1, 159, 160, 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, -1, - 182, 183, 184, 185, 186, 187, -1, 189, 190, 191, - 192, -1, 194, 195, 196, 197, 198, 199, -1, 201, - -1, 203, 204, 205, 206, 207, 208, 209, -1, 211, - -1, 213, -1, -1, 216, -1, 218, 219, 220, 221, - 222, -1, -1, 225, -1, 227, -1, -1, 230, 231, - 232, -1, -1, 235, 236, 237, 238, 239, 240, 241, + 182, 183, 184, 185, 186, 187, 188, -1, 190, 191, + 192, 193, -1, 195, 196, 197, 198, 199, 200, -1, + 202, -1, 204, 205, 206, 207, 208, 209, 210, 211, + -1, 213, -1, 215, -1, -1, 218, -1, 220, 221, + 222, 223, 224, -1, -1, 227, -1, 229, -1, -1, + 232, 233, 234, -1, -1, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, - 252, 253, 254, 255, 256, 257, 258, 259, -1, 261, - 262, 263, 264, 265, -1, 267, 268, -1, 270, -1, - 272, 273, 274, 275, 276, 277, -1, 279, 280, 281, - -1, 283, 284, 285, -1, -1, 288, 289, -1, 291, - -1, 293, 294, 295, 296, 297, 298, 299, 300, 301, - 302, 303, -1, 305, 306, 307, 308, 309, 310, 311, - 312, 313, -1, 315, 316, 317, 318, 319, 320, 321, - 322, 323, 324, 325, 326, 327, 328, -1, 330, 331, - 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, - -1, 343, 344, -1, 346, 347, 348, 349, 350, 351, - 352, 353, 354, 355, 356, 357, 358, 359, 360, -1, - 362, 363, 364, 365, 366, -1, 368, 369, 370, 371, - 372, -1, 374, 375, 376, 377, -1, 379, 380, 381, - 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, - 392, 393, -1, 395, 396, -1, 398, -1, 400, 401, - 402, 403, 404, -1, 406, 407, -1, -1, 410, 411, - 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, - 422, 423, -1, -1, 426, 427, 428, 429, 430, -1, - -1, 433, 434, 435, 436, 437, 438, 439, -1, 441, - -1, 443, 444, 445, 446, -1, -1, 449, -1, -1, - 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, + 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, + -1, 263, 264, 265, 266, 267, -1, 269, 270, -1, + 272, -1, 274, 275, 276, 277, 278, 279, -1, 281, + 282, -1, -1, 285, 286, 287, -1, -1, 290, 291, + -1, 293, -1, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, -1, 307, 308, 309, 310, 311, + 312, 313, 314, 315, -1, 317, 318, 319, 320, 321, + 322, -1, 324, 325, 326, 327, 328, 329, 330, 331, + -1, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 343, 344, 345, -1, 347, 348, -1, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, -1, 366, 367, 368, 369, 370, -1, + 372, 373, 374, 375, 376, -1, 378, 379, 380, 381, + -1, 383, 384, 385, 386, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, -1, 399, 400, -1, + 402, -1, 404, 405, 406, 407, 408, -1, 410, 411, + -1, -1, 414, 415, 416, 417, 418, -1, 420, 421, + 422, 423, 424, 425, 426, 427, -1, -1, 430, 431, + 432, 433, 434, -1, -1, 437, 438, 439, 440, 441, + 442, 443, -1, 445, -1, 447, 448, 449, 450, -1, + -1, 453, -1, -1, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, - 472, -1, 3, -1, -1, -1, -1, -1, 480, 481, - 482, -1, -1, -1, -1, -1, -1, 489, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - 31, 32, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, 397, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, -1, 3, 475, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 489, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, -1, -1, -1, -1, -1, -1, -1, 38, 39, - -1, 41, 42, 43, -1, 45, 46, 47, 48, 49, - -1, 51, 52, -1, 54, 55, 56, 57, 58, 59, - -1, -1, 62, 63, 64, 65, 66, -1, 68, 69, - 70, 71, 72, -1, -1, -1, 76, 77, 78, 79, - 80, 81, -1, 83, 84, 85, -1, 87, 88, 89, - 90, 91, 92, -1, -1, 95, 96, 97, -1, -1, - -1, -1, -1, -1, -1, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, -1, 116, -1, 118, 119, - 120, 121, 122, 123, -1, 125, 126, 127, 128, 129, - -1, -1, 132, 133, 134, 135, 136, -1, 138, 139, - 140, -1, 142, 143, 144, -1, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, -1, 157, -1, 159, - 160, 161, 162, -1, 164, -1, 166, -1, -1, -1, - 170, 171, 172, -1, 174, -1, 176, -1, 178, 179, - 180, -1, 182, 183, 184, 185, 186, 187, -1, 189, - 190, 191, 192, -1, 194, 195, 196, 197, 198, 199, - -1, 201, -1, 203, 204, 205, 206, 207, 208, 209, - -1, 211, -1, 213, -1, -1, 216, -1, 218, 219, - 220, 221, 222, -1, -1, 225, -1, 227, -1, -1, - 230, 231, 232, -1, -1, 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, - -1, 261, 262, 263, 264, 265, -1, 267, 268, -1, - 270, -1, 272, 273, 274, 275, 276, 277, -1, 279, - 280, -1, -1, 283, 284, 285, -1, -1, 288, 289, - -1, 291, -1, 293, 294, 295, 296, 297, 298, 299, - 300, 301, 302, 303, -1, 305, 306, 307, 308, 309, - 310, 311, 312, 313, -1, 315, 316, 317, 318, 319, - 320, 321, 322, 323, 324, 325, 326, 327, 328, -1, - 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, - 340, 341, -1, 343, 344, -1, 346, 347, 348, 349, - 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, - 360, 361, 362, 363, 364, 365, 366, -1, 368, 369, - 370, 371, 372, -1, 374, 375, 376, 377, -1, 379, - 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, - 390, 391, 392, 393, -1, 395, 396, 397, 398, -1, - 400, 401, 402, 403, 404, -1, 406, 407, -1, -1, - 410, 411, 412, 413, 414, -1, 416, 417, 418, 419, - 420, 421, 422, 423, -1, -1, 426, 427, 428, 429, - 430, -1, -1, 433, 434, 435, 436, 437, 438, 439, - -1, 441, -1, 443, 444, 445, 446, -1, -1, 449, - -1, 451, 452, 453, 454, 455, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 471, 472, -1, 3, 475, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 489, - 19, 20, 21, 22, 23, 24, 25, 26, -1, 28, - 29, 30, -1, -1, -1, -1, -1, -1, -1, 38, - 39, -1, 41, 42, 43, -1, 45, 46, 47, 48, - 49, -1, 51, 52, -1, 54, 55, 56, 57, 58, - 59, -1, -1, 62, 63, 64, 65, 66, -1, 68, - 69, 70, 71, 72, -1, -1, -1, 76, 77, 78, - 79, 80, 81, -1, 83, 84, 85, -1, 87, 88, - 89, 90, 91, 92, -1, -1, 95, 96, 97, -1, - -1, -1, -1, -1, -1, -1, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, -1, 116, -1, 118, - 119, 120, 121, 122, 123, -1, 125, 126, 127, 128, - 129, -1, -1, 132, 133, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, -1, 146, 147, 148, - 149, 150, 151, 152, 153, 154, 155, -1, 157, -1, - 159, 160, 161, 162, -1, 164, -1, 166, -1, -1, - -1, 170, 171, 172, -1, 174, -1, 176, -1, 178, - 179, 180, -1, 182, 183, 184, 185, 186, 187, -1, - 189, 190, 191, 192, -1, 194, 195, 196, 197, 198, - 199, -1, 201, -1, 203, 204, 205, 206, 207, 208, - 209, -1, 211, -1, 213, -1, -1, 216, -1, 218, - 219, 220, 221, 222, -1, -1, 225, -1, 227, -1, - -1, 230, 231, 232, -1, -1, 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, -1, 261, 262, 263, 264, 265, -1, 267, 268, - -1, 270, -1, 272, 273, 274, 275, 276, 277, -1, - 279, 280, -1, -1, 283, 284, 285, -1, -1, 288, - 289, -1, 291, -1, 293, 294, 295, 296, 297, 298, - 299, 300, 301, 302, 303, -1, 305, 306, 307, 308, - 309, 310, 311, 312, 313, -1, 315, 316, 317, 318, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - -1, 330, 331, 332, 333, 334, 335, 336, 337, 338, - 339, 340, 341, -1, 343, 344, -1, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, - 359, 360, 361, 362, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, -1, 374, 375, 376, 377, -1, - 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, - 389, 390, 391, 392, 393, -1, 395, 396, 397, 398, - -1, 400, 401, 402, 403, 404, -1, 406, 407, -1, - -1, 410, 411, 412, 413, 414, -1, 416, 417, 418, - 419, 420, 421, 422, 423, -1, -1, 426, 427, 428, - 429, 430, -1, -1, 433, 434, 435, 436, 437, 438, - 439, -1, 441, -1, 443, 444, 445, 446, -1, -1, - 449, -1, 451, 452, 453, 454, 455, 456, 457, 458, - 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, - 469, 470, 471, 472, -1, 3, 475, 5, -1, -1, + 472, 473, 474, 475, 476, -1, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 489, 19, 20, 21, 22, 23, 24, 25, 26, -1, - 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, - 38, 39, -1, 41, 42, 43, -1, 45, 46, 47, - 48, 49, -1, 51, 52, -1, 54, 55, 56, 57, - 58, 59, -1, -1, 62, 63, 64, 65, 66, -1, - 68, 69, 70, 71, 72, -1, -1, -1, 76, 77, - 78, 79, 80, 81, -1, 83, 84, 85, -1, 87, - 88, 89, 90, 91, 92, -1, -1, 95, 96, 97, - -1, -1, -1, -1, -1, -1, -1, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, -1, 116, -1, - 118, 119, 120, 121, 122, 123, -1, 125, 126, 127, - 128, 129, -1, -1, 132, 133, 134, 135, 136, -1, - 138, 139, 140, -1, 142, 143, 144, -1, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, -1, 157, - -1, 159, 160, 161, 162, -1, 164, -1, 166, -1, - -1, -1, 170, 171, 172, -1, 174, -1, 176, -1, - 178, 179, 180, -1, 182, 183, 184, 185, 186, 187, - -1, 189, 190, 191, 192, -1, 194, 195, 196, 197, - 198, 199, -1, 201, -1, 203, 204, 205, 206, 207, - 208, 209, -1, 211, -1, 213, -1, -1, 216, -1, - 218, 219, 220, 221, 222, -1, -1, 225, -1, 227, - -1, -1, 230, 231, 232, -1, -1, 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, -1, 261, 262, 263, 264, 265, -1, 267, - 268, -1, 270, -1, 272, 273, 274, 275, 276, 277, - -1, 279, 280, -1, -1, 283, 284, 285, -1, -1, - 288, 289, -1, 291, -1, 293, 294, 295, 296, 297, - 298, 299, 300, 301, 302, 303, -1, 305, 306, 307, - 308, 309, 310, 311, 312, 313, -1, 315, 316, 317, - 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, - 328, -1, 330, 331, 332, 333, 334, 335, 336, 337, - 338, 339, 340, 341, -1, 343, 344, -1, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, - 358, 359, 360, -1, 362, 363, 364, 365, 366, -1, - 368, 369, 370, 371, 372, -1, 374, 375, 376, 377, - -1, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 388, 389, 390, 391, 392, 393, -1, 395, 396, -1, - 398, -1, 400, 401, 402, 403, 404, -1, 406, 407, - -1, -1, 410, 411, 412, 413, 414, -1, 416, 417, - 418, 419, 420, 421, 422, 423, -1, -1, 426, 427, - 428, 429, 430, -1, -1, 433, 434, 435, 436, 437, - 438, 439, -1, 441, -1, 443, 444, 445, 446, -1, - -1, 449, -1, -1, 452, 453, 454, 455, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 471, 472, -1, 3, -1, 5, -1, + -1, 493, 19, 20, 21, 22, 23, 24, 25, 26, + -1, 28, 29, 30, -1, -1, -1, -1, -1, -1, + -1, 38, 39, -1, 41, 42, 43, -1, 45, 46, + 47, 48, 49, -1, 51, 52, -1, 54, 55, 56, + 57, 58, 59, -1, -1, 62, 63, 64, 65, 66, + -1, 68, 69, 70, 71, 72, -1, -1, -1, 76, + 77, 78, 79, 80, 81, -1, 83, 84, 85, -1, + 87, 88, 89, 90, 91, 92, -1, -1, 95, 96, + 97, -1, -1, -1, -1, -1, -1, -1, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, -1, 116, + -1, 118, 119, 120, 121, 122, 123, -1, 125, 126, + 127, 128, 129, -1, -1, 132, 133, 134, 135, 136, + -1, 138, 139, 140, -1, 142, 143, 144, -1, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, -1, + 157, -1, 159, 160, 161, 162, -1, 164, -1, 166, + -1, -1, -1, 170, 171, 172, -1, 174, -1, 176, + -1, 178, 179, 180, -1, 182, 183, 184, 185, 186, + 187, 188, -1, 190, 191, 192, 193, -1, 195, 196, + 197, 198, 199, 200, -1, 202, -1, 204, 205, 206, + 207, 208, 209, 210, 211, -1, 213, -1, 215, -1, + -1, 218, -1, 220, 221, 222, 223, 224, -1, -1, + 227, -1, 229, -1, -1, 232, 233, 234, -1, -1, + 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, -1, 263, 264, 265, 266, + 267, -1, 269, 270, -1, 272, -1, 274, 275, 276, + 277, 278, 279, -1, 281, 282, -1, -1, 285, 286, + 287, -1, -1, 290, 291, -1, 293, -1, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, -1, + 307, 308, 309, 310, 311, 312, 313, 314, 315, -1, + 317, 318, 319, 320, 321, 322, -1, 324, 325, 326, + 327, 328, 329, 330, 331, -1, 333, 334, 335, 336, + 337, 338, 339, 340, 341, 342, 343, 344, 345, -1, + 347, 348, -1, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, -1, 366, + 367, 368, 369, 370, -1, 372, 373, 374, 375, 376, + -1, 378, 379, 380, 381, -1, 383, 384, 385, 386, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, -1, 399, 400, -1, 402, -1, 404, 405, 406, + 407, 408, -1, 410, 411, -1, -1, 414, 415, 416, + 417, 418, -1, 420, 421, 422, 423, 424, 425, 426, + 427, -1, -1, 430, 431, 432, 433, 434, -1, -1, + 437, 438, 439, 440, 441, 442, 443, -1, 445, -1, + 447, 448, 449, 450, -1, -1, 453, -1, -1, 456, + 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, + 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, + -1, 3, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 493, 19, 20, 21, + 22, 23, 24, 25, 26, -1, 28, 29, 30, -1, + -1, -1, -1, -1, -1, -1, 38, 39, -1, 41, + 42, 43, -1, 45, 46, 47, 48, 49, -1, 51, + 52, -1, 54, 55, 56, 57, 58, 59, -1, -1, + 62, 63, 64, 65, 66, -1, 68, 69, 70, 71, + 72, -1, -1, -1, 76, 77, 78, 79, 80, 81, + -1, 83, 84, 85, -1, 87, 88, 89, 90, 91, + 92, -1, -1, 95, 96, 97, -1, -1, -1, -1, + -1, -1, -1, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, -1, 116, -1, 118, 119, 120, 121, + 122, 123, -1, 125, 126, 127, 128, 129, -1, -1, + 132, 133, 134, 135, 136, -1, 138, 139, 140, -1, + 142, 143, 144, -1, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, -1, 157, -1, 159, 160, 161, + 162, -1, 164, -1, 166, -1, -1, -1, 170, 171, + 172, -1, 174, -1, 176, -1, 178, 179, 180, -1, + 182, 183, 184, 185, 186, 187, 188, -1, 190, 191, + 192, 193, -1, 195, 196, 197, 198, 199, 200, -1, + 202, -1, 204, 205, 206, 207, 208, 209, 210, 211, + -1, 213, -1, 215, -1, -1, 218, -1, 220, 221, + 222, 223, 224, -1, -1, 227, -1, 229, -1, -1, + 232, 233, 234, -1, -1, 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, + -1, 263, 264, 265, 266, 267, -1, 269, 270, -1, + 272, -1, 274, 275, 276, 277, 278, 279, -1, 281, + 282, -1, -1, 285, 286, 287, -1, -1, 290, 291, + -1, 293, -1, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, -1, 307, 308, 309, 310, 311, + 312, 313, 314, 315, -1, 317, 318, 319, 320, 321, + 322, -1, 324, 325, 326, 327, 328, 329, 330, 331, + -1, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 343, 344, 345, -1, 347, 348, -1, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, -1, 366, 367, 368, 369, 370, -1, + 372, 373, 374, 375, 376, -1, 378, 379, 380, 381, + -1, 383, 384, 385, 386, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, -1, 399, 400, -1, + 402, -1, 404, 405, 406, 407, 408, -1, 410, 411, + -1, -1, 414, 415, 416, 417, 418, -1, 420, 421, + 422, 423, 424, 425, 426, 427, -1, -1, 430, 431, + 432, 433, 434, -1, -1, 437, 438, 439, 440, 441, + 442, 443, -1, 445, -1, 447, 448, 449, 450, -1, + -1, 453, -1, -1, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 473, 474, 475, 476, -1, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 489, 19, 20, 21, 22, 23, 24, 25, 26, + -1, 493, 19, 20, 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, 51, 52, -1, 54, 55, 56, @@ -226371,2564 +242383,267 @@ static const yytype_int16 yycheck[] = 157, -1, 159, 160, 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, 184, 185, 186, - 187, -1, 189, 190, 191, 192, -1, 194, 195, 196, - 197, 198, 199, -1, 201, -1, 203, 204, 205, 206, - 207, 208, 209, -1, 211, -1, 213, -1, -1, 216, - -1, 218, 219, 220, 221, 222, -1, -1, 225, -1, - 227, -1, -1, 230, 231, 232, -1, -1, 235, 236, + 187, 188, -1, 190, 191, 192, 193, -1, 195, 196, + 197, 198, 199, 200, -1, 202, -1, 204, 205, 206, + 207, 208, 209, 210, 211, -1, 213, -1, 215, -1, + -1, 218, -1, 220, 221, 222, 223, 224, -1, -1, + 227, -1, 229, -1, -1, 232, 233, 234, -1, -1, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, -1, 261, 262, 263, 264, 265, -1, - 267, 268, -1, 270, -1, 272, 273, 274, 275, 276, - 277, -1, 279, 280, -1, -1, 283, 284, 285, -1, - -1, 288, 289, -1, 291, -1, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, -1, 305, 306, - 307, 308, 309, 310, 311, 312, 313, -1, 315, 316, - 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, -1, 330, 331, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, -1, 343, 344, -1, 346, - 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, - 357, 358, 359, 360, -1, 362, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, -1, 374, 375, 376, - 377, -1, 379, 380, 381, 382, 383, 384, 385, 386, - 387, 388, 389, 390, 391, 392, 393, -1, 395, 396, - -1, 398, -1, 400, 401, 402, 403, 404, -1, 406, - 407, -1, -1, 410, 411, 412, 413, 414, -1, 416, - 417, 418, 419, 420, 421, 422, 423, -1, -1, 426, - 427, 428, 429, 430, -1, -1, 433, 434, 435, 436, - 437, 438, 439, -1, 441, -1, 443, 444, 445, 446, - -1, -1, 449, -1, -1, 452, 453, 454, 455, 456, + 257, 258, 259, 260, 261, -1, 263, 264, 265, 266, + 267, -1, 269, 270, -1, 272, -1, 274, 275, 276, + 277, 278, 279, -1, 281, 282, -1, -1, 285, 286, + 287, -1, -1, 290, 291, -1, 293, -1, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, -1, + 307, 308, 309, 310, 311, 312, 313, 314, 315, -1, + 317, 318, 319, 320, 321, 322, -1, 324, 325, 326, + 327, 328, 329, 330, 331, -1, 333, 334, 335, 336, + 337, 338, 339, 340, 341, 342, 343, 344, 345, -1, + 347, 348, -1, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, -1, 366, + 367, 368, 369, 370, -1, 372, 373, 374, 375, 376, + -1, 378, 379, 380, 381, -1, 383, 384, 385, 386, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, -1, 399, 400, -1, 402, -1, 404, 405, 406, + 407, 408, -1, 410, 411, -1, -1, 414, 415, 416, + 417, 418, -1, 420, 421, 422, 423, 424, 425, 426, + 427, -1, -1, 430, 431, 432, 433, 434, -1, -1, + 437, 438, 439, 440, 441, 442, 443, -1, 445, -1, + 447, 448, 449, 450, -1, -1, 453, -1, -1, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 469, 470, 471, 472, -1, 3, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 489, 19, 20, 21, 22, 23, 24, 25, - 26, -1, 28, 29, 30, -1, -1, -1, -1, -1, - -1, -1, 38, 39, -1, 41, 42, 43, -1, 45, - 46, 47, 48, 49, -1, 51, 52, -1, 54, 55, - 56, 57, 58, 59, -1, -1, 62, 63, 64, 65, - 66, -1, 68, 69, 70, 71, 72, -1, -1, -1, - 76, 77, 78, 79, 80, 81, -1, 83, 84, 85, - -1, 87, 88, 89, 90, 91, 92, -1, -1, 95, - 96, 97, -1, -1, -1, -1, -1, -1, -1, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, -1, - 116, -1, 118, 119, 120, 121, 122, 123, -1, 125, - 126, 127, 128, 129, -1, -1, 132, 133, 134, 135, - 136, -1, 138, 139, 140, -1, 142, 143, 144, -1, - 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, - -1, 157, -1, 159, 160, 161, 162, -1, 164, -1, - 166, -1, -1, -1, 170, 171, 172, -1, 174, -1, - 176, -1, 178, 179, 180, -1, 182, 183, 184, 185, - 186, 187, -1, 189, 190, 191, 192, -1, 194, 195, - 196, 197, 198, 199, -1, 201, -1, 203, 204, 205, - 206, 207, 208, 209, -1, 211, -1, 213, -1, -1, - 216, -1, 218, 219, 220, 221, 222, -1, -1, 225, - -1, 227, -1, -1, 230, 231, 232, -1, -1, 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, -1, 261, 262, 263, 264, 265, - -1, 267, 268, -1, 270, -1, 272, 273, 274, 275, - 276, 277, -1, 279, 280, -1, -1, 283, 284, 285, - -1, -1, 288, 289, -1, 291, -1, 293, 294, 295, - 296, 297, 298, 299, 300, 301, 302, 303, -1, 305, - 306, 307, 308, 309, 310, 311, 312, 313, -1, 315, - 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, - 326, 327, 328, -1, 330, 331, 332, 333, 334, 335, - 336, 337, 338, 339, 340, 341, -1, 343, 344, -1, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 357, 358, 359, 360, -1, 362, 363, 364, 365, - 366, -1, 368, 369, 370, 371, 372, -1, 374, 375, - 376, 377, -1, 379, 380, 381, 382, 383, 384, 385, - 386, 387, 388, 389, 390, 391, 392, 393, -1, 395, - 396, -1, 398, -1, 400, 401, 402, 403, 404, -1, - 406, 407, -1, -1, 410, 411, 412, 413, 414, -1, - 416, 417, 418, 419, 420, 421, 422, 423, -1, -1, - 426, 427, 428, 429, 430, -1, -1, 433, 434, 435, - 436, 437, 438, 439, -1, 441, -1, 443, 444, 445, - 446, -1, -1, 449, -1, -1, 452, 453, 454, 455, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, -1, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 489, 19, 20, 21, 22, 23, 24, - 25, 26, -1, 28, 29, 30, -1, -1, -1, -1, - -1, -1, -1, 38, 39, -1, 41, 42, 43, -1, - 45, 46, 47, 48, 49, -1, 51, 52, -1, 54, - 55, 56, 57, 58, 59, -1, -1, 62, 63, 64, - 65, 66, -1, 68, 69, 70, 71, 72, -1, -1, - -1, 76, 77, 78, 79, 80, 81, -1, 83, 84, - 85, -1, 87, 88, 89, 90, 91, 92, -1, -1, - 95, 96, 97, -1, -1, -1, -1, -1, -1, -1, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - -1, 116, -1, 118, 119, 120, 121, 122, 123, -1, - 125, 126, 127, 128, 129, -1, -1, 132, 133, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - -1, 146, 147, 148, 149, 150, 151, 152, 153, 154, - 155, -1, 157, -1, 159, 160, 161, 162, -1, 164, - -1, 166, -1, -1, -1, 170, 171, 172, -1, 174, - -1, 176, -1, 178, 179, 180, -1, 182, 183, 184, - 185, 186, 187, -1, 189, 190, 191, 192, -1, 194, - 195, 196, 197, 198, 199, -1, 201, -1, 203, 204, - 205, 206, 207, 208, 209, -1, 211, -1, 213, -1, - -1, 216, -1, 218, 219, 220, 221, 222, -1, -1, - 225, -1, 227, -1, -1, 230, 231, 232, -1, -1, - 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, -1, 261, 262, 263, 264, - 265, -1, 267, 268, -1, 270, -1, 272, 273, 274, - 275, 276, 277, -1, 279, 280, -1, -1, 283, 284, - 285, -1, -1, 288, 289, -1, 291, -1, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, -1, - 305, 306, 307, 308, 309, 310, 311, 312, 313, -1, - 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, -1, 330, 331, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, -1, 343, 344, - -1, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 359, 360, -1, 362, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, -1, 374, - 375, 376, 377, -1, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 388, 389, 390, 391, 392, 393, -1, - 395, 396, -1, 398, -1, 400, 401, 402, 403, 404, - -1, 406, 407, -1, -1, 410, 411, 412, 413, 414, - -1, 416, 417, 418, 419, 420, 421, 422, 423, -1, - -1, 426, 427, 428, 429, 430, -1, -1, 433, 434, - 435, 436, 437, 438, 439, -1, 441, -1, 443, 444, - 445, 446, -1, -1, 449, -1, -1, 452, 453, 454, - 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, - 465, 466, 467, 468, 469, 470, 471, 472, -1, 3, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 489, 19, 20, 21, 22, 23, - 24, 25, 26, -1, 28, 29, 30, -1, -1, -1, - -1, -1, -1, -1, 38, 39, -1, 41, 42, 43, - -1, 45, 46, 47, 48, 49, -1, 51, 52, -1, - 54, 55, 56, 57, 58, 59, -1, -1, 62, 63, - 64, 65, 66, -1, 68, 69, 70, 71, 72, -1, - -1, -1, 76, 77, 78, 79, 80, 81, -1, 83, - 84, 85, -1, 87, 88, 89, 90, 91, 92, -1, - -1, 95, 96, 97, -1, -1, -1, -1, -1, -1, - -1, 105, 106, 107, 108, 109, 110, 111, 112, 113, - 114, -1, 116, -1, 118, 119, 120, 121, 122, 123, - -1, 125, 126, 127, 128, 129, -1, -1, 132, 133, - 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, - 144, -1, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, -1, 157, -1, 159, 160, 161, 162, -1, - 164, -1, 166, -1, -1, -1, 170, 171, 172, -1, - 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, - 184, 185, 186, 187, -1, 189, 190, 191, 192, -1, - 194, 195, 196, 197, 198, 199, -1, 201, -1, 203, - 204, 205, 206, 207, 208, 209, -1, 211, -1, 213, - -1, -1, 216, -1, 218, 219, 220, 221, 222, -1, - -1, 225, -1, 227, -1, -1, 230, 231, 232, -1, - -1, 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, -1, 261, 262, 263, - 264, 265, -1, 267, 268, -1, 270, -1, 272, 273, - 274, 275, 276, 277, -1, 279, 280, -1, -1, 283, - 284, 285, -1, -1, 288, 289, -1, 291, -1, 293, - 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, - -1, 305, 306, 307, 308, 309, 310, 311, 312, 313, - -1, 315, 316, 317, 318, 319, 320, 321, 322, 323, - 324, 325, 326, 327, 328, -1, 330, 331, 332, 333, - 334, 335, 336, 337, 338, 339, 340, 341, -1, 343, - 344, -1, 346, 347, 348, 349, 350, 351, 352, 353, - 354, 355, 356, 357, 358, 359, 360, -1, 362, 363, - 364, 365, 366, -1, 368, 369, 370, 371, 372, -1, - 374, 375, 376, 377, -1, 379, 380, 381, 382, 383, - 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, - -1, 395, 396, -1, 398, -1, 400, 401, 402, 403, - 404, -1, 406, 407, -1, -1, 410, 411, 412, 413, - 414, -1, 416, 417, 418, 419, 420, 421, 422, 423, - -1, -1, 426, 427, 428, 429, 430, -1, -1, 433, - 434, 435, 436, 437, 438, 439, -1, 441, -1, 443, - 444, 445, 446, -1, -1, 449, -1, -1, 452, 453, - 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 471, 472, -1, - -1, -1, -1, 3, 4, 5, -1, -1, 8, 9, - -1, -1, -1, -1, -1, 489, 16, 17, 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, -1, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, -1, 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, - -1, 151, 152, 153, 154, -1, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - 170, 171, 172, 173, 174, 175, 176, 177, -1, -1, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, -1, 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, -1, 273, 274, 275, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, -1, - 290, 291, 292, -1, 294, 295, 296, 297, 298, 299, - 300, 301, 302, 303, 304, 305, 306, -1, 308, 309, - -1, 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, -1, 393, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 411, -1, 413, -1, 415, 416, 417, 418, 419, - 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, - 430, 431, 432, 433, 434, 435, 436, 437, -1, 439, - 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, - 450, 451, 452, 453, 454, 455, 456, 457, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 469, - 470, 471, 472, -1, 3, -1, 476, 477, 478, 8, - 480, 481, 482, 483, 484, 485, -1, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, -1, 28, - 29, 30, -1, -1, -1, -1, -1, -1, -1, 38, - 39, -1, 41, 42, 43, -1, 45, 46, 47, 48, - 49, -1, 51, 52, -1, 54, 55, 56, 57, 58, - 59, -1, -1, 62, 63, 64, 65, 66, -1, 68, - 69, 70, 71, 72, -1, -1, -1, 76, 77, 78, - 79, 80, 81, -1, 83, 84, 85, -1, 87, 88, - 89, 90, 91, 92, -1, -1, 95, 96, 97, -1, - -1, -1, -1, -1, -1, -1, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, -1, 116, -1, 118, - 119, 120, 121, 122, 123, -1, 125, 126, 127, 128, - 129, -1, -1, 132, 133, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, -1, 146, 147, 148, - 149, 150, 151, 152, 153, 154, 155, -1, 157, -1, - 159, 160, 161, 162, -1, 164, -1, 166, -1, -1, - -1, 170, 171, 172, -1, 174, -1, 176, -1, 178, - 179, 180, -1, 182, 183, 184, 185, 186, 187, -1, - 189, 190, 191, 192, -1, 194, 195, 196, 197, 198, - 199, -1, 201, -1, 203, 204, 205, 206, 207, 208, - 209, -1, 211, -1, 213, -1, -1, 216, -1, 218, - 219, 220, 221, 222, -1, -1, 225, -1, 227, -1, - -1, 230, 231, 232, -1, -1, 235, 236, 237, 238, + 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, + -1, -1, -1, -1, 3, 4, 5, -1, -1, 8, + 9, -1, -1, -1, -1, -1, 493, 16, 17, 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, -1, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, -1, 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, -1, 151, 152, 153, 154, -1, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, 177, -1, + -1, 180, 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, -1, 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, -1, 261, 262, 263, 264, 265, -1, 267, 268, - -1, 270, -1, 272, 273, 274, 275, 276, 277, -1, - 279, 280, -1, -1, 283, 284, 285, -1, -1, 288, - 289, -1, 291, -1, 293, 294, 295, 296, 297, 298, - 299, 300, 301, 302, 303, -1, 305, 306, 307, 308, - 309, 310, 311, 312, 313, -1, 315, 316, 317, 318, + 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, -1, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, -1, 292, 293, 294, -1, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + -1, 310, 311, -1, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - -1, 330, 331, 332, 333, 334, 335, 336, 337, 338, - 339, 340, 341, -1, 343, 344, -1, 346, 347, 348, + 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, -1, 362, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, -1, 374, 375, 376, 377, -1, + 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, -1, 395, 396, -1, 398, - -1, 400, 401, 402, 403, 404, -1, 406, 407, -1, - -1, 410, 411, 412, 413, 414, -1, 416, 417, 418, - 419, 420, 421, 422, 423, -1, -1, 426, 427, 428, - 429, 430, -1, -1, 433, 434, 435, 436, 437, 438, - 439, 21, 441, -1, 443, 444, 445, 446, -1, -1, - 449, -1, -1, 452, 453, 454, 455, 456, 457, 458, - 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, - 469, 470, 471, 472, -1, -1, -1, 476, 477, 478, - -1, 480, 481, 482, 483, 484, 485, 8, -1, -1, - 11, -1, -1, -1, 74, 16, 17, 18, -1, -1, - -1, -1, -1, -1, -1, 8, -1, -1, 11, -1, - 90, -1, 33, 16, 17, 18, -1, -1, -1, -1, - 41, -1, -1, 8, -1, -1, 11, 48, -1, -1, - 33, 16, 17, 18, -1, -1, -1, -1, 41, -1, - -1, -1, -1, -1, -1, 48, -1, -1, 33, -1, - -1, -1, 73, -1, -1, -1, 41, -1, -1, -1, - -1, -1, -1, 48, 144, -1, -1, -1, -1, -1, - 73, -1, -1, 153, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 165, -1, -1, 73, -1, - 170, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 196, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 173, -1, -1, -1, -1, -1, -1, 239, - -1, -1, -1, 243, -1, -1, -1, 188, -1, -1, - 173, -1, 193, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 188, -1, -1, 173, -1, - 193, -1, -1, 214, 215, -1, -1, -1, -1, -1, - -1, -1, -1, 188, -1, -1, -1, 228, 193, -1, - -1, 214, 215, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 228, 306, -1, -1, 214, - 215, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 320, -1, -1, 228, -1, 266, -1, -1, 269, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 283, 266, -1, 286, 269, -1, -1, -1, - -1, 351, -1, -1, 354, -1, -1, -1, -1, -1, - 283, 266, 362, 286, 269, 365, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 283, -1, - -1, 286, -1, -1, 384, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 397, -1, -1, - -1, -1, -1, -1, 404, -1, -1, -1, -1, -1, - -1, -1, -1, 413, -1, -1, -1, -1, -1, 419, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 373, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 444, -1, -1, -1, -1, -1, - 373, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 373, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 473, -1, -1, 476, 477, 478, -1, 480, - 481, 482, 483, 484, 485, -1, -1, -1, -1, 490, - 473, -1, -1, 476, 477, 478, -1, 480, 481, 482, - 483, 484, 485, -1, -1, -1, -1, 490, 473, 3, - -1, 476, 477, 478, -1, 480, 481, 482, 483, 484, - 485, -1, -1, 488, -1, 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, - -1, 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, -1, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, - -1, 95, 96, 97, 98, 99, 100, -1, 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, -1, 168, -1, 170, 171, 172, -1, - 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, - 184, 185, 186, 187, -1, 189, 190, 191, 192, 193, - 194, 195, 196, 197, 198, 199, 200, 201, -1, 203, - 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, - -1, -1, 216, -1, 218, 219, 220, 221, 222, 223, - 224, 225, -1, 227, -1, 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, -1, 261, 262, 263, - 264, 265, 266, 267, 268, -1, 270, 271, 272, 273, - 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, -1, 291, -1, 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, -1, 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, -1, - 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, -1, 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, -1, 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, 3, - -1, -1, -1, -1, -1, -1, -1, -1, 482, -1, - -1, -1, -1, -1, -1, 19, 20, 21, 22, 23, - 24, 25, 26, -1, 28, 29, 30, -1, -1, -1, - -1, -1, -1, -1, 38, 39, -1, 41, 42, 43, - -1, 45, 46, 47, 48, 49, -1, 51, 52, -1, - 54, 55, 56, 57, 58, 59, -1, -1, 62, 63, - 64, 65, 66, -1, 68, 69, 70, 71, 72, -1, - -1, -1, 76, 77, 78, 79, 80, 81, -1, 83, - 84, 85, -1, 87, 88, 89, 90, 91, 92, -1, - -1, 95, 96, 97, -1, -1, -1, -1, -1, -1, - -1, 105, 106, 107, 108, 109, 110, 111, 112, 113, - 114, -1, 116, -1, 118, 119, 120, 121, 122, 123, - -1, 125, 126, 127, 128, 129, -1, -1, 132, 133, - 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, - 144, -1, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, -1, 157, -1, 159, 160, 161, 162, -1, - 164, -1, 166, -1, -1, -1, 170, 171, 172, -1, - 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, - 184, 185, 186, 187, -1, 189, 190, 191, 192, -1, - 194, 195, 196, 197, 198, 199, -1, 201, -1, 203, - 204, 205, 206, 207, 208, 209, -1, 211, -1, 213, - -1, -1, 216, -1, 218, 219, 220, 221, 222, -1, - -1, 225, -1, 227, -1, -1, 230, 231, 232, -1, - -1, 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, -1, 261, 262, 263, - 264, 265, -1, 267, 268, -1, 270, -1, 272, 273, - 274, 275, 276, 277, -1, 279, 280, -1, -1, 283, - 284, 285, -1, -1, 288, 289, -1, 291, -1, 293, - 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, - -1, 305, 306, 307, 308, 309, 310, 311, 312, 313, - -1, 315, 316, 317, 318, 319, 320, 321, 322, 323, - 324, 325, 326, 327, 328, -1, 330, 331, 332, 333, - 334, 335, 336, 337, 338, 339, 340, 341, -1, 343, - 344, -1, 346, 347, 348, 349, 350, 351, 352, 353, - 354, 355, 356, 357, 358, 359, 360, -1, 362, 363, - 364, 365, 366, -1, 368, 369, 370, 371, 372, -1, - 374, 375, 376, 377, -1, 379, 380, 381, 382, 383, - 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, - -1, 395, 396, -1, 398, -1, 400, 401, 402, 403, - 404, -1, 406, 407, -1, -1, 410, 411, 412, 413, - 414, -1, 416, 417, 418, 419, 420, 421, 422, 423, - -1, -1, 426, 427, 428, 429, 430, -1, -1, 433, - 434, 435, 436, 437, 438, 439, -1, 441, -1, 443, - 444, 445, 446, -1, -1, 449, -1, -1, 452, 453, - 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 471, 472, 3, - 4, 5, -1, -1, -1, 9, -1, -1, 482, -1, - -1, -1, -1, -1, -1, 19, 20, 21, 22, 23, - 24, 25, 26, -1, 28, 29, 30, -1, -1, -1, - -1, -1, -1, -1, 38, 39, -1, 41, 42, 43, - -1, 45, 46, 47, 48, 49, -1, 51, 52, -1, - 54, 55, 56, 57, 58, 59, -1, -1, 62, 63, - 64, 65, 66, -1, 68, 69, 70, 71, 72, -1, - -1, -1, 76, 77, 78, 79, 80, 81, -1, 83, - 84, 85, -1, 87, 88, 89, 90, 91, 92, -1, - -1, 95, 96, 97, -1, -1, -1, -1, -1, -1, - -1, 105, 106, 107, 108, 109, 110, 111, 112, 113, - 114, 115, 116, -1, 118, 119, 120, 121, 122, 123, - -1, 125, 126, 127, 128, 129, -1, -1, 132, 133, - 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, - 144, -1, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, -1, 159, 160, 161, 162, -1, - 164, -1, 166, -1, -1, -1, 170, 171, 172, -1, - 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, - 184, 185, 186, 187, -1, 189, 190, 191, 192, -1, - 194, 195, 196, 197, 198, 199, -1, 201, -1, 203, - 204, 205, 206, 207, 208, 209, -1, 211, -1, 213, - -1, -1, 216, -1, 218, 219, 220, 221, 222, -1, - -1, 225, -1, 227, -1, -1, 230, 231, 232, -1, - -1, 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, -1, 261, 262, 263, - 264, 265, -1, 267, 268, -1, 270, -1, 272, 273, - 274, 275, 276, 277, -1, 279, 280, 281, -1, 283, - 284, 285, -1, -1, 288, 289, -1, 291, -1, 293, - 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, - -1, 305, 306, 307, 308, 309, 310, 311, 312, 313, - -1, 315, 316, 317, 318, 319, 320, 321, 322, 323, - 324, 325, 326, 327, 328, -1, 330, 331, 332, 333, - 334, 335, 336, 337, 338, 339, 340, 341, -1, 343, - 344, -1, 346, 347, 348, 349, 350, 351, 352, 353, - 354, 355, 356, 357, 358, 359, 360, -1, 362, 363, - 364, 365, 366, -1, 368, 369, 370, 371, 372, -1, - 374, 375, 376, 377, -1, 379, 380, 381, 382, 383, - 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, - -1, 395, 396, -1, 398, -1, 400, 401, 402, 403, - 404, -1, 406, 407, -1, -1, 410, 411, 412, 413, - 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, - -1, -1, 426, 427, 428, 429, 430, -1, -1, 433, - 434, 435, 436, 437, 438, 439, -1, 441, -1, 443, - 444, 445, 446, -1, -1, 449, -1, -1, 452, 453, - 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 471, 472, 3, - 4, 5, -1, -1, -1, 9, 480, 481, -1, -1, - -1, -1, -1, -1, -1, 19, 20, 21, 22, 23, - 24, 25, 26, -1, 28, 29, 30, -1, -1, -1, - -1, -1, -1, -1, 38, 39, -1, 41, 42, 43, - -1, 45, 46, 47, 48, 49, -1, 51, 52, -1, - 54, 55, 56, 57, 58, 59, -1, -1, 62, 63, - 64, 65, 66, -1, 68, 69, 70, 71, 72, -1, - -1, -1, 76, 77, 78, 79, 80, 81, -1, 83, - 84, 85, -1, 87, 88, 89, 90, 91, 92, -1, - -1, 95, 96, 97, -1, -1, -1, -1, -1, -1, - -1, 105, 106, 107, 108, 109, 110, 111, 112, 113, - 114, 115, 116, -1, 118, 119, 120, 121, 122, 123, - -1, 125, 126, 127, 128, 129, -1, -1, 132, 133, - 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, - 144, -1, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, -1, 159, 160, 161, 162, -1, - 164, -1, 166, -1, -1, -1, 170, 171, 172, -1, - 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, - 184, 185, 186, 187, -1, 189, 190, 191, 192, -1, - 194, 195, 196, 197, 198, 199, -1, 201, -1, 203, - 204, 205, 206, 207, 208, 209, -1, 211, -1, 213, - -1, -1, 216, -1, 218, 219, 220, 221, 222, -1, - -1, 225, -1, 227, -1, -1, 230, 231, 232, -1, - -1, 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, -1, 261, 262, 263, - 264, 265, -1, 267, 268, -1, 270, -1, 272, 273, - 274, 275, 276, 277, -1, 279, 280, 281, -1, 283, - 284, 285, -1, -1, 288, 289, -1, 291, -1, 293, - 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, - -1, 305, 306, 307, 308, 309, 310, 311, 312, 313, - -1, 315, 316, 317, 318, 319, 320, 321, 322, 323, - 324, 325, 326, 327, 328, -1, 330, 331, 332, 333, - 334, 335, 336, 337, 338, 339, 340, 341, -1, 343, - 344, -1, 346, 347, 348, 349, 350, 351, 352, 353, - 354, 355, 356, 357, 358, 359, 360, -1, 362, 363, - 364, 365, 366, -1, 368, 369, 370, 371, 372, -1, - 374, 375, 376, 377, -1, 379, 380, 381, 382, 383, - 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, - -1, 395, 396, -1, 398, -1, 400, 401, 402, 403, - 404, -1, 406, 407, -1, -1, 410, 411, 412, 413, - 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, - -1, -1, 426, 427, 428, 429, 430, -1, -1, 433, - 434, 435, 436, 437, 438, 439, -1, 441, -1, 443, - 444, 445, 446, -1, -1, 449, -1, -1, 452, 453, - 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 471, 472, 3, - 4, 5, -1, -1, -1, 9, 480, 481, -1, -1, - -1, -1, -1, -1, -1, 19, 20, 21, 22, 23, + 389, 390, 391, 392, 393, 394, 395, -1, 397, 398, + 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, + 409, 410, 411, 412, 413, 414, 415, -1, 417, -1, + 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, + 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, + 439, 440, 441, -1, 443, 444, 445, 446, 447, 448, + 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, + 459, 460, 461, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 473, 474, 475, 476, -1, 3, + -1, 480, 481, 482, 8, 484, 485, 486, 487, 488, + 489, -1, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, 41, 42, 43, - -1, 45, 46, 47, 48, 49, -1, 51, 52, -1, - 54, 55, 56, 57, 58, 59, -1, -1, 62, 63, - 64, 65, 66, -1, 68, 69, 70, 71, 72, -1, - -1, -1, 76, 77, 78, 79, 80, 81, -1, 83, - 84, 85, -1, 87, 88, 89, 90, 91, 92, -1, - -1, 95, 96, 97, -1, -1, -1, -1, -1, -1, - -1, 105, 106, 107, 108, 109, 110, 111, 112, 113, - 114, -1, 116, -1, 118, 119, 120, 121, 122, 123, - -1, 125, 126, 127, 128, 129, -1, -1, 132, 133, - 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, - 144, -1, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, -1, 159, 160, 161, 162, -1, - 164, -1, 166, -1, -1, -1, 170, 171, 172, -1, - 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, - 184, 185, 186, 187, -1, 189, 190, 191, 192, -1, - 194, 195, 196, 197, 198, 199, -1, 201, -1, 203, - 204, 205, 206, 207, 208, 209, -1, 211, -1, 213, - -1, -1, 216, -1, 218, 219, 220, 221, 222, -1, - -1, 225, -1, 227, -1, -1, 230, 231, 232, -1, - -1, 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, -1, 261, 262, 263, - 264, 265, -1, 267, 268, -1, 270, -1, 272, 273, - 274, 275, 276, 277, -1, 279, 280, 281, -1, 283, - 284, 285, -1, -1, 288, 289, -1, 291, -1, 293, - 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, - -1, 305, 306, 307, 308, 309, 310, 311, 312, 313, - -1, 315, 316, 317, 318, 319, 320, 321, 322, 323, - 324, 325, 326, 327, 328, -1, 330, 331, 332, 333, - 334, 335, 336, 337, 338, 339, 340, 341, -1, 343, - 344, -1, 346, 347, 348, 349, 350, 351, 352, 353, - 354, 355, 356, 357, 358, 359, 360, -1, 362, 363, - 364, 365, 366, -1, 368, 369, 370, 371, 372, -1, - 374, 375, 376, 377, -1, 379, 380, 381, 382, 383, - 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, - -1, 395, 396, -1, 398, -1, 400, 401, 402, 403, - 404, -1, 406, 407, -1, -1, 410, 411, 412, 413, - 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, - -1, -1, 426, 427, 428, 429, 430, -1, -1, 433, - 434, 435, 436, 437, 438, 439, -1, 441, -1, 443, - 444, 445, 446, -1, -1, 449, -1, -1, 452, 453, - 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 471, 472, -1, - 8, -1, -1, 11, -1, -1, 480, 481, 16, 17, - 18, -1, -1, -1, -1, -1, -1, -1, 8, -1, - -1, 11, -1, -1, -1, 33, 16, 17, 18, 37, - -1, -1, -1, 41, -1, -1, 8, -1, -1, 11, - 48, -1, -1, 33, 16, 17, 18, -1, -1, -1, - -1, 41, -1, -1, -1, -1, -1, -1, 48, -1, - -1, 33, -1, -1, 8, 73, -1, 11, -1, 41, - -1, -1, 16, 17, 18, -1, 48, -1, -1, -1, - -1, -1, -1, 73, -1, -1, -1, -1, -1, 33, - -1, -1, 36, -1, -1, -1, -1, 41, -1, -1, - -1, 73, -1, -1, 48, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 124, -1, -1, -1, - -1, -1, -1, -1, 8, -1, -1, 11, -1, 73, - -1, -1, 16, 17, 18, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, - -1, -1, -1, -1, -1, -1, -1, 41, -1, -1, - -1, -1, -1, -1, 48, 173, -1, -1, -1, -1, - -1, -1, -1, 163, -1, -1, -1, -1, 168, -1, - 188, -1, -1, 173, -1, 193, -1, -1, -1, 73, - 162, -1, -1, -1, -1, -1, -1, -1, 188, -1, - -1, 173, -1, 193, -1, -1, 214, 215, -1, -1, - -1, -1, -1, -1, -1, -1, 188, -1, -1, -1, - 228, 193, -1, -1, 214, 215, -1, -1, -1, 173, - -1, -1, -1, -1, -1, -1, -1, -1, 228, -1, - -1, -1, 214, 215, 188, -1, -1, -1, -1, 193, - -1, -1, -1, -1, -1, -1, 228, -1, 266, -1, - -1, 269, -1, -1, -1, -1, -1, -1, -1, -1, - 214, 215, -1, -1, -1, 283, 266, -1, 286, 269, - -1, -1, -1, -1, 228, -1, -1, -1, -1, 173, - -1, -1, -1, 283, 266, -1, 286, 269, -1, -1, - -1, -1, -1, -1, 188, -1, -1, -1, -1, 193, - -1, 283, -1, -1, 286, -1, -1, -1, -1, -1, - -1, -1, 266, -1, -1, 269, -1, -1, -1, -1, - 214, 215, -1, -1, -1, -1, -1, 309, -1, 283, - -1, -1, 286, -1, 228, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 8, -1, 373, 11, -1, -1, -1, - -1, 16, 17, 18, -1, -1, -1, -1, -1, -1, - -1, -1, 266, 373, -1, 269, -1, -1, 33, -1, - -1, 36, -1, -1, -1, -1, 41, 8, -1, 283, - 11, 373, 286, 48, -1, 16, 17, 18, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 304, -1, 33, -1, 432, -1, -1, -1, 73, 373, - 41, -1, -1, -1, -1, -1, -1, 48, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 73, -1, -1, 473, -1, -1, 476, 477, - 478, -1, 480, 481, 482, 483, 484, 485, -1, -1, - -1, -1, -1, 473, -1, -1, 476, 477, 478, 373, - 480, 481, 482, 483, 484, 485, -1, -1, -1, -1, - -1, 473, -1, -1, 476, 477, 478, -1, 480, 481, - 482, 483, 484, 485, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 173, 473, - -1, -1, 476, 477, 478, -1, 480, 481, 482, 483, - 484, 485, -1, 188, -1, -1, 8, -1, 193, 11, - -1, -1, -1, -1, 16, 17, 18, 168, -1, -1, - -1, -1, 173, -1, -1, -1, -1, -1, -1, 214, - 215, 33, -1, -1, 36, -1, -1, 188, -1, 41, - -1, -1, 193, 228, -1, -1, 48, -1, -1, 473, - -1, -1, 476, 477, 478, -1, 480, 481, 482, 483, - 484, 485, -1, 214, 215, -1, -1, -1, -1, -1, - -1, 73, -1, -1, -1, -1, -1, 228, -1, -1, - -1, 266, -1, -1, 269, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 8, 283, -1, - 11, 286, -1, -1, -1, 16, 17, 18, -1, -1, - -1, -1, -1, -1, -1, 266, -1, -1, 269, -1, - -1, -1, 33, -1, -1, -1, -1, -1, -1, -1, - 41, -1, 283, -1, -1, 286, 8, 48, -1, 11, - -1, -1, -1, -1, 16, 17, 18, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 33, 73, -1, 36, -1, -1, -1, -1, 41, - -1, 173, -1, -1, -1, -1, 48, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 188, -1, 373, -1, - -1, 193, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 73, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 8, 214, 215, 11, -1, -1, -1, -1, 16, - 17, 18, 373, -1, -1, -1, 228, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 33, -1, -1, -1, - -1, -1, -1, -1, 41, -1, -1, -1, -1, -1, - 8, 48, -1, 11, -1, -1, -1, -1, 16, 17, - 18, -1, 173, -1, 266, -1, -1, 269, -1, -1, - -1, -1, -1, -1, -1, -1, 73, 188, -1, -1, - -1, 283, 193, 41, 286, -1, -1, -1, 473, -1, - 48, 476, 477, 478, -1, 480, 481, 482, 483, 484, - 485, 173, -1, 214, 215, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 73, 188, 228, -1, -1, - -1, 193, 473, -1, -1, 476, 477, 478, -1, 480, - 481, 482, 483, 484, 485, -1, -1, -1, -1, -1, - -1, -1, 214, 215, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 266, 228, -1, 269, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 373, 283, -1, -1, 286, 173, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 188, -1, -1, 266, -1, 193, 269, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 283, -1, -1, 286, 173, -1, 214, 215, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 188, 228, -1, -1, -1, 193, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 214, 215, -1, -1, - -1, -1, 373, -1, -1, -1, -1, -1, -1, 266, - 228, 473, 269, -1, 476, 477, 478, -1, 480, 481, - 482, 483, 484, 485, -1, -1, 283, -1, -1, 286, - -1, -1, -1, -1, 405, -1, -1, -1, -1, -1, - -1, 373, -1, -1, -1, -1, -1, -1, 266, -1, - -1, 269, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 283, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 473, -1, -1, 476, 477, 478, -1, 480, - 481, 482, 483, 484, 485, -1, 373, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 473, -1, -1, 476, 477, 478, -1, 480, 481, - 482, 483, 484, 485, -1, 373, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 473, -1, -1, 476, - 477, 478, -1, 480, 481, 482, 483, 484, 485, -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, 473, -1, -1, 476, 477, - 478, -1, 480, 481, 482, 483, 484, 485, 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, -1, 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, -1, 83, 84, 85, 86, 87, 88, 89, 90, - 91, 92, 93, -1, 95, 96, 97, 98, 99, 100, - -1, 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, -1, 168, -1, 170, - 171, 172, -1, 174, 175, 176, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 201, -1, 203, 204, 205, 206, 207, 208, 209, 210, - 211, 212, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, 223, 224, 225, -1, 227, -1, 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, -1, - 261, 262, 263, 264, 265, 266, 267, 268, -1, 270, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, -1, - 291, -1, 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, -1, 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, -1, 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, -1, 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, -1, 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, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 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, -1, 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, -1, 83, 84, 85, 86, 87, 88, 89, 90, - 91, 92, 93, -1, 95, 96, 97, 98, 99, 100, - -1, 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, -1, 168, -1, 170, - 171, 172, -1, 174, 175, 176, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 201, -1, 203, 204, 205, 206, 207, 208, 209, 210, - 211, 212, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, 223, 224, 225, -1, 227, -1, 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, -1, - 261, 262, 263, 264, 265, 266, 267, 268, -1, 270, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, -1, - 291, -1, 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, -1, 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, -1, 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, -1, 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, -1, 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, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 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, -1, 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, -1, 83, 84, 85, 86, 87, 88, 89, 90, - 91, 92, 93, -1, 95, 96, 97, 98, 99, 100, - -1, 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, -1, 168, -1, 170, - 171, 172, -1, 174, 175, 176, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 201, -1, 203, 204, 205, 206, 207, 208, 209, 210, - 211, 212, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, 223, 224, 225, -1, 227, -1, 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, -1, - 261, 262, 263, 264, 265, 266, 267, 268, -1, 270, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, -1, - 291, -1, 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, -1, 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, -1, 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, -1, 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, -1, 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, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - 61, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, 74, -1, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, 167, -1, 169, 170, - 171, 172, 173, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, 188, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, 202, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, 214, 215, 216, 217, 218, 219, 220, - 221, 222, -1, -1, 225, 226, 227, 228, -1, 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, -1, 267, 268, 269, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, 290, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, 345, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, 367, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, 399, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - 431, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, 442, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, 74, -1, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, 94, 95, 96, 97, -1, -1, -1, - 101, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, 167, -1, 169, 170, - 171, 172, 173, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, 188, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, 202, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, 214, 215, 216, 217, 218, 219, 220, - 221, 222, -1, -1, 225, 226, 227, 228, -1, 230, - 231, 232, -1, -1, 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, -1, 267, 268, 269, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, 290, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, 345, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, 399, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, 442, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, -1, -1, 75, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, 86, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, 165, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, 425, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, 86, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, 165, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, 228, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, 425, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, 5, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, 156, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - 281, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, 5, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - 31, 32, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, 5, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, 282, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, 5, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, 282, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - 31, 32, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, 5, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, 397, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, 4, -1, -1, -1, -1, 9, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, 5, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, 5, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, 5, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, 5, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, 5, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, 5, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, 5, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, 36, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, 36, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, 5, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, 36, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, -1, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, 72, -1, -1, -1, 76, 77, 78, 79, 80, - 81, -1, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, - 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, + -1, 45, 46, 47, 48, 49, -1, 51, 52, -1, + 54, 55, 56, 57, 58, 59, -1, -1, 62, 63, + 64, 65, 66, -1, 68, 69, 70, 71, 72, -1, + -1, -1, 76, 77, 78, 79, 80, 81, -1, 83, + 84, 85, -1, 87, 88, 89, 90, 91, 92, -1, + -1, 95, 96, 97, -1, -1, -1, -1, -1, -1, + -1, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, -1, 116, -1, 118, 119, 120, 121, 122, 123, + -1, 125, 126, 127, 128, 129, -1, -1, 132, 133, + 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, + 144, -1, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, -1, 157, -1, 159, 160, 161, 162, -1, + 164, -1, 166, -1, -1, -1, 170, 171, 172, -1, + 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, + 184, 185, 186, 187, 188, -1, 190, 191, 192, 193, + -1, 195, 196, 197, 198, 199, 200, -1, 202, -1, + 204, 205, 206, 207, 208, 209, 210, 211, -1, 213, + -1, 215, -1, -1, 218, -1, 220, 221, 222, 223, + 224, -1, -1, 227, -1, 229, -1, -1, 232, 233, + 234, -1, -1, 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, -1, 263, + 264, 265, 266, 267, -1, 269, 270, -1, 272, -1, + 274, 275, 276, 277, 278, 279, -1, 281, 282, -1, + -1, 285, 286, 287, -1, -1, 290, 291, -1, 293, + -1, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, -1, 307, 308, 309, 310, 311, 312, 313, + 314, 315, -1, 317, 318, 319, 320, 321, 322, -1, + 324, 325, 326, 327, 328, 329, 330, 331, -1, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, + 344, 345, -1, 347, 348, -1, 350, 351, 352, 353, + 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, + 364, -1, 366, 367, 368, 369, 370, -1, 372, 373, + 374, 375, 376, -1, 378, 379, 380, 381, -1, 383, + 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, -1, 399, 400, -1, 402, -1, + 404, 405, 406, 407, 408, -1, 410, 411, -1, -1, + 414, 415, 416, 417, 418, -1, 420, 421, 422, 423, + 424, 425, 426, 427, -1, -1, 430, 431, 432, 433, + 434, -1, -1, 437, 438, 439, 440, 441, 442, 443, + -1, 445, -1, 447, 448, 449, 450, -1, -1, 453, + -1, -1, 456, 457, 458, 459, 460, 461, 462, 463, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, + 474, 475, 476, -1, -1, -1, 480, 481, 482, -1, + 484, 485, 486, 487, 488, 489, 8, -1, -1, 11, + -1, -1, -1, -1, 16, 17, 18, -1, -1, -1, + -1, -1, -1, -1, 8, -1, -1, 11, -1, -1, + -1, 33, 16, 17, 18, -1, -1, -1, -1, 41, + -1, -1, -1, -1, -1, -1, 48, -1, -1, 33, + -1, -1, -1, 8, -1, -1, 11, 41, -1, -1, + -1, 16, 17, 18, 48, -1, -1, -1, -1, -1, + -1, 73, 8, -1, -1, 11, -1, -1, 33, -1, + 16, 17, 18, -1, -1, -1, 41, -1, -1, 73, + -1, -1, -1, 48, -1, -1, -1, 33, -1, -1, + -1, -1, -1, -1, -1, 41, -1, -1, -1, -1, + -1, -1, 48, -1, -1, -1, -1, -1, 73, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 73, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 8, -1, -1, 11, -1, + -1, -1, -1, 16, 17, 18, -1, -1, -1, -1, + -1, 173, -1, 8, -1, -1, 11, -1, -1, -1, + 33, 16, 17, 18, -1, -1, -1, 189, 41, 173, + -1, -1, 194, -1, -1, 48, -1, -1, 33, -1, + -1, -1, -1, -1, -1, 189, 41, -1, -1, -1, + 194, -1, -1, 48, 216, 217, -1, -1, 173, -1, + 73, -1, -1, -1, -1, -1, -1, -1, 230, -1, + -1, -1, 216, 217, 189, -1, -1, 173, 73, 194, + -1, -1, -1, -1, -1, -1, 230, -1, -1, -1, + -1, -1, -1, 189, -1, -1, -1, -1, 194, -1, + -1, 216, 217, -1, -1, -1, 268, -1, -1, 271, + -1, -1, -1, -1, -1, 230, -1, -1, -1, -1, + 216, 217, -1, 285, 268, -1, 288, 271, -1, -1, + -1, -1, -1, -1, 230, -1, -1, -1, -1, -1, + -1, 285, -1, -1, 288, -1, -1, -1, -1, -1, + -1, -1, -1, 268, -1, -1, 271, -1, -1, -1, + 173, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 285, -1, 268, 288, -1, 271, 189, -1, 173, -1, + -1, 194, -1, -1, -1, -1, -1, -1, -1, 285, + -1, -1, 288, -1, 189, -1, -1, -1, -1, 194, + -1, -1, -1, 216, 217, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 377, -1, 230, -1, -1, + -1, 216, 217, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 377, -1, 230, -1, -1, 8, -1, + -1, 11, -1, -1, -1, -1, 16, 17, 18, -1, + -1, -1, -1, -1, -1, 268, -1, -1, 271, -1, + -1, -1, 377, 33, -1, -1, -1, -1, -1, -1, + -1, 41, 285, 268, -1, 288, 271, -1, 48, -1, + -1, 377, -1, -1, -1, -1, -1, -1, -1, -1, + 285, -1, -1, 288, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 73, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 477, -1, -1, 480, 481, + 482, -1, 484, 485, 486, 487, 488, 489, -1, -1, + -1, -1, 494, 477, -1, -1, 480, 481, 482, -1, + 484, 485, 486, 487, 488, 489, -1, -1, -1, -1, + 494, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 477, -1, 377, 480, 481, 482, -1, 484, + 485, 486, 487, 488, 489, -1, -1, -1, -1, 494, + -1, 477, 377, -1, 480, 481, 482, -1, 484, 485, + 486, 487, 488, 489, -1, -1, -1, -1, 494, -1, + -1, -1, -1, 173, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 189, + -1, -1, -1, -1, 194, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 216, 217, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 230, -1, -1, -1, 477, -1, -1, 480, 481, 482, + -1, 484, 485, 486, 487, 488, 489, -1, -1, -1, + -1, 494, 477, -1, -1, 480, 481, 482, -1, 484, + 485, 486, 487, 488, 489, -1, -1, -1, 268, 494, + -1, 271, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 285, -1, -1, 288, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 377, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 477, 3, -1, + 480, 481, 482, -1, 484, 485, 486, 487, 488, 489, + -1, -1, 492, -1, 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, -1, + 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, -1, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, -1, + 95, 96, 97, 98, 99, 100, -1, 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, -1, 168, -1, 170, 171, 172, -1, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, -1, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, -1, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, -1, -1, 218, -1, 220, 221, 222, 223, 224, + 225, 226, 227, -1, 229, -1, 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, -1, 263, 264, + 265, 266, 267, 268, 269, 270, -1, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, -1, 293, -1, + 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, -1, 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, -1, 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, 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, -1, 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, 3, -1, -1, -1, -1, -1, -1, -1, + -1, 486, -1, -1, -1, -1, -1, -1, 19, 20, 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, 41, 42, 43, -1, 45, 46, 47, 48, 49, -1, @@ -228945,128 +242660,2460 @@ static const yytype_int16 yycheck[] = 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, 161, 162, -1, 164, -1, 166, -1, -1, -1, 170, 171, 172, -1, 174, -1, 176, -1, 178, 179, 180, - -1, 182, 183, 184, 185, 186, 187, -1, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, -1, 203, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, -1, -1, 216, -1, 218, 219, 220, - 221, 222, -1, -1, 225, -1, 227, -1, -1, 230, - 231, 232, -1, -1, 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, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, 270, - -1, 272, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, 289, -1, - 291, -1, 293, 294, 295, 296, 297, 298, 299, -1, - 301, 302, 303, -1, 305, 306, 307, 308, 309, 310, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, -1, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, -1, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, -1, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, -1, 395, 396, -1, 398, -1, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, 412, 413, 414, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, 438, 439, -1, - 441, -1, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - 41, 42, 43, 44, 45, 46, 47, -1, 49, 50, - 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, - -1, 62, 63, 64, 65, 66, -1, 68, 69, 70, - 71, -1, -1, 74, -1, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 85, -1, 87, 88, 89, 90, - 91, 92, -1, 94, 95, 96, 97, -1, -1, -1, - 101, -1, -1, -1, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, - 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, - -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, -1, 146, 147, 148, 149, -1, - 151, 152, 153, 154, -1, -1, 157, -1, 159, 160, - 161, 162, -1, 164, -1, 166, 167, -1, 169, 170, - 171, 172, 173, 174, -1, 176, -1, -1, -1, 180, - -1, 182, 183, 184, 185, 186, 187, 188, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, 202, -1, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, 214, 215, 216, 217, 218, 219, 220, - 221, 222, -1, -1, 225, 226, 227, 228, -1, 230, - 231, 232, -1, -1, 235, 236, 237, 238, 239, 240, + -1, 182, 183, 184, 185, 186, 187, 188, -1, 190, + 191, 192, 193, -1, 195, 196, 197, 198, 199, 200, + -1, 202, -1, 204, 205, 206, 207, 208, 209, 210, + 211, -1, 213, -1, 215, -1, -1, 218, -1, 220, + 221, 222, 223, 224, -1, -1, 227, -1, 229, -1, + -1, 232, 233, 234, -1, -1, 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, -1, -1, 267, 268, 269, 270, - -1, -1, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, -1, 290, - 291, 292, -1, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, -1, 308, 309, -1, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, 345, 346, 347, 348, 349, 350, + 261, -1, 263, 264, 265, 266, 267, -1, 269, 270, + -1, 272, -1, 274, 275, 276, 277, 278, 279, -1, + 281, 282, -1, -1, 285, 286, 287, -1, -1, 290, + 291, -1, 293, -1, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 305, -1, 307, 308, 309, 310, + 311, 312, 313, 314, 315, -1, 317, 318, 319, 320, + 321, 322, -1, 324, 325, 326, 327, 328, 329, 330, + 331, -1, 333, 334, 335, 336, 337, 338, 339, 340, + 341, 342, 343, 344, 345, -1, 347, 348, -1, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, -1, 393, -1, 395, 396, -1, 398, 399, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, -1, 413, -1, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, -1, 439, -1, - 441, 442, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 3, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 469, 470, - 471, 472, -1, 19, 20, 21, 22, 23, 24, 25, + 361, 362, 363, 364, -1, 366, 367, 368, 369, 370, + -1, 372, 373, 374, 375, 376, -1, 378, 379, 380, + 381, -1, 383, 384, 385, 386, 387, 388, 389, 390, + 391, 392, 393, 394, 395, 396, 397, -1, 399, 400, + -1, 402, -1, 404, 405, 406, 407, 408, -1, 410, + 411, -1, -1, 414, 415, 416, 417, 418, -1, 420, + 421, 422, 423, 424, 425, 426, 427, -1, -1, 430, + 431, 432, 433, 434, -1, -1, 437, 438, 439, 440, + 441, 442, 443, -1, 445, -1, 447, 448, 449, 450, + -1, -1, 453, -1, -1, 456, 457, 458, 459, 460, + 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, + 471, 472, 473, 474, 475, 476, 3, 4, 5, -1, + -1, -1, 9, -1, -1, 486, -1, -1, -1, -1, + -1, -1, 19, 20, 21, 22, 23, 24, 25, 26, + -1, 28, 29, 30, -1, -1, -1, -1, -1, -1, + -1, 38, 39, -1, 41, 42, 43, -1, 45, 46, + 47, 48, 49, -1, 51, 52, -1, 54, 55, 56, + 57, 58, 59, -1, -1, 62, 63, 64, 65, 66, + -1, 68, 69, 70, 71, 72, -1, -1, -1, 76, + 77, 78, 79, 80, 81, -1, 83, 84, 85, -1, + 87, 88, 89, 90, 91, 92, -1, -1, 95, 96, + 97, -1, -1, -1, -1, -1, -1, -1, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + -1, 118, 119, 120, 121, 122, 123, -1, 125, 126, + 127, 128, 129, -1, -1, 132, 133, 134, 135, 136, + -1, 138, 139, 140, -1, 142, 143, 144, -1, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, -1, 159, 160, 161, 162, -1, 164, -1, 166, + -1, -1, -1, 170, 171, 172, -1, 174, -1, 176, + -1, 178, 179, 180, -1, 182, 183, 184, 185, 186, + 187, 188, -1, 190, 191, 192, 193, -1, 195, 196, + 197, 198, 199, 200, -1, 202, -1, 204, 205, 206, + 207, 208, 209, 210, 211, -1, 213, -1, 215, -1, + -1, 218, -1, 220, 221, 222, 223, 224, -1, -1, + 227, -1, 229, -1, -1, 232, 233, 234, -1, -1, + 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, -1, 263, 264, 265, 266, + 267, -1, 269, 270, -1, 272, -1, 274, 275, 276, + 277, 278, 279, -1, 281, 282, 283, -1, 285, 286, + 287, -1, -1, 290, 291, -1, 293, -1, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, -1, + 307, 308, 309, 310, 311, 312, 313, 314, 315, -1, + 317, 318, 319, 320, 321, 322, -1, 324, 325, 326, + 327, 328, 329, 330, 331, -1, 333, 334, 335, 336, + 337, 338, 339, 340, 341, 342, 343, 344, 345, -1, + 347, 348, -1, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, -1, 366, + 367, 368, 369, 370, -1, 372, 373, 374, 375, 376, + -1, 378, 379, 380, 381, -1, 383, 384, 385, 386, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, -1, 399, 400, -1, 402, -1, 404, 405, 406, + 407, 408, -1, 410, 411, -1, -1, 414, 415, 416, + 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, + 427, -1, -1, 430, 431, 432, 433, 434, -1, -1, + 437, 438, 439, 440, 441, 442, 443, -1, 445, -1, + 447, 448, 449, 450, -1, -1, 453, -1, -1, 456, + 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, + 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, + 3, 4, 5, -1, -1, -1, 9, 484, 485, -1, + -1, -1, -1, -1, -1, -1, 19, 20, 21, 22, + 23, 24, 25, 26, -1, 28, 29, 30, -1, -1, + -1, -1, -1, -1, -1, 38, 39, -1, 41, 42, + 43, -1, 45, 46, 47, 48, 49, -1, 51, 52, + -1, 54, 55, 56, 57, 58, 59, -1, -1, 62, + 63, 64, 65, 66, -1, 68, 69, 70, 71, 72, + -1, -1, -1, 76, 77, 78, 79, 80, 81, -1, + 83, 84, 85, -1, 87, 88, 89, 90, 91, 92, + -1, -1, 95, 96, 97, -1, -1, -1, -1, -1, + -1, -1, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, -1, 118, 119, 120, 121, 122, + 123, -1, 125, 126, 127, 128, 129, -1, -1, 132, + 133, 134, 135, 136, -1, 138, 139, 140, -1, 142, + 143, 144, -1, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, -1, 159, 160, 161, 162, + -1, 164, -1, 166, -1, -1, -1, 170, 171, 172, + -1, 174, -1, 176, -1, 178, 179, 180, -1, 182, + 183, 184, 185, 186, 187, 188, -1, 190, 191, 192, + 193, -1, 195, 196, 197, 198, 199, 200, -1, 202, + -1, 204, 205, 206, 207, 208, 209, 210, 211, -1, + 213, -1, 215, -1, -1, 218, -1, 220, 221, 222, + 223, 224, -1, -1, 227, -1, 229, -1, -1, 232, + 233, 234, -1, -1, 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, -1, + 263, 264, 265, 266, 267, -1, 269, 270, -1, 272, + -1, 274, 275, 276, 277, 278, 279, -1, 281, 282, + 283, -1, 285, 286, 287, -1, -1, 290, 291, -1, + 293, -1, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, -1, 307, 308, 309, 310, 311, 312, + 313, 314, 315, -1, 317, 318, 319, 320, 321, 322, + -1, 324, 325, 326, 327, 328, 329, 330, 331, -1, + 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, + 343, 344, 345, -1, 347, 348, -1, 350, 351, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, -1, 366, 367, 368, 369, 370, -1, 372, + 373, 374, 375, 376, -1, 378, 379, 380, 381, -1, + 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, -1, 399, 400, -1, 402, + -1, 404, 405, 406, 407, 408, -1, 410, 411, -1, + -1, 414, 415, 416, 417, 418, 419, 420, 421, 422, + 423, 424, 425, 426, 427, -1, -1, 430, 431, 432, + 433, 434, -1, -1, 437, 438, 439, 440, 441, 442, + 443, -1, 445, -1, 447, 448, 449, 450, -1, -1, + 453, -1, -1, 456, 457, 458, 459, 460, 461, 462, + 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, + 473, 474, 475, 476, 3, 4, 5, -1, -1, -1, + 9, 484, 485, -1, -1, -1, -1, -1, -1, -1, + 19, 20, 21, 22, 23, 24, 25, 26, -1, 28, + 29, 30, -1, -1, -1, -1, -1, -1, -1, 38, + 39, -1, 41, 42, 43, -1, 45, 46, 47, 48, + 49, -1, 51, 52, -1, 54, 55, 56, 57, 58, + 59, -1, -1, 62, 63, 64, 65, 66, -1, 68, + 69, 70, 71, 72, -1, -1, -1, 76, 77, 78, + 79, 80, 81, -1, 83, 84, 85, -1, 87, 88, + 89, 90, 91, 92, -1, -1, 95, 96, 97, -1, + -1, -1, -1, -1, -1, -1, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, -1, 116, -1, 118, + 119, 120, 121, 122, 123, -1, 125, 126, 127, 128, + 129, -1, -1, 132, 133, 134, 135, 136, -1, 138, + 139, 140, -1, 142, 143, 144, -1, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, -1, + 159, 160, 161, 162, -1, 164, -1, 166, -1, -1, + -1, 170, 171, 172, -1, 174, -1, 176, -1, 178, + 179, 180, -1, 182, 183, 184, 185, 186, 187, 188, + -1, 190, 191, 192, 193, -1, 195, 196, 197, 198, + 199, 200, -1, 202, -1, 204, 205, 206, 207, 208, + 209, 210, 211, -1, 213, -1, 215, -1, -1, 218, + -1, 220, 221, 222, 223, 224, -1, -1, 227, -1, + 229, -1, -1, 232, 233, 234, -1, -1, 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, -1, 263, 264, 265, 266, 267, -1, + 269, 270, -1, 272, -1, 274, 275, 276, 277, 278, + 279, -1, 281, 282, 283, -1, 285, 286, 287, -1, + -1, 290, 291, -1, 293, -1, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, -1, 307, 308, + 309, 310, 311, 312, 313, 314, 315, -1, 317, 318, + 319, 320, 321, 322, -1, 324, 325, 326, 327, 328, + 329, 330, 331, -1, 333, 334, 335, 336, 337, 338, + 339, 340, 341, 342, 343, 344, 345, -1, 347, 348, + -1, 350, 351, 352, 353, 354, 355, 356, 357, 358, + 359, 360, 361, 362, 363, 364, -1, 366, 367, 368, + 369, 370, -1, 372, 373, 374, 375, 376, -1, 378, + 379, 380, 381, -1, 383, 384, 385, 386, 387, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, -1, + 399, 400, -1, 402, -1, 404, 405, 406, 407, 408, + -1, 410, 411, -1, -1, 414, 415, 416, 417, 418, + 419, 420, 421, 422, 423, 424, 425, 426, 427, -1, + -1, 430, 431, 432, 433, 434, -1, -1, 437, 438, + 439, 440, 441, 442, 443, -1, 445, -1, 447, 448, + 449, 450, -1, -1, 453, -1, -1, 456, 457, 458, + 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, + 469, 470, 471, 472, 473, 474, 475, 476, -1, 8, + -1, -1, 11, -1, -1, 484, 485, 16, 17, 18, + -1, -1, -1, -1, -1, -1, -1, 8, -1, -1, + 11, -1, -1, -1, 33, 16, 17, 18, 37, -1, + -1, -1, 41, -1, -1, -1, -1, -1, -1, 48, + -1, -1, 33, -1, -1, -1, 8, -1, -1, 11, + 41, -1, -1, -1, 16, 17, 18, 48, -1, -1, + -1, -1, -1, -1, 73, 8, -1, -1, 11, -1, + -1, 33, -1, 16, 17, 18, -1, -1, -1, 41, + -1, -1, 73, -1, -1, -1, 48, -1, -1, -1, + 33, -1, -1, 36, -1, -1, -1, -1, 41, -1, + -1, -1, -1, -1, -1, 48, -1, -1, -1, -1, + -1, 73, -1, -1, -1, 124, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 73, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 8, -1, + -1, 11, -1, -1, -1, -1, 16, 17, 18, -1, + -1, -1, -1, -1, 173, -1, -1, -1, -1, -1, + -1, -1, 163, 33, -1, -1, -1, 168, -1, -1, + 189, 41, 173, -1, -1, 194, -1, -1, 48, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 189, -1, + 162, -1, -1, 194, -1, -1, -1, 216, 217, -1, + -1, 173, -1, 73, -1, -1, -1, -1, -1, -1, + -1, 230, -1, -1, -1, 216, 217, 189, -1, -1, + 173, -1, 194, -1, -1, -1, -1, -1, -1, 230, + -1, -1, -1, -1, -1, -1, 189, -1, -1, -1, + -1, 194, -1, -1, 216, 217, -1, -1, -1, 268, + -1, -1, 271, -1, -1, -1, -1, -1, 230, -1, + -1, -1, -1, 216, 217, -1, 285, 268, -1, 288, + 271, -1, -1, -1, -1, -1, -1, 230, -1, -1, + -1, -1, -1, -1, 285, -1, -1, 288, -1, -1, + -1, -1, -1, -1, -1, -1, 268, -1, -1, 271, + -1, -1, -1, 173, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 285, -1, 268, 288, 8, 271, 189, + 11, -1, -1, -1, 194, 16, 17, 18, -1, -1, + -1, -1, 285, -1, -1, 288, -1, -1, -1, 311, + -1, -1, 33, -1, -1, 36, 216, 217, -1, -1, + 41, -1, -1, -1, -1, -1, -1, 48, 377, -1, + 230, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 377, -1, -1, -1, + -1, 8, 73, -1, 11, -1, -1, -1, -1, 16, + 17, 18, -1, -1, -1, -1, -1, -1, 268, -1, + -1, 271, -1, -1, -1, 377, 33, -1, -1, -1, + -1, -1, -1, -1, 41, 285, -1, 436, 288, -1, + -1, 48, -1, -1, 377, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 306, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 73, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 477, -1, + -1, 480, 481, 482, -1, 484, 485, 486, 487, 488, + 489, -1, -1, -1, -1, -1, 477, -1, -1, 480, + 481, 482, 173, 484, 485, 486, 487, 488, 489, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 189, -1, + -1, -1, -1, 194, -1, 477, -1, 377, 480, 481, + 482, -1, 484, 485, 486, 487, 488, 489, -1, -1, + -1, -1, -1, -1, 477, 216, 217, 480, 481, 482, + -1, 484, 485, 486, 487, 488, 489, -1, -1, 230, + -1, 168, -1, -1, -1, -1, 173, -1, 8, -1, + -1, 11, -1, -1, -1, -1, 16, 17, 18, -1, + -1, -1, 189, -1, -1, -1, -1, 194, -1, -1, + -1, -1, -1, 33, -1, -1, 36, 268, -1, -1, + 271, 41, -1, -1, -1, -1, -1, -1, 48, 216, + 217, -1, -1, -1, 285, -1, -1, 288, -1, -1, + -1, -1, -1, 230, -1, -1, -1, 477, -1, -1, + 480, 481, 482, 73, 484, 485, 486, 487, 488, 489, + -1, -1, -1, 8, -1, -1, 11, -1, -1, -1, + -1, 16, 17, 18, -1, -1, -1, -1, -1, -1, + -1, 268, -1, -1, 271, -1, -1, -1, 33, -1, + -1, 36, -1, -1, -1, -1, 41, -1, 285, -1, + -1, 288, 8, 48, -1, 11, -1, -1, -1, -1, + 16, 17, 18, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 377, 33, 73, -1, + -1, -1, -1, -1, -1, 41, -1, -1, -1, -1, + -1, -1, 48, -1, -1, -1, -1, 8, -1, -1, + 11, -1, -1, 173, -1, 16, 17, 18, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 73, -1, 189, + -1, -1, 33, -1, 194, -1, -1, -1, -1, -1, + 41, -1, -1, -1, -1, -1, -1, 48, -1, -1, + 377, -1, -1, -1, -1, -1, 216, 217, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 230, -1, 73, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 477, -1, 173, 480, + 481, 482, -1, 484, 485, 486, 487, 488, 489, -1, + -1, -1, -1, -1, 189, -1, -1, -1, 268, 194, + -1, 271, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 285, -1, 173, 288, -1, + -1, 216, 217, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 189, -1, 230, -1, -1, 194, -1, + 477, -1, -1, 480, 481, 482, -1, 484, 485, 486, + 487, 488, 489, -1, -1, -1, -1, -1, -1, -1, + 216, 217, 173, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 268, 230, -1, 271, -1, 189, -1, + -1, -1, -1, 194, -1, -1, -1, -1, -1, -1, + 285, 8, -1, 288, 11, -1, -1, -1, -1, 16, + 17, 18, -1, -1, -1, 216, 217, 377, -1, -1, + -1, -1, 268, -1, -1, 271, 33, -1, -1, 230, + -1, -1, -1, -1, 41, -1, -1, -1, -1, 285, + 8, 48, 288, 11, -1, -1, -1, -1, 16, 17, + 18, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 33, 73, 268, -1, -1, + 271, -1, -1, 41, -1, -1, -1, -1, -1, -1, + 48, -1, -1, -1, 285, -1, -1, 288, -1, -1, + -1, -1, 377, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 73, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 477, -1, -1, + 480, 481, 482, -1, 484, 485, 486, 487, 488, 489, + -1, 377, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 8, -1, -1, 11, -1, -1, -1, -1, 16, + 17, 18, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 409, -1, -1, 173, -1, -1, -1, + -1, -1, -1, -1, 41, -1, 377, -1, -1, -1, + -1, 48, 189, -1, -1, -1, -1, 194, -1, -1, + -1, -1, 477, -1, -1, 480, 481, 482, -1, 484, + 485, 486, 487, 488, 489, 173, 73, -1, -1, 216, + 217, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 189, -1, 230, -1, -1, 194, -1, -1, -1, + -1, 477, -1, -1, 480, 481, 482, -1, 484, 485, + 486, 487, 488, 489, -1, -1, -1, -1, 216, 217, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 268, 230, -1, 271, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 477, -1, 285, 480, + 481, 482, -1, 484, 485, 486, 487, 488, 489, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 268, -1, -1, 271, -1, -1, 173, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 285, -1, -1, + 288, -1, 189, -1, -1, -1, -1, 194, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 216, + 217, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 230, -1, -1, -1, -1, -1, -1, + 377, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 268, -1, -1, 271, -1, -1, -1, -1, 377, + -1, -1, -1, -1, -1, -1, -1, -1, 285, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 477, -1, -1, 480, 481, 482, -1, 484, 485, 486, + 487, 488, 489, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 477, + 377, -1, 480, 481, 482, -1, 484, 485, 486, 487, + 488, 489, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -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, + 477, -1, -1, 480, 481, 482, -1, 484, 485, 486, + 487, 488, 489, 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, -1, 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, -1, 83, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 93, -1, 95, + 96, 97, 98, 99, 100, -1, 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, -1, 168, -1, 170, 171, 172, -1, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, + 186, 187, 188, -1, 190, 191, 192, 193, 194, 195, + 196, 197, 198, 199, 200, 201, 202, -1, 204, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, + -1, -1, 218, -1, 220, 221, 222, 223, 224, 225, + 226, 227, -1, 229, -1, 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, -1, 263, 264, 265, + 266, 267, 268, 269, 270, -1, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, + 286, 287, 288, 289, 290, 291, -1, 293, -1, 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, -1, 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, -1, 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, + 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, + -1, 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, 3, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 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, -1, 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, + -1, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, -1, 95, 96, 97, 98, 99, 100, -1, + 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, -1, 168, -1, 170, 171, + 172, -1, 174, 175, 176, 177, 178, 179, 180, 181, + 182, 183, 184, 185, 186, 187, 188, -1, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, + 202, -1, 204, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, -1, -1, 218, -1, 220, 221, + 222, 223, 224, 225, 226, 227, -1, 229, -1, 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, + -1, 263, 264, 265, 266, 267, 268, 269, 270, -1, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, + -1, 293, -1, 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, -1, 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, -1, 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, 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, -1, 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, 3, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 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, -1, 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, -1, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, -1, 95, 96, 97, + 98, 99, 100, -1, 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, -1, + 168, -1, 170, 171, 172, -1, 174, 175, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, + 188, -1, 190, 191, 192, 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, -1, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, -1, -1, + 218, -1, 220, 221, 222, 223, 224, 225, 226, 227, + -1, 229, -1, 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, -1, 263, 264, 265, 266, 267, + 268, 269, 270, -1, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 288, 289, 290, 291, -1, 293, -1, 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, -1, 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, -1, + 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, 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, -1, 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, 3, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 19, 20, 21, 22, 23, + 24, 25, 26, -1, 28, 29, 30, -1, -1, -1, + -1, -1, -1, -1, 38, 39, -1, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, -1, + 54, 55, 56, 57, 58, 59, -1, 61, 62, 63, + 64, 65, 66, -1, 68, 69, 70, 71, 72, -1, + 74, -1, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, -1, 87, 88, 89, 90, 91, 92, -1, + 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, -1, 116, -1, 118, 119, 120, 121, 122, 123, + -1, 125, 126, 127, 128, 129, -1, -1, 132, 133, + 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, + 144, -1, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, -1, 157, -1, 159, 160, 161, 162, -1, + 164, -1, 166, 167, -1, 169, 170, 171, 172, 173, + 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, + -1, 195, 196, 197, 198, 199, 200, -1, 202, 203, + 204, 205, 206, 207, 208, 209, 210, 211, -1, 213, + -1, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, -1, -1, 227, 228, 229, 230, -1, 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, -1, 269, 270, 271, 272, -1, + 274, 275, 276, 277, 278, 279, -1, 281, 282, -1, + -1, 285, 286, 287, -1, -1, 290, 291, 292, 293, + 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, -1, 307, 308, 309, 310, 311, 312, 313, + 314, 315, -1, 317, 318, 319, 320, 321, 322, -1, + 324, 325, 326, 327, 328, 329, 330, 331, -1, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, + 344, 345, -1, 347, 348, 349, 350, 351, 352, 353, + 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, + 364, -1, 366, 367, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 379, 380, 381, -1, 383, + 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, -1, 399, 400, -1, 402, 403, + 404, 405, 406, 407, 408, -1, 410, 411, -1, -1, + 414, 415, 416, 417, 418, -1, 420, 421, 422, 423, + 424, 425, 426, 427, -1, -1, 430, 431, 432, 433, + 434, 435, -1, 437, 438, 439, 440, 441, 442, 443, + -1, 445, 446, 447, 448, 449, 450, -1, -1, 453, + -1, -1, 456, 457, 458, 459, 460, 461, 462, 463, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, + 474, 475, 476, 3, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, + 20, 21, 22, 23, 24, 25, 26, -1, 28, 29, + 30, -1, -1, -1, -1, -1, -1, -1, 38, 39, + -1, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, -1, 54, 55, 56, 57, 58, 59, + -1, -1, 62, 63, 64, 65, 66, -1, 68, 69, + 70, 71, 72, -1, 74, -1, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, -1, 87, 88, 89, + 90, 91, 92, -1, 94, 95, 96, 97, -1, -1, + -1, 101, -1, -1, -1, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, -1, 116, -1, 118, 119, + 120, 121, 122, 123, -1, 125, 126, 127, 128, 129, + -1, -1, 132, 133, 134, 135, 136, -1, 138, 139, + 140, -1, 142, 143, 144, -1, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, -1, 157, -1, 159, + 160, 161, 162, -1, 164, -1, 166, 167, -1, 169, + 170, 171, 172, 173, 174, -1, 176, -1, 178, 179, + 180, -1, 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 192, 193, -1, 195, 196, 197, 198, 199, + 200, -1, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, -1, 213, -1, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, -1, -1, 227, 228, 229, + 230, -1, 232, 233, 234, -1, -1, 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, -1, 269, + 270, 271, 272, -1, 274, 275, 276, 277, 278, 279, + -1, 281, 282, -1, -1, 285, 286, 287, -1, -1, + 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, -1, 307, 308, 309, + 310, 311, 312, 313, 314, 315, -1, 317, 318, 319, + 320, 321, 322, -1, 324, 325, 326, 327, 328, 329, + 330, 331, -1, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 343, 344, 345, -1, 347, 348, 349, + 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, + 360, 361, 362, 363, 364, -1, 366, 367, 368, 369, + 370, -1, 372, 373, 374, 375, 376, 377, 378, 379, + 380, 381, -1, 383, 384, 385, 386, 387, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, -1, 399, + 400, -1, 402, 403, 404, 405, 406, 407, 408, -1, + 410, 411, -1, -1, 414, 415, 416, 417, 418, -1, + 420, 421, 422, 423, 424, 425, 426, 427, -1, -1, + 430, 431, 432, 433, 434, -1, -1, 437, 438, 439, + 440, 441, 442, 443, -1, 445, 446, 447, 448, 449, + 450, -1, -1, 453, -1, -1, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 473, 474, 475, 476, 3, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 19, 20, 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, -1, -1, -1, -1, -1, - -1, -1, 38, 39, -1, 41, 42, 43, 44, 45, - 46, 47, -1, 49, 50, 51, 52, -1, 54, 55, + -1, -1, 38, 39, -1, 41, 42, 43, -1, 45, + 46, 47, 48, 49, -1, 51, 52, -1, 54, 55, 56, 57, 58, 59, -1, -1, 62, 63, 64, 65, - 66, -1, 68, 69, 70, 71, -1, -1, 74, -1, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - -1, 87, 88, 89, 90, 91, 92, -1, 94, 95, - 96, 97, -1, -1, -1, 101, -1, -1, -1, 105, + 66, 67, 68, 69, 70, 71, 72, -1, -1, 75, + 76, 77, 78, 79, 80, 81, -1, 83, 84, 85, + 86, 87, 88, 89, 90, 91, 92, -1, -1, 95, + 96, 97, -1, -1, -1, -1, -1, -1, -1, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, -1, + 116, -1, 118, 119, 120, 121, 122, 123, -1, 125, + 126, 127, 128, 129, -1, -1, 132, 133, 134, 135, + 136, -1, 138, 139, 140, -1, 142, 143, 144, -1, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, + -1, 157, -1, 159, 160, 161, 162, -1, 164, 165, + 166, -1, -1, -1, 170, 171, 172, -1, 174, -1, + 176, -1, 178, 179, 180, -1, 182, 183, 184, 185, + 186, 187, 188, -1, 190, 191, 192, 193, -1, 195, + 196, 197, 198, 199, 200, -1, 202, -1, 204, 205, + 206, 207, 208, 209, 210, 211, -1, 213, -1, 215, + -1, -1, 218, -1, 220, 221, 222, 223, 224, -1, + -1, 227, -1, 229, -1, -1, 232, 233, 234, -1, + -1, 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, -1, 263, 264, 265, + 266, 267, -1, 269, 270, -1, 272, -1, 274, 275, + 276, 277, 278, 279, -1, 281, 282, -1, -1, 285, + 286, 287, -1, -1, 290, 291, -1, 293, -1, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + -1, 307, 308, 309, 310, 311, 312, 313, 314, 315, + 316, 317, 318, 319, 320, 321, 322, -1, 324, 325, + 326, 327, 328, 329, 330, 331, -1, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, + -1, 347, 348, -1, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 361, 362, 363, 364, -1, + 366, 367, 368, 369, 370, -1, 372, 373, 374, 375, + 376, -1, 378, 379, 380, 381, -1, 383, 384, 385, + 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, -1, 399, 400, -1, 402, -1, 404, 405, + 406, 407, 408, -1, 410, 411, -1, -1, 414, 415, + 416, 417, 418, -1, 420, 421, 422, 423, 424, 425, + 426, 427, -1, 429, 430, 431, 432, 433, 434, -1, + -1, 437, 438, 439, 440, 441, 442, 443, -1, 445, + -1, 447, 448, 449, 450, -1, -1, 453, -1, -1, + 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, + 476, 3, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 19, 20, 21, + 22, 23, 24, 25, 26, -1, 28, 29, 30, -1, + -1, -1, -1, -1, -1, -1, 38, 39, -1, 41, + 42, 43, -1, 45, 46, 47, 48, 49, -1, 51, + 52, -1, 54, 55, 56, 57, 58, 59, -1, -1, + 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, -1, -1, -1, 76, 77, 78, 79, 80, 81, + -1, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, -1, -1, 95, 96, 97, -1, -1, -1, -1, + -1, -1, -1, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, -1, 116, -1, 118, 119, 120, 121, + 122, 123, -1, 125, 126, 127, 128, 129, -1, -1, + 132, 133, 134, 135, 136, -1, 138, 139, 140, -1, + 142, 143, 144, -1, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, -1, 157, -1, 159, 160, 161, + 162, -1, 164, 165, 166, -1, -1, -1, 170, 171, + 172, -1, 174, -1, 176, -1, 178, 179, 180, -1, + 182, 183, 184, 185, 186, 187, 188, -1, 190, 191, + 192, 193, -1, 195, 196, 197, 198, 199, 200, -1, + 202, -1, 204, 205, 206, 207, 208, 209, 210, 211, + -1, 213, -1, 215, -1, -1, 218, -1, 220, 221, + 222, 223, 224, -1, -1, 227, -1, 229, 230, -1, + 232, 233, 234, -1, -1, 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, + -1, 263, 264, 265, 266, 267, -1, 269, 270, -1, + 272, -1, 274, 275, 276, 277, 278, 279, -1, 281, + 282, -1, -1, 285, 286, 287, -1, -1, 290, 291, + -1, 293, -1, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, -1, 307, 308, 309, 310, 311, + 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, + 322, -1, 324, 325, 326, 327, 328, 329, 330, 331, + -1, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 343, 344, 345, -1, 347, 348, -1, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, -1, 366, 367, 368, 369, 370, -1, + 372, 373, 374, 375, 376, -1, 378, 379, 380, 381, + -1, 383, 384, 385, 386, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, -1, 399, 400, -1, + 402, -1, 404, 405, 406, 407, 408, -1, 410, 411, + -1, -1, 414, 415, 416, 417, 418, -1, 420, 421, + 422, 423, 424, 425, 426, 427, -1, 429, 430, 431, + 432, 433, 434, -1, -1, 437, 438, 439, 440, 441, + 442, 443, -1, 445, -1, 447, 448, 449, 450, -1, + -1, 453, -1, -1, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 473, 474, 475, 476, 3, -1, 5, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 19, 20, 21, 22, 23, 24, 25, 26, -1, + 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, + 38, 39, -1, 41, 42, 43, -1, 45, 46, 47, + 48, 49, -1, 51, 52, -1, 54, 55, 56, 57, + 58, 59, -1, -1, 62, 63, 64, 65, 66, -1, + 68, 69, 70, 71, 72, -1, -1, -1, 76, 77, + 78, 79, 80, 81, -1, 83, 84, 85, -1, 87, + 88, 89, 90, 91, 92, -1, -1, 95, 96, 97, + -1, -1, -1, -1, -1, -1, -1, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, -1, 116, -1, + 118, 119, 120, 121, 122, 123, -1, 125, 126, 127, + 128, 129, -1, -1, 132, 133, 134, 135, 136, -1, + 138, 139, 140, -1, 142, 143, 144, -1, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + -1, 159, 160, 161, 162, -1, 164, -1, 166, -1, + -1, -1, 170, 171, 172, -1, 174, -1, 176, -1, + 178, 179, 180, -1, 182, 183, 184, 185, 186, 187, + 188, -1, 190, 191, 192, 193, -1, 195, 196, 197, + 198, 199, 200, -1, 202, -1, 204, 205, 206, 207, + 208, 209, 210, 211, -1, 213, -1, 215, -1, -1, + 218, -1, 220, 221, 222, 223, 224, -1, -1, 227, + -1, 229, -1, -1, 232, 233, 234, -1, -1, 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, -1, 263, 264, 265, 266, 267, + -1, 269, 270, -1, 272, -1, 274, 275, 276, 277, + 278, 279, -1, 281, 282, 283, -1, 285, 286, 287, + -1, -1, 290, 291, -1, 293, -1, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, -1, 307, + 308, 309, 310, 311, 312, 313, 314, 315, -1, 317, + 318, 319, 320, 321, 322, -1, 324, 325, 326, 327, + 328, 329, 330, 331, -1, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 343, 344, 345, -1, 347, + 348, -1, 350, 351, 352, 353, 354, 355, 356, 357, + 358, 359, 360, 361, 362, 363, 364, -1, 366, 367, + 368, 369, 370, -1, 372, 373, 374, 375, 376, -1, + 378, 379, 380, 381, -1, 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + -1, 399, 400, -1, 402, -1, 404, 405, 406, 407, + 408, -1, 410, 411, -1, -1, 414, 415, 416, 417, + 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, + -1, -1, 430, 431, 432, 433, 434, -1, -1, 437, + 438, 439, 440, 441, 442, 443, -1, 445, -1, 447, + 448, 449, 450, -1, -1, 453, -1, -1, 456, 457, + 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 473, 474, 475, 476, 3, + -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 19, 20, 21, 22, 23, + 24, 25, 26, -1, 28, 29, 30, 31, 32, -1, + -1, -1, -1, -1, 38, 39, -1, 41, 42, 43, + -1, 45, 46, 47, 48, 49, -1, 51, 52, -1, + 54, 55, 56, 57, 58, 59, -1, -1, 62, 63, + 64, 65, 66, -1, 68, 69, 70, 71, 72, -1, + -1, -1, 76, 77, 78, 79, 80, 81, -1, 83, + 84, 85, -1, 87, 88, 89, 90, 91, 92, -1, + -1, 95, 96, 97, -1, -1, -1, -1, -1, -1, + -1, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, -1, 116, -1, 118, 119, 120, 121, 122, 123, + -1, 125, 126, 127, 128, 129, -1, -1, 132, 133, + 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, + 144, -1, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, -1, 157, -1, 159, 160, 161, 162, -1, + 164, -1, 166, -1, -1, -1, 170, 171, 172, -1, + 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, + 184, 185, 186, 187, 188, -1, 190, 191, 192, 193, + -1, 195, 196, 197, 198, 199, 200, -1, 202, -1, + 204, 205, 206, 207, 208, 209, 210, 211, -1, 213, + -1, 215, -1, -1, 218, -1, 220, 221, 222, 223, + 224, -1, -1, 227, -1, 229, -1, -1, 232, 233, + 234, -1, -1, 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, -1, 263, + 264, 265, 266, 267, -1, 269, 270, -1, 272, -1, + 274, 275, 276, 277, 278, 279, -1, 281, 282, -1, + -1, 285, 286, 287, -1, -1, 290, 291, -1, 293, + -1, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, -1, 307, 308, 309, 310, 311, 312, 313, + 314, 315, -1, 317, 318, 319, 320, 321, 322, -1, + 324, 325, 326, 327, 328, 329, 330, 331, -1, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, + 344, 345, -1, 347, 348, -1, 350, 351, 352, 353, + 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, + 364, -1, 366, 367, 368, 369, 370, -1, 372, 373, + 374, 375, 376, -1, 378, 379, 380, 381, -1, 383, + 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, -1, 399, 400, -1, 402, -1, + 404, 405, 406, 407, 408, -1, 410, 411, -1, -1, + 414, 415, 416, 417, 418, -1, 420, 421, 422, 423, + 424, 425, 426, 427, -1, -1, 430, 431, 432, 433, + 434, -1, -1, 437, 438, 439, 440, 441, 442, 443, + -1, 445, -1, 447, 448, 449, 450, -1, -1, 453, + -1, -1, 456, 457, 458, 459, 460, 461, 462, 463, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, + 474, 475, 476, 3, -1, 5, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, + 20, 21, 22, 23, 24, 25, 26, -1, 28, 29, + 30, -1, -1, -1, -1, -1, -1, -1, 38, 39, + -1, 41, 42, 43, -1, 45, 46, 47, 48, 49, + -1, 51, 52, -1, 54, 55, 56, 57, 58, 59, + -1, -1, 62, 63, 64, 65, 66, -1, 68, 69, + 70, 71, 72, -1, -1, -1, 76, 77, 78, 79, + 80, 81, -1, 83, 84, 85, -1, 87, 88, 89, + 90, 91, 92, -1, -1, 95, 96, 97, -1, -1, + -1, -1, -1, -1, -1, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, -1, 116, -1, 118, 119, + 120, 121, 122, 123, -1, 125, 126, 127, 128, 129, + -1, -1, 132, 133, 134, 135, 136, -1, 138, 139, + 140, -1, 142, 143, 144, -1, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, -1, 157, -1, 159, + 160, 161, 162, -1, 164, -1, 166, -1, -1, -1, + 170, 171, 172, -1, 174, -1, 176, -1, 178, 179, + 180, -1, 182, 183, 184, 185, 186, 187, 188, -1, + 190, 191, 192, 193, -1, 195, 196, 197, 198, 199, + 200, -1, 202, -1, 204, 205, 206, 207, 208, 209, + 210, 211, -1, 213, -1, 215, -1, -1, 218, -1, + 220, 221, 222, 223, 224, -1, -1, 227, -1, 229, + -1, -1, 232, 233, 234, -1, -1, 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, -1, 263, 264, 265, 266, 267, -1, 269, + 270, -1, 272, -1, 274, 275, 276, 277, 278, 279, + -1, 281, 282, -1, 284, 285, 286, 287, -1, -1, + 290, 291, -1, 293, -1, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, -1, 307, 308, 309, + 310, 311, 312, 313, 314, 315, -1, 317, 318, 319, + 320, 321, 322, -1, 324, 325, 326, 327, 328, 329, + 330, 331, -1, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 343, 344, 345, -1, 347, 348, -1, + 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, + 360, 361, 362, 363, 364, -1, 366, 367, 368, 369, + 370, -1, 372, 373, 374, 375, 376, -1, 378, 379, + 380, 381, -1, 383, 384, 385, 386, 387, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, -1, 399, + 400, -1, 402, -1, 404, 405, 406, 407, 408, -1, + 410, 411, -1, -1, 414, 415, 416, 417, 418, -1, + 420, 421, 422, 423, 424, 425, 426, 427, -1, -1, + 430, 431, 432, 433, 434, -1, -1, 437, 438, 439, + 440, 441, 442, 443, -1, 445, -1, 447, 448, 449, + 450, -1, -1, 453, -1, -1, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 473, 474, 475, 476, 3, -1, 5, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 19, 20, 21, 22, 23, 24, 25, + 26, -1, 28, 29, 30, -1, -1, -1, -1, -1, + -1, -1, 38, 39, -1, 41, 42, 43, -1, 45, + 46, 47, 48, 49, -1, 51, 52, -1, 54, 55, + 56, 57, 58, 59, -1, -1, 62, 63, 64, 65, + 66, -1, 68, 69, 70, 71, 72, -1, -1, -1, + 76, 77, 78, 79, 80, 81, -1, 83, 84, 85, + -1, 87, 88, 89, 90, 91, 92, -1, -1, 95, + 96, 97, -1, -1, -1, -1, -1, -1, -1, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, -1, 116, -1, 118, 119, 120, 121, 122, 123, -1, 125, 126, 127, 128, 129, -1, -1, 132, 133, 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, -1, - 146, 147, 148, 149, -1, 151, 152, 153, 154, -1, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, -1, 157, -1, 159, 160, 161, 162, -1, 164, -1, - 166, 167, -1, 169, 170, 171, 172, 173, 174, -1, - 176, -1, -1, -1, 180, -1, 182, 183, 184, 185, - 186, 187, 188, 189, 190, 191, 192, -1, 194, 195, - 196, 197, 198, 199, -1, 201, 202, -1, 204, 205, - 206, 207, 208, 209, -1, 211, -1, 213, 214, 215, - 216, 217, 218, 219, 220, 221, 222, -1, -1, 225, - 226, 227, 228, -1, 230, 231, 232, -1, -1, 235, - 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, + 166, -1, -1, -1, 170, 171, 172, -1, 174, -1, + 176, -1, 178, 179, 180, -1, 182, 183, 184, 185, + 186, 187, 188, -1, 190, 191, 192, 193, -1, 195, + 196, 197, 198, 199, 200, -1, 202, -1, 204, 205, + 206, 207, 208, 209, 210, 211, -1, 213, -1, 215, + -1, -1, 218, -1, 220, 221, 222, 223, 224, -1, + -1, 227, -1, 229, -1, -1, 232, 233, 234, -1, + -1, 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, -1, - -1, 267, 268, 269, 270, -1, -1, 273, 274, 275, - 276, 277, -1, 279, 280, -1, -1, 283, 284, 285, - -1, -1, 288, -1, 290, 291, 292, -1, 294, 295, - 296, 297, 298, 299, 300, 301, 302, 303, -1, 305, - 306, -1, 308, 309, -1, 311, 312, 313, -1, 315, - 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, - 326, 327, 328, -1, 330, 331, 332, 333, 334, 335, - 336, 337, 338, 339, 340, 341, -1, 343, 344, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 357, 358, 359, 360, -1, 362, 363, 364, 365, - 366, -1, 368, 369, 370, 371, 372, 373, 374, 375, - 376, 377, -1, 379, 380, 381, 382, 383, 384, 385, - 386, 387, 388, 389, 390, 391, -1, 393, -1, 395, - 396, -1, 398, 399, 400, 401, 402, 403, 404, -1, - 406, 407, -1, -1, 410, 411, -1, 413, -1, -1, - 416, 417, 418, 419, 420, 421, 422, 423, -1, -1, - 426, 427, 428, 429, 430, -1, -1, 433, 434, 435, - 436, 437, -1, 439, -1, 441, 442, 443, 444, 445, - 446, -1, -1, 449, -1, -1, 452, 453, 454, 455, - 456, 457, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 469, 470, 471, 472, -1, 19, 20, + 256, 257, 258, 259, 260, 261, -1, 263, 264, 265, + 266, 267, -1, 269, 270, -1, 272, -1, 274, 275, + 276, 277, 278, 279, -1, 281, 282, -1, 284, 285, + 286, 287, -1, -1, 290, 291, -1, 293, -1, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + -1, 307, 308, 309, 310, 311, 312, 313, 314, 315, + -1, 317, 318, 319, 320, 321, 322, -1, 324, 325, + 326, 327, 328, 329, 330, 331, -1, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, + -1, 347, 348, -1, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 361, 362, 363, 364, -1, + 366, 367, 368, 369, 370, -1, 372, 373, 374, 375, + 376, -1, 378, 379, 380, 381, -1, 383, 384, 385, + 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, -1, 399, 400, -1, 402, -1, 404, 405, + 406, 407, 408, -1, 410, 411, -1, -1, 414, 415, + 416, 417, 418, -1, 420, 421, 422, 423, 424, 425, + 426, 427, -1, -1, 430, 431, 432, 433, 434, -1, + -1, 437, 438, 439, 440, 441, 442, 443, -1, 445, + -1, 447, 448, 449, 450, -1, -1, 453, -1, -1, + 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, + 476, 3, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 19, 20, 21, + 22, 23, 24, 25, 26, -1, 28, 29, 30, 31, + 32, -1, -1, -1, -1, -1, 38, 39, -1, 41, + 42, 43, -1, 45, 46, 47, 48, 49, -1, 51, + 52, -1, 54, 55, 56, 57, 58, 59, -1, -1, + 62, 63, 64, 65, 66, -1, 68, 69, 70, 71, + 72, -1, -1, -1, 76, 77, 78, 79, 80, 81, + -1, 83, 84, 85, -1, 87, 88, 89, 90, 91, + 92, -1, -1, 95, 96, 97, -1, -1, -1, -1, + -1, -1, -1, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, -1, 116, -1, 118, 119, 120, 121, + 122, 123, -1, 125, 126, 127, 128, 129, -1, -1, + 132, 133, 134, 135, 136, -1, 138, 139, 140, -1, + 142, 143, 144, -1, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, -1, 157, -1, 159, 160, 161, + 162, -1, 164, -1, 166, -1, -1, -1, 170, 171, + 172, -1, 174, -1, 176, -1, 178, 179, 180, -1, + 182, 183, 184, 185, 186, 187, 188, -1, 190, 191, + 192, 193, -1, 195, 196, 197, 198, 199, 200, -1, + 202, -1, 204, 205, 206, 207, 208, 209, 210, 211, + -1, 213, -1, 215, -1, -1, 218, -1, 220, 221, + 222, 223, 224, -1, -1, 227, -1, 229, -1, -1, + 232, 233, 234, -1, -1, 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, + -1, 263, 264, 265, 266, 267, -1, 269, 270, -1, + 272, -1, 274, 275, 276, 277, 278, 279, -1, 281, + 282, -1, -1, 285, 286, 287, -1, -1, 290, 291, + -1, 293, -1, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, -1, 307, 308, 309, 310, 311, + 312, 313, 314, 315, -1, 317, 318, 319, 320, 321, + 322, -1, 324, 325, 326, 327, 328, 329, 330, 331, + -1, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 343, 344, 345, -1, 347, 348, -1, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, -1, 366, 367, 368, 369, 370, -1, + 372, 373, 374, 375, 376, -1, 378, 379, 380, 381, + -1, 383, 384, 385, 386, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, -1, 399, 400, -1, + 402, -1, 404, 405, 406, 407, 408, -1, 410, 411, + -1, -1, 414, 415, 416, 417, 418, -1, 420, 421, + 422, 423, 424, 425, 426, 427, -1, -1, 430, 431, + 432, 433, 434, -1, -1, 437, 438, 439, 440, 441, + 442, 443, -1, 445, -1, 447, 448, 449, 450, -1, + -1, 453, -1, -1, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 473, 474, 475, 476, 3, -1, 5, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 19, 20, 21, 22, 23, 24, 25, 26, -1, + 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, + 38, 39, -1, 41, 42, 43, -1, 45, 46, 47, + 48, 49, -1, 51, 52, -1, 54, 55, 56, 57, + 58, 59, -1, -1, 62, 63, 64, 65, 66, -1, + 68, 69, 70, 71, 72, -1, -1, -1, 76, 77, + 78, 79, 80, 81, -1, 83, 84, 85, -1, 87, + 88, 89, 90, 91, 92, -1, -1, 95, 96, 97, + -1, -1, -1, -1, -1, -1, -1, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, -1, 116, -1, + 118, 119, 120, 121, 122, 123, -1, 125, 126, 127, + 128, 129, -1, -1, 132, 133, 134, 135, 136, -1, + 138, 139, 140, -1, 142, 143, 144, -1, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, -1, 157, + -1, 159, 160, 161, 162, -1, 164, -1, 166, -1, + -1, -1, 170, 171, 172, -1, 174, -1, 176, -1, + 178, 179, 180, -1, 182, 183, 184, 185, 186, 187, + 188, -1, 190, 191, 192, 193, -1, 195, 196, 197, + 198, 199, 200, -1, 202, -1, 204, 205, 206, 207, + 208, 209, 210, 211, -1, 213, -1, 215, -1, -1, + 218, -1, 220, 221, 222, 223, 224, -1, -1, 227, + -1, 229, -1, -1, 232, 233, 234, -1, -1, 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, -1, 263, 264, 265, 266, 267, + -1, 269, 270, -1, 272, -1, 274, 275, 276, 277, + 278, 279, -1, 281, 282, -1, -1, 285, 286, 287, + -1, -1, 290, 291, -1, 293, -1, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, -1, 307, + 308, 309, 310, 311, 312, 313, 314, 315, -1, 317, + 318, 319, 320, 321, 322, -1, 324, 325, 326, 327, + 328, 329, 330, 331, -1, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 343, 344, 345, -1, 347, + 348, -1, 350, 351, 352, 353, 354, 355, 356, 357, + 358, 359, 360, 361, 362, 363, 364, -1, 366, 367, + 368, 369, 370, -1, 372, 373, 374, 375, 376, -1, + 378, 379, 380, 381, -1, 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + -1, 399, 400, 401, 402, -1, 404, 405, 406, 407, + 408, -1, 410, 411, -1, -1, 414, 415, 416, 417, + 418, -1, 420, 421, 422, 423, 424, 425, 426, 427, + -1, -1, 430, 431, 432, 433, 434, -1, -1, 437, + 438, 439, 440, 441, 442, 443, -1, 445, -1, 447, + 448, 449, 450, -1, -1, 453, -1, -1, 456, 457, + 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 473, 474, 475, 476, 3, + 4, -1, -1, -1, -1, 9, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 19, 20, 21, 22, 23, + 24, 25, 26, -1, 28, 29, 30, -1, -1, -1, + -1, -1, -1, -1, 38, 39, -1, 41, 42, 43, + -1, 45, 46, 47, 48, 49, -1, 51, 52, -1, + 54, 55, 56, 57, 58, 59, -1, -1, 62, 63, + 64, 65, 66, -1, 68, 69, 70, 71, 72, -1, + -1, -1, 76, 77, 78, 79, 80, 81, -1, 83, + 84, 85, -1, 87, 88, 89, 90, 91, 92, -1, + -1, 95, 96, 97, -1, -1, -1, -1, -1, -1, + -1, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, -1, 116, -1, 118, 119, 120, 121, 122, 123, + -1, 125, 126, 127, 128, 129, -1, -1, 132, 133, + 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, + 144, -1, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, -1, 157, -1, 159, 160, 161, 162, -1, + 164, -1, 166, -1, -1, -1, 170, 171, 172, -1, + 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, + 184, 185, 186, 187, 188, -1, 190, 191, 192, 193, + -1, 195, 196, 197, 198, 199, 200, -1, 202, -1, + 204, 205, 206, 207, 208, 209, 210, 211, -1, 213, + -1, 215, -1, -1, 218, -1, 220, 221, 222, 223, + 224, -1, -1, 227, -1, 229, -1, -1, 232, 233, + 234, -1, -1, 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, -1, 263, + 264, 265, 266, 267, -1, 269, 270, -1, 272, -1, + 274, 275, 276, 277, 278, 279, -1, 281, 282, -1, + -1, 285, 286, 287, -1, -1, 290, 291, -1, 293, + -1, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, -1, 307, 308, 309, 310, 311, 312, 313, + 314, 315, -1, 317, 318, 319, 320, 321, 322, -1, + 324, 325, 326, 327, 328, 329, 330, 331, -1, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, + 344, 345, -1, 347, 348, -1, 350, 351, 352, 353, + 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, + 364, -1, 366, 367, 368, 369, 370, -1, 372, 373, + 374, 375, 376, -1, 378, 379, 380, 381, -1, 383, + 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, -1, 399, 400, -1, 402, -1, + 404, 405, 406, 407, 408, -1, 410, 411, -1, -1, + 414, 415, 416, 417, 418, -1, 420, 421, 422, 423, + 424, 425, 426, 427, -1, -1, 430, 431, 432, 433, + 434, -1, -1, 437, 438, 439, 440, 441, 442, 443, + -1, 445, -1, 447, 448, 449, 450, -1, -1, 453, + -1, -1, 456, 457, 458, 459, 460, 461, 462, 463, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, + 474, 475, 476, 3, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, -1, -1, -1, -1, -1, -1, -1, 38, 39, + -1, 41, 42, 43, -1, 45, 46, 47, 48, 49, + -1, 51, 52, -1, 54, 55, 56, 57, 58, 59, + -1, -1, 62, 63, 64, 65, 66, -1, 68, 69, + 70, 71, 72, -1, -1, -1, 76, 77, 78, 79, + 80, 81, -1, 83, 84, 85, -1, 87, 88, 89, + 90, 91, 92, -1, -1, 95, 96, 97, -1, -1, + -1, -1, -1, -1, -1, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, -1, 116, -1, 118, 119, + 120, 121, 122, 123, -1, 125, 126, 127, 128, 129, + -1, -1, 132, 133, 134, 135, 136, -1, 138, 139, + 140, -1, 142, 143, 144, -1, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, -1, 157, -1, 159, + 160, 161, 162, -1, 164, -1, 166, -1, -1, -1, + 170, 171, 172, -1, 174, -1, 176, -1, 178, 179, + 180, -1, 182, 183, 184, 185, 186, 187, 188, -1, + 190, 191, 192, 193, -1, 195, 196, 197, 198, 199, + 200, -1, 202, -1, 204, 205, 206, 207, 208, 209, + 210, 211, -1, 213, -1, 215, -1, -1, 218, -1, + 220, 221, 222, 223, 224, -1, -1, 227, -1, 229, + -1, -1, 232, 233, 234, -1, -1, 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, -1, 263, 264, 265, 266, 267, -1, 269, + 270, -1, 272, -1, 274, 275, 276, 277, 278, 279, + -1, 281, 282, -1, -1, 285, 286, 287, -1, -1, + 290, 291, -1, 293, -1, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, -1, 307, 308, 309, + 310, 311, 312, 313, 314, 315, -1, 317, 318, 319, + 320, 321, 322, -1, 324, 325, 326, 327, 328, 329, + 330, 331, -1, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 343, 344, 345, -1, 347, 348, -1, + 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, + 360, 361, 362, 363, 364, -1, 366, 367, 368, 369, + 370, -1, 372, 373, 374, 375, 376, -1, 378, 379, + 380, 381, -1, 383, 384, 385, 386, 387, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, -1, 399, + 400, -1, 402, -1, 404, 405, 406, 407, 408, -1, + 410, 411, -1, -1, 414, 415, 416, 417, 418, -1, + 420, 421, 422, 423, 424, 425, 426, 427, -1, -1, + 430, 431, 432, 433, 434, -1, -1, 437, 438, 439, + 440, 441, 442, 443, -1, 445, -1, 447, 448, 449, + 450, -1, -1, 453, -1, -1, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 473, 474, 475, 476, 3, -1, 5, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 19, 20, 21, 22, 23, 24, 25, + 26, -1, 28, 29, 30, -1, -1, -1, -1, -1, + -1, -1, 38, 39, -1, 41, 42, 43, -1, 45, + 46, 47, 48, 49, -1, 51, 52, -1, 54, 55, + 56, 57, 58, 59, -1, -1, 62, 63, 64, 65, + 66, -1, 68, 69, 70, 71, 72, -1, -1, -1, + 76, 77, 78, 79, 80, 81, -1, 83, 84, 85, + -1, 87, 88, 89, 90, 91, 92, -1, -1, 95, + 96, 97, -1, -1, -1, -1, -1, -1, -1, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, -1, + 116, -1, 118, 119, 120, 121, 122, 123, -1, 125, + 126, 127, 128, 129, -1, -1, 132, 133, 134, 135, + 136, -1, 138, 139, 140, -1, 142, 143, 144, -1, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, + -1, 157, -1, 159, 160, 161, 162, -1, 164, -1, + 166, -1, -1, -1, 170, 171, 172, -1, 174, -1, + 176, -1, 178, 179, 180, -1, 182, 183, 184, 185, + 186, 187, 188, -1, 190, 191, 192, 193, -1, 195, + 196, 197, 198, 199, 200, -1, 202, -1, 204, 205, + 206, 207, 208, 209, 210, 211, -1, 213, -1, 215, + -1, -1, 218, -1, 220, 221, 222, 223, 224, -1, + -1, 227, -1, 229, -1, -1, 232, 233, 234, -1, + -1, 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, -1, 263, 264, 265, + 266, 267, -1, 269, 270, -1, 272, -1, 274, 275, + 276, 277, 278, 279, -1, 281, 282, -1, -1, 285, + 286, 287, -1, -1, 290, 291, -1, 293, -1, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + -1, 307, 308, 309, 310, 311, 312, 313, 314, 315, + -1, 317, 318, 319, 320, 321, 322, -1, 324, 325, + 326, 327, 328, 329, 330, 331, -1, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, + -1, 347, 348, -1, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 361, 362, 363, 364, -1, + 366, 367, 368, 369, 370, -1, 372, 373, 374, 375, + 376, -1, 378, 379, 380, 381, -1, 383, 384, 385, + 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, -1, 399, 400, -1, 402, -1, 404, 405, + 406, 407, 408, -1, 410, 411, -1, -1, 414, 415, + 416, 417, 418, -1, 420, 421, 422, 423, 424, 425, + 426, 427, -1, -1, 430, 431, 432, 433, 434, -1, + -1, 437, 438, 439, 440, 441, 442, 443, -1, 445, + -1, 447, 448, 449, 450, -1, -1, 453, -1, -1, + 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, + 476, 3, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, -1, + -1, -1, -1, -1, -1, -1, 38, 39, -1, 41, + 42, 43, -1, 45, 46, 47, 48, 49, -1, 51, + 52, -1, 54, 55, 56, 57, 58, 59, -1, -1, + 62, 63, 64, 65, 66, -1, 68, 69, 70, 71, + 72, -1, -1, -1, 76, 77, 78, 79, 80, 81, + -1, 83, 84, 85, -1, 87, 88, 89, 90, 91, + 92, -1, -1, 95, 96, 97, -1, -1, -1, -1, + -1, -1, -1, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, -1, 116, -1, 118, 119, 120, 121, + 122, 123, -1, 125, 126, 127, 128, 129, -1, -1, + 132, 133, 134, 135, 136, -1, 138, 139, 140, -1, + 142, 143, 144, -1, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, -1, 157, -1, 159, 160, 161, + 162, -1, 164, -1, 166, -1, -1, -1, 170, 171, + 172, -1, 174, -1, 176, -1, 178, 179, 180, -1, + 182, 183, 184, 185, 186, 187, 188, -1, 190, 191, + 192, 193, -1, 195, 196, 197, 198, 199, 200, -1, + 202, -1, 204, 205, 206, 207, 208, 209, 210, 211, + -1, 213, -1, 215, -1, -1, 218, -1, 220, 221, + 222, 223, 224, -1, -1, 227, -1, 229, -1, -1, + 232, 233, 234, -1, -1, 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, + -1, 263, 264, 265, 266, 267, -1, 269, 270, -1, + 272, -1, 274, 275, 276, 277, 278, 279, -1, 281, + 282, -1, -1, 285, 286, 287, -1, -1, 290, 291, + -1, 293, -1, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, -1, 307, 308, 309, 310, 311, + 312, 313, 314, 315, -1, 317, 318, 319, 320, 321, + 322, -1, 324, 325, 326, 327, 328, 329, 330, 331, + -1, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 343, 344, 345, -1, 347, 348, -1, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, -1, 366, 367, 368, 369, 370, -1, + 372, 373, 374, 375, 376, -1, 378, 379, 380, 381, + -1, 383, 384, 385, 386, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, -1, 399, 400, -1, + 402, -1, 404, 405, 406, 407, 408, -1, 410, 411, + -1, -1, 414, 415, 416, 417, 418, -1, 420, 421, + 422, 423, 424, 425, 426, 427, -1, -1, 430, 431, + 432, 433, 434, -1, -1, 437, 438, 439, 440, 441, + 442, 443, -1, 445, -1, 447, 448, 449, 450, -1, + -1, 453, -1, -1, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 473, 474, 475, 476, 3, -1, 5, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 19, 20, 21, 22, 23, 24, 25, 26, -1, + 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, + 38, 39, -1, 41, 42, 43, -1, 45, 46, 47, + 48, 49, -1, 51, 52, -1, 54, 55, 56, 57, + 58, 59, -1, -1, 62, 63, 64, 65, 66, -1, + 68, 69, 70, 71, 72, -1, -1, -1, 76, 77, + 78, 79, 80, 81, -1, 83, 84, 85, -1, 87, + 88, 89, 90, 91, 92, -1, -1, 95, 96, 97, + -1, -1, -1, -1, -1, -1, -1, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, -1, 116, -1, + 118, 119, 120, 121, 122, 123, -1, 125, 126, 127, + 128, 129, -1, -1, 132, 133, 134, 135, 136, -1, + 138, 139, 140, -1, 142, 143, 144, -1, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, -1, 157, + -1, 159, 160, 161, 162, -1, 164, -1, 166, -1, + -1, -1, 170, 171, 172, -1, 174, -1, 176, -1, + 178, 179, 180, -1, 182, 183, 184, 185, 186, 187, + 188, -1, 190, 191, 192, 193, -1, 195, 196, 197, + 198, 199, 200, -1, 202, -1, 204, 205, 206, 207, + 208, 209, 210, 211, -1, 213, -1, 215, -1, -1, + 218, -1, 220, 221, 222, 223, 224, -1, -1, 227, + -1, 229, -1, -1, 232, 233, 234, -1, -1, 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, -1, 263, 264, 265, 266, 267, + -1, 269, 270, -1, 272, -1, 274, 275, 276, 277, + 278, 279, -1, 281, 282, -1, -1, 285, 286, 287, + -1, -1, 290, 291, -1, 293, -1, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, -1, 307, + 308, 309, 310, 311, 312, 313, 314, 315, -1, 317, + 318, 319, 320, 321, 322, -1, 324, 325, 326, 327, + 328, 329, 330, 331, -1, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 343, 344, 345, -1, 347, + 348, -1, 350, 351, 352, 353, 354, 355, 356, 357, + 358, 359, 360, 361, 362, 363, 364, -1, 366, 367, + 368, 369, 370, -1, 372, 373, 374, 375, 376, -1, + 378, 379, 380, 381, -1, 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + -1, 399, 400, -1, 402, -1, 404, 405, 406, 407, + 408, -1, 410, 411, -1, -1, 414, 415, 416, 417, + 418, -1, 420, 421, 422, 423, 424, 425, 426, 427, + -1, -1, 430, 431, 432, 433, 434, -1, -1, 437, + 438, 439, 440, 441, 442, 443, -1, 445, -1, 447, + 448, 449, 450, -1, -1, 453, -1, -1, 456, 457, + 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 473, 474, 475, 476, 3, + -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 19, 20, 21, 22, 23, + 24, 25, 26, -1, 28, 29, 30, -1, -1, -1, + -1, -1, -1, -1, 38, 39, -1, 41, 42, 43, + -1, 45, 46, 47, 48, 49, -1, 51, 52, -1, + 54, 55, 56, 57, 58, 59, -1, -1, 62, 63, + 64, 65, 66, -1, 68, 69, 70, 71, 72, -1, + -1, -1, 76, 77, 78, 79, 80, 81, -1, 83, + 84, 85, -1, 87, 88, 89, 90, 91, 92, -1, + -1, 95, 96, 97, -1, -1, -1, -1, -1, -1, + -1, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, -1, 116, -1, 118, 119, 120, 121, 122, 123, + -1, 125, 126, 127, 128, 129, -1, -1, 132, 133, + 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, + 144, -1, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, -1, 157, -1, 159, 160, 161, 162, -1, + 164, -1, 166, -1, -1, -1, 170, 171, 172, -1, + 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, + 184, 185, 186, 187, 188, -1, 190, 191, 192, 193, + -1, 195, 196, 197, 198, 199, 200, -1, 202, -1, + 204, 205, 206, 207, 208, 209, 210, 211, -1, 213, + -1, 215, -1, -1, 218, -1, 220, 221, 222, 223, + 224, -1, -1, 227, -1, 229, -1, -1, 232, 233, + 234, -1, -1, 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, -1, 263, + 264, 265, 266, 267, -1, 269, 270, -1, 272, -1, + 274, 275, 276, 277, 278, 279, -1, 281, 282, -1, + -1, 285, 286, 287, -1, -1, 290, 291, -1, 293, + -1, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, -1, 307, 308, 309, 310, 311, 312, 313, + 314, 315, -1, 317, 318, 319, 320, 321, 322, -1, + 324, 325, 326, 327, 328, 329, 330, 331, -1, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, + 344, 345, -1, 347, 348, -1, 350, 351, 352, 353, + 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, + 364, -1, 366, 367, 368, 369, 370, -1, 372, 373, + 374, 375, 376, -1, 378, 379, 380, 381, -1, 383, + 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, -1, 399, 400, -1, 402, -1, + 404, 405, 406, 407, 408, -1, 410, 411, -1, -1, + 414, 415, 416, 417, 418, -1, 420, 421, 422, 423, + 424, 425, 426, 427, -1, -1, 430, 431, 432, 433, + 434, -1, -1, 437, 438, 439, 440, 441, 442, 443, + -1, 445, -1, 447, 448, 449, 450, -1, -1, 453, + -1, -1, 456, 457, 458, 459, 460, 461, 462, 463, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, + 474, 475, 476, 3, -1, 5, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, + 20, 21, 22, 23, 24, 25, 26, -1, 28, 29, + 30, -1, -1, -1, -1, -1, -1, -1, 38, 39, + -1, 41, 42, 43, -1, 45, 46, 47, 48, 49, + -1, 51, 52, -1, 54, 55, 56, 57, 58, 59, + -1, -1, 62, 63, 64, 65, 66, -1, 68, 69, + 70, 71, 72, -1, -1, -1, 76, 77, 78, 79, + 80, 81, -1, 83, 84, 85, -1, 87, 88, 89, + 90, 91, 92, -1, -1, 95, 96, 97, -1, -1, + -1, -1, -1, -1, -1, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, -1, 116, -1, 118, 119, + 120, 121, 122, 123, -1, 125, 126, 127, 128, 129, + -1, -1, 132, 133, 134, 135, 136, -1, 138, 139, + 140, -1, 142, 143, 144, -1, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, -1, 157, -1, 159, + 160, 161, 162, -1, 164, -1, 166, -1, -1, -1, + 170, 171, 172, -1, 174, -1, 176, -1, 178, 179, + 180, -1, 182, 183, 184, 185, 186, 187, 188, -1, + 190, 191, 192, 193, -1, 195, 196, 197, 198, 199, + 200, -1, 202, -1, 204, 205, 206, 207, 208, 209, + 210, 211, -1, 213, -1, 215, -1, -1, 218, -1, + 220, 221, 222, 223, 224, -1, -1, 227, -1, 229, + -1, -1, 232, 233, 234, -1, -1, 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, -1, 263, 264, 265, 266, 267, -1, 269, + 270, -1, 272, -1, 274, 275, 276, 277, 278, 279, + -1, 281, 282, -1, -1, 285, 286, 287, -1, -1, + 290, 291, -1, 293, -1, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, -1, 307, 308, 309, + 310, 311, 312, 313, 314, 315, -1, 317, 318, 319, + 320, 321, 322, -1, 324, 325, 326, 327, 328, 329, + 330, 331, -1, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 343, 344, 345, -1, 347, 348, -1, + 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, + 360, 361, 362, 363, 364, -1, 366, 367, 368, 369, + 370, -1, 372, 373, 374, 375, 376, -1, 378, 379, + 380, 381, -1, 383, 384, 385, 386, 387, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, -1, 399, + 400, -1, 402, -1, 404, 405, 406, 407, 408, -1, + 410, 411, -1, -1, 414, 415, 416, 417, 418, -1, + 420, 421, 422, 423, 424, 425, 426, 427, -1, -1, + 430, 431, 432, 433, 434, -1, -1, 437, 438, 439, + 440, 441, 442, 443, -1, 445, -1, 447, 448, 449, + 450, -1, -1, 453, -1, -1, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 473, 474, 475, 476, 3, -1, 5, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 19, 20, 21, 22, 23, 24, 25, + 26, -1, 28, 29, 30, -1, -1, -1, -1, -1, + -1, -1, 38, 39, -1, 41, 42, 43, -1, 45, + 46, 47, 48, 49, -1, 51, 52, -1, 54, 55, + 56, 57, 58, 59, -1, -1, 62, 63, 64, 65, + 66, -1, 68, 69, 70, 71, 72, -1, -1, -1, + 76, 77, 78, 79, 80, 81, -1, 83, 84, 85, + -1, 87, 88, 89, 90, 91, 92, -1, -1, 95, + 96, 97, -1, -1, -1, -1, -1, -1, -1, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, -1, + 116, -1, 118, 119, 120, 121, 122, 123, -1, 125, + 126, 127, 128, 129, -1, -1, 132, 133, 134, 135, + 136, -1, 138, 139, 140, -1, 142, 143, 144, -1, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, + -1, 157, -1, 159, 160, 161, 162, -1, 164, -1, + 166, -1, -1, -1, 170, 171, 172, -1, 174, -1, + 176, -1, 178, 179, 180, -1, 182, 183, 184, 185, + 186, 187, 188, -1, 190, 191, 192, 193, -1, 195, + 196, 197, 198, 199, 200, -1, 202, -1, 204, 205, + 206, 207, 208, 209, 210, 211, -1, 213, -1, 215, + -1, -1, 218, -1, 220, 221, 222, 223, 224, -1, + -1, 227, -1, 229, -1, -1, 232, 233, 234, -1, + -1, 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, -1, 263, 264, 265, + 266, 267, -1, 269, 270, -1, 272, -1, 274, 275, + 276, 277, 278, 279, -1, 281, 282, -1, -1, 285, + 286, 287, -1, -1, 290, 291, -1, 293, -1, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + -1, 307, 308, 309, 310, 311, 312, 313, 314, 315, + -1, 317, 318, 319, 320, 321, 322, -1, 324, 325, + 326, 327, 328, 329, 330, 331, -1, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, + -1, 347, 348, -1, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 361, 362, 363, 364, -1, + 366, 367, 368, 369, 370, -1, 372, 373, 374, 375, + 376, -1, 378, 379, 380, 381, -1, 383, 384, 385, + 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, -1, 399, 400, -1, 402, -1, 404, 405, + 406, 407, 408, -1, 410, 411, -1, -1, 414, 415, + 416, 417, 418, -1, 420, 421, 422, 423, 424, 425, + 426, 427, -1, -1, 430, 431, 432, 433, 434, -1, + -1, 437, 438, 439, 440, 441, 442, 443, -1, 445, + -1, 447, 448, 449, 450, -1, -1, 453, -1, -1, + 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, + 476, 3, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, -1, + -1, -1, -1, -1, -1, -1, 38, 39, -1, 41, + 42, 43, -1, 45, 46, 47, 48, 49, -1, 51, + 52, -1, 54, 55, 56, 57, 58, 59, -1, -1, + 62, 63, 64, 65, 66, -1, 68, 69, 70, 71, + 72, -1, -1, -1, 76, 77, 78, 79, 80, 81, + -1, 83, 84, 85, -1, 87, 88, 89, 90, 91, + 92, -1, -1, 95, 96, 97, -1, -1, -1, -1, + -1, -1, -1, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, -1, 116, -1, 118, 119, 120, 121, + 122, 123, -1, 125, 126, 127, 128, 129, -1, -1, + 132, 133, 134, 135, 136, -1, 138, 139, 140, -1, + 142, 143, 144, -1, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, -1, 157, -1, 159, 160, 161, + 162, -1, 164, -1, 166, -1, -1, -1, 170, 171, + 172, -1, 174, -1, 176, -1, 178, 179, 180, -1, + 182, 183, 184, 185, 186, 187, 188, -1, 190, 191, + 192, 193, -1, 195, 196, 197, 198, 199, 200, -1, + 202, -1, 204, 205, 206, 207, 208, 209, 210, 211, + -1, 213, -1, 215, -1, -1, 218, -1, 220, 221, + 222, 223, 224, -1, -1, 227, -1, 229, -1, -1, + 232, 233, 234, -1, -1, 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, + -1, 263, 264, 265, 266, 267, -1, 269, 270, -1, + 272, -1, 274, 275, 276, 277, 278, 279, -1, 281, + 282, -1, -1, 285, 286, 287, -1, -1, 290, 291, + -1, 293, -1, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, -1, 307, 308, 309, 310, 311, + 312, 313, 314, 315, -1, 317, 318, 319, 320, 321, + 322, -1, 324, 325, 326, 327, 328, 329, 330, 331, + -1, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 343, 344, 345, -1, 347, 348, -1, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, -1, 366, 367, 368, 369, 370, -1, + 372, 373, 374, 375, 376, -1, 378, 379, 380, 381, + -1, 383, 384, 385, 386, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, -1, 399, 400, -1, + 402, -1, 404, 405, 406, 407, 408, -1, 410, 411, + -1, -1, 414, 415, 416, 417, 418, -1, 420, 421, + 422, 423, 424, 425, 426, 427, -1, -1, 430, 431, + 432, 433, 434, -1, -1, 437, 438, 439, 440, 441, + 442, 443, -1, 445, -1, 447, 448, 449, 450, -1, + -1, 453, -1, -1, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 473, 474, 475, 476, 3, -1, 5, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 19, 20, 21, 22, 23, 24, 25, 26, -1, + 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, + 38, 39, -1, 41, 42, 43, -1, 45, 46, 47, + 48, 49, -1, 51, 52, -1, 54, 55, 56, 57, + 58, 59, -1, -1, 62, 63, 64, 65, 66, -1, + 68, 69, 70, 71, 72, -1, -1, -1, 76, 77, + 78, 79, 80, 81, -1, 83, 84, 85, -1, 87, + 88, 89, 90, 91, 92, -1, -1, 95, 96, 97, + -1, -1, -1, -1, -1, -1, -1, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, -1, 116, -1, + 118, 119, 120, 121, 122, 123, -1, 125, 126, 127, + 128, 129, -1, -1, 132, 133, 134, 135, 136, -1, + 138, 139, 140, -1, 142, 143, 144, -1, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, -1, 157, + -1, 159, 160, 161, 162, -1, 164, -1, 166, -1, + -1, -1, 170, 171, 172, -1, 174, -1, 176, -1, + 178, 179, 180, -1, 182, 183, 184, 185, 186, 187, + 188, -1, 190, 191, 192, 193, -1, 195, 196, 197, + 198, 199, 200, -1, 202, -1, 204, 205, 206, 207, + 208, 209, 210, 211, -1, 213, -1, 215, -1, -1, + 218, -1, 220, 221, 222, 223, 224, -1, -1, 227, + -1, 229, -1, -1, 232, 233, 234, -1, -1, 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, -1, 263, 264, 265, 266, 267, + -1, 269, 270, -1, 272, -1, 274, 275, 276, 277, + 278, 279, -1, 281, 282, -1, -1, 285, 286, 287, + -1, -1, 290, 291, -1, 293, -1, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, -1, 307, + 308, 309, 310, 311, 312, 313, 314, 315, -1, 317, + 318, 319, 320, 321, 322, -1, 324, 325, 326, 327, + 328, 329, 330, 331, -1, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 343, 344, 345, -1, 347, + 348, -1, 350, 351, 352, 353, 354, 355, 356, 357, + 358, 359, 360, 361, 362, 363, 364, -1, 366, 367, + 368, 369, 370, -1, 372, 373, 374, 375, 376, -1, + 378, 379, 380, 381, -1, 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + -1, 399, 400, -1, 402, -1, 404, 405, 406, 407, + 408, -1, 410, 411, -1, -1, 414, 415, 416, 417, + 418, -1, 420, 421, 422, 423, 424, 425, 426, 427, + -1, -1, 430, 431, 432, 433, 434, -1, -1, 437, + 438, 439, 440, 441, 442, 443, -1, 445, -1, 447, + 448, 449, 450, -1, -1, 453, -1, -1, 456, 457, + 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 473, 474, 475, 476, 3, + -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 19, 20, 21, 22, 23, + 24, 25, 26, -1, 28, 29, 30, -1, -1, -1, + -1, -1, -1, -1, 38, 39, -1, 41, 42, 43, + -1, 45, 46, 47, 48, 49, -1, 51, 52, -1, + 54, 55, 56, 57, 58, 59, -1, -1, 62, 63, + 64, 65, 66, -1, 68, 69, 70, 71, 72, -1, + -1, -1, 76, 77, 78, 79, 80, 81, -1, 83, + 84, 85, -1, 87, 88, 89, 90, 91, 92, -1, + -1, 95, 96, 97, -1, -1, -1, -1, -1, -1, + -1, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, -1, 116, -1, 118, 119, 120, 121, 122, 123, + -1, 125, 126, 127, 128, 129, -1, -1, 132, 133, + 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, + 144, -1, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, -1, 157, -1, 159, 160, 161, 162, -1, + 164, -1, 166, -1, -1, -1, 170, 171, 172, -1, + 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, + 184, 185, 186, 187, 188, -1, 190, 191, 192, 193, + -1, 195, 196, 197, 198, 199, 200, -1, 202, -1, + 204, 205, 206, 207, 208, 209, 210, 211, -1, 213, + -1, 215, -1, -1, 218, -1, 220, 221, 222, 223, + 224, -1, -1, 227, -1, 229, -1, -1, 232, 233, + 234, -1, -1, 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, -1, 263, + 264, 265, 266, 267, -1, 269, 270, -1, 272, -1, + 274, 275, 276, 277, 278, 279, -1, 281, 282, -1, + -1, 285, 286, 287, -1, -1, 290, 291, -1, 293, + -1, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, -1, 307, 308, 309, 310, 311, 312, 313, + 314, 315, -1, 317, 318, 319, 320, 321, 322, -1, + 324, 325, 326, 327, 328, 329, 330, 331, -1, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, + 344, 345, -1, 347, 348, -1, 350, 351, 352, 353, + 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, + 364, -1, 366, 367, 368, 369, 370, -1, 372, 373, + 374, 375, 376, -1, 378, 379, 380, 381, -1, 383, + 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, -1, 399, 400, -1, 402, -1, + 404, 405, 406, 407, 408, -1, 410, 411, -1, -1, + 414, 415, 416, 417, 418, -1, 420, 421, 422, 423, + 424, 425, 426, 427, -1, -1, 430, 431, 432, 433, + 434, -1, -1, 437, 438, 439, 440, 441, 442, 443, + -1, 445, -1, 447, 448, 449, 450, -1, -1, 453, + -1, -1, 456, 457, 458, 459, 460, 461, 462, 463, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, + 474, 475, 476, 3, -1, 5, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, + 20, 21, 22, 23, 24, 25, 26, -1, 28, 29, + 30, -1, -1, -1, -1, -1, -1, -1, 38, 39, + -1, 41, 42, 43, -1, 45, 46, 47, 48, 49, + -1, 51, 52, -1, 54, 55, 56, 57, 58, 59, + -1, -1, 62, 63, 64, 65, 66, -1, 68, 69, + 70, 71, 72, -1, -1, -1, 76, 77, 78, 79, + 80, 81, -1, 83, 84, 85, -1, 87, 88, 89, + 90, 91, 92, -1, -1, 95, 96, 97, -1, -1, + -1, -1, -1, -1, -1, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, -1, 116, -1, 118, 119, + 120, 121, 122, 123, -1, 125, 126, 127, 128, 129, + -1, -1, 132, 133, 134, 135, 136, -1, 138, 139, + 140, -1, 142, 143, 144, -1, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, -1, 157, -1, 159, + 160, 161, 162, -1, 164, -1, 166, -1, -1, -1, + 170, 171, 172, -1, 174, -1, 176, -1, 178, 179, + 180, -1, 182, 183, 184, 185, 186, 187, 188, -1, + 190, 191, 192, 193, -1, 195, 196, 197, 198, 199, + 200, -1, 202, -1, 204, 205, 206, 207, 208, 209, + 210, 211, -1, 213, -1, 215, -1, -1, 218, -1, + 220, 221, 222, 223, 224, -1, -1, 227, -1, 229, + -1, -1, 232, 233, 234, -1, -1, 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, -1, 263, 264, 265, 266, 267, -1, 269, + 270, -1, 272, -1, 274, 275, 276, 277, 278, 279, + -1, 281, 282, -1, -1, 285, 286, 287, -1, -1, + 290, 291, -1, 293, -1, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, -1, 307, 308, 309, + 310, 311, 312, 313, 314, 315, -1, 317, 318, 319, + 320, 321, 322, -1, 324, 325, 326, 327, 328, 329, + 330, 331, -1, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 343, 344, 345, -1, 347, 348, -1, + 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, + 360, 361, 362, 363, 364, -1, 366, 367, 368, 369, + 370, -1, 372, 373, 374, 375, 376, -1, 378, 379, + 380, 381, -1, 383, 384, 385, 386, 387, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, -1, 399, + 400, -1, 402, -1, 404, 405, 406, 407, 408, -1, + 410, 411, -1, -1, 414, 415, 416, 417, 418, -1, + 420, 421, 422, 423, 424, 425, 426, 427, -1, -1, + 430, 431, 432, 433, 434, -1, -1, 437, 438, 439, + 440, 441, 442, 443, -1, 445, -1, 447, 448, 449, + 450, -1, -1, 453, -1, -1, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 473, 474, 475, 476, 3, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 19, 20, 21, 22, 23, 24, 25, + 26, -1, 28, 29, 30, -1, -1, -1, -1, -1, + 36, -1, 38, 39, -1, 41, 42, 43, -1, 45, + 46, 47, 48, 49, -1, 51, 52, -1, 54, 55, + 56, 57, 58, 59, -1, -1, 62, 63, 64, 65, + 66, -1, 68, 69, 70, 71, 72, -1, -1, -1, + 76, 77, 78, 79, 80, 81, -1, 83, 84, 85, + -1, 87, 88, 89, 90, 91, 92, -1, -1, 95, + 96, 97, -1, -1, -1, -1, -1, -1, -1, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, -1, + 116, -1, 118, 119, 120, 121, 122, 123, -1, 125, + 126, 127, 128, 129, -1, -1, 132, 133, 134, 135, + 136, -1, 138, 139, 140, -1, 142, 143, 144, -1, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, + -1, 157, -1, 159, 160, 161, 162, -1, 164, -1, + 166, -1, -1, -1, 170, 171, 172, -1, 174, -1, + 176, -1, 178, 179, 180, -1, 182, 183, 184, 185, + 186, 187, 188, -1, 190, 191, 192, 193, -1, 195, + 196, 197, 198, 199, 200, -1, 202, -1, 204, 205, + 206, 207, 208, 209, 210, 211, -1, 213, -1, 215, + -1, -1, 218, -1, 220, 221, 222, 223, 224, -1, + -1, 227, -1, 229, -1, -1, 232, 233, 234, -1, + -1, 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, -1, 263, 264, 265, + 266, 267, -1, 269, 270, -1, 272, -1, 274, 275, + 276, 277, 278, 279, -1, 281, 282, -1, -1, 285, + 286, 287, -1, -1, 290, 291, -1, 293, -1, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + -1, 307, 308, 309, 310, 311, 312, 313, 314, 315, + -1, 317, 318, 319, 320, 321, 322, -1, 324, 325, + 326, 327, 328, 329, 330, 331, -1, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, + -1, 347, 348, -1, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 361, 362, 363, 364, -1, + 366, 367, 368, 369, 370, -1, 372, 373, 374, 375, + 376, -1, 378, 379, 380, 381, -1, 383, 384, 385, + 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, -1, 399, 400, -1, 402, -1, 404, 405, + 406, 407, 408, -1, 410, 411, -1, -1, 414, 415, + 416, 417, 418, -1, 420, 421, 422, 423, 424, 425, + 426, 427, -1, -1, 430, 431, 432, 433, 434, -1, + -1, 437, 438, 439, 440, 441, 442, 443, -1, 445, + -1, 447, 448, 449, 450, -1, -1, 453, -1, -1, + 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, + 476, 3, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 19, 20, 21, + 22, 23, 24, 25, 26, -1, 28, 29, 30, -1, + -1, -1, -1, -1, 36, -1, 38, 39, -1, 41, + 42, 43, -1, 45, 46, 47, 48, 49, -1, 51, + 52, -1, 54, 55, 56, 57, 58, 59, -1, -1, + 62, 63, 64, 65, 66, -1, 68, 69, 70, 71, + 72, -1, -1, -1, 76, 77, 78, 79, 80, 81, + -1, 83, 84, 85, -1, 87, 88, 89, 90, 91, + 92, -1, -1, 95, 96, 97, -1, -1, -1, -1, + -1, -1, -1, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, -1, 116, -1, 118, 119, 120, 121, + 122, 123, -1, 125, 126, 127, 128, 129, -1, -1, + 132, 133, 134, 135, 136, -1, 138, 139, 140, -1, + 142, 143, 144, -1, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, -1, 157, -1, 159, 160, 161, + 162, -1, 164, -1, 166, -1, -1, -1, 170, 171, + 172, -1, 174, -1, 176, -1, 178, 179, 180, -1, + 182, 183, 184, 185, 186, 187, 188, -1, 190, 191, + 192, 193, -1, 195, 196, 197, 198, 199, 200, -1, + 202, -1, 204, 205, 206, 207, 208, 209, 210, 211, + -1, 213, -1, 215, -1, -1, 218, -1, 220, 221, + 222, 223, 224, -1, -1, 227, -1, 229, -1, -1, + 232, 233, 234, -1, -1, 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, + -1, 263, 264, 265, 266, 267, -1, 269, 270, -1, + 272, -1, 274, 275, 276, 277, 278, 279, -1, 281, + 282, -1, -1, 285, 286, 287, -1, -1, 290, 291, + -1, 293, -1, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, -1, 307, 308, 309, 310, 311, + 312, 313, 314, 315, -1, 317, 318, 319, 320, 321, + 322, -1, 324, 325, 326, 327, 328, 329, 330, 331, + -1, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 343, 344, 345, -1, 347, 348, -1, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, -1, 366, 367, 368, 369, 370, -1, + 372, 373, 374, 375, 376, -1, 378, 379, 380, 381, + -1, 383, 384, 385, 386, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, -1, 399, 400, -1, + 402, -1, 404, 405, 406, 407, 408, -1, 410, 411, + -1, -1, 414, 415, 416, 417, 418, -1, 420, 421, + 422, 423, 424, 425, 426, 427, -1, -1, 430, 431, + 432, 433, 434, -1, -1, 437, 438, 439, 440, 441, + 442, 443, -1, 445, -1, 447, 448, 449, 450, -1, + -1, 453, -1, -1, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 473, 474, 475, 476, 3, -1, 5, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 19, 20, 21, 22, 23, 24, 25, 26, -1, + 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, + 38, 39, -1, 41, 42, 43, -1, 45, 46, 47, + 48, 49, -1, 51, 52, -1, 54, 55, 56, 57, + 58, 59, -1, -1, 62, 63, 64, 65, 66, -1, + 68, 69, 70, 71, 72, -1, -1, -1, 76, 77, + 78, 79, 80, 81, -1, 83, 84, 85, -1, 87, + 88, 89, 90, 91, 92, -1, -1, 95, 96, 97, + -1, -1, -1, -1, -1, -1, -1, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, -1, 116, -1, + 118, 119, 120, 121, 122, 123, -1, 125, 126, 127, + 128, 129, -1, -1, 132, 133, 134, 135, 136, -1, + 138, 139, 140, -1, 142, 143, 144, -1, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, -1, 157, + -1, 159, 160, 161, 162, -1, 164, -1, 166, -1, + -1, -1, 170, 171, 172, -1, 174, -1, 176, -1, + 178, 179, 180, -1, 182, 183, 184, 185, 186, 187, + 188, -1, 190, 191, 192, 193, -1, 195, 196, 197, + 198, 199, 200, -1, 202, -1, 204, 205, 206, 207, + 208, 209, 210, 211, -1, 213, -1, 215, -1, -1, + 218, -1, 220, 221, 222, 223, 224, -1, -1, 227, + -1, 229, -1, -1, 232, 233, 234, -1, -1, 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, -1, 263, 264, 265, 266, 267, + -1, 269, 270, -1, 272, -1, 274, 275, 276, 277, + 278, 279, -1, 281, 282, -1, -1, 285, 286, 287, + -1, -1, 290, 291, -1, 293, -1, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, -1, 307, + 308, 309, 310, 311, 312, 313, 314, 315, -1, 317, + 318, 319, 320, 321, 322, -1, 324, 325, 326, 327, + 328, 329, 330, 331, -1, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 343, 344, 345, -1, 347, + 348, -1, 350, 351, 352, 353, 354, 355, 356, 357, + 358, 359, 360, 361, 362, 363, 364, -1, 366, 367, + 368, 369, 370, -1, 372, 373, 374, 375, 376, -1, + 378, 379, 380, 381, -1, 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + -1, 399, 400, -1, 402, -1, 404, 405, 406, 407, + 408, -1, 410, 411, -1, -1, 414, 415, 416, 417, + 418, -1, 420, 421, 422, 423, 424, 425, 426, 427, + -1, -1, 430, 431, 432, 433, 434, -1, -1, 437, + 438, 439, 440, 441, 442, 443, -1, 445, -1, 447, + 448, 449, 450, -1, -1, 453, -1, -1, 456, 457, + 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 473, 474, 475, 476, 3, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 19, 20, 21, 22, 23, + 24, 25, 26, -1, 28, 29, 30, -1, -1, -1, + -1, -1, -1, -1, 38, 39, -1, 41, 42, 43, + -1, 45, 46, 47, 48, 49, -1, 51, 52, -1, + 54, 55, 56, 57, 58, 59, -1, -1, 62, 63, + 64, 65, 66, -1, 68, 69, 70, 71, 72, -1, + -1, -1, 76, 77, 78, 79, 80, 81, -1, 83, + 84, 85, -1, 87, 88, 89, 90, 91, 92, -1, + -1, 95, 96, 97, -1, -1, -1, -1, -1, -1, + -1, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, -1, 116, -1, 118, 119, 120, 121, 122, 123, + -1, 125, 126, 127, 128, 129, -1, -1, 132, 133, + 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, + 144, -1, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, -1, 157, -1, 159, 160, 161, 162, -1, + 164, -1, 166, -1, -1, -1, 170, 171, 172, -1, + 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, + 184, 185, 186, 187, 188, -1, 190, 191, 192, 193, + -1, 195, 196, 197, 198, 199, 200, -1, 202, -1, + 204, 205, 206, 207, 208, 209, 210, 211, -1, 213, + -1, 215, -1, -1, 218, -1, 220, 221, 222, 223, + 224, -1, -1, 227, -1, 229, -1, -1, 232, 233, + 234, -1, -1, 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, -1, 263, + 264, 265, 266, 267, -1, 269, 270, -1, 272, -1, + 274, 275, 276, 277, 278, 279, -1, 281, 282, -1, + -1, 285, 286, 287, -1, -1, 290, 291, -1, 293, + -1, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, -1, 307, 308, 309, 310, 311, 312, 313, + 314, 315, -1, 317, 318, 319, 320, 321, 322, -1, + 324, 325, 326, 327, 328, 329, 330, 331, -1, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, + 344, 345, -1, 347, 348, -1, 350, 351, 352, 353, + 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, + 364, -1, 366, 367, 368, 369, 370, -1, 372, 373, + 374, 375, 376, -1, 378, 379, 380, 381, -1, 383, + 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, -1, 399, 400, -1, 402, -1, + 404, 405, 406, 407, 408, -1, 410, 411, -1, -1, + 414, 415, 416, 417, 418, -1, 420, 421, 422, 423, + 424, 425, 426, 427, -1, -1, 430, 431, 432, 433, + 434, -1, -1, 437, 438, 439, 440, 441, 442, 443, + -1, 445, -1, 447, 448, 449, 450, -1, -1, 453, + -1, -1, 456, 457, 458, 459, 460, 461, 462, 463, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, + 474, 475, 476, 3, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, + 20, 21, 22, 23, 24, 25, 26, -1, 28, 29, + 30, -1, -1, -1, -1, -1, -1, -1, 38, 39, + -1, 41, 42, 43, -1, 45, 46, 47, 48, 49, + -1, 51, 52, -1, 54, 55, 56, 57, 58, 59, + -1, -1, 62, 63, 64, 65, 66, -1, 68, 69, + 70, 71, 72, -1, -1, -1, 76, 77, 78, 79, + 80, 81, -1, 83, 84, 85, -1, 87, 88, 89, + 90, 91, 92, -1, -1, 95, 96, 97, -1, -1, + -1, -1, -1, -1, -1, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, -1, 116, -1, 118, 119, + 120, 121, 122, 123, -1, 125, 126, 127, 128, 129, + -1, -1, 132, 133, 134, 135, 136, -1, 138, 139, + 140, -1, 142, 143, 144, -1, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, -1, 157, -1, 159, + 160, 161, 162, -1, 164, -1, 166, -1, -1, -1, + 170, 171, 172, -1, 174, -1, 176, -1, 178, 179, + 180, -1, 182, 183, 184, 185, 186, 187, 188, -1, + 190, 191, 192, 193, -1, 195, 196, 197, 198, 199, + 200, -1, 202, -1, 204, 205, 206, 207, 208, 209, + 210, 211, -1, 213, -1, 215, -1, -1, 218, -1, + 220, 221, 222, 223, 224, -1, -1, 227, -1, 229, + -1, -1, 232, 233, 234, -1, -1, 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, -1, 263, 264, 265, 266, 267, -1, 269, + 270, -1, 272, -1, 274, 275, 276, 277, 278, 279, + -1, 281, 282, -1, -1, 285, 286, 287, -1, -1, + 290, 291, -1, 293, -1, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, -1, 307, 308, 309, + 310, 311, 312, 313, 314, 315, -1, 317, 318, 319, + 320, 321, 322, -1, 324, 325, 326, 327, 328, 329, + 330, 331, -1, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 343, 344, 345, -1, 347, 348, -1, + 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, + 360, 361, 362, 363, 364, -1, 366, 367, 368, 369, + 370, -1, 372, 373, 374, 375, 376, -1, 378, 379, + 380, 381, -1, 383, 384, 385, 386, 387, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, -1, 399, + 400, -1, 402, -1, 404, 405, 406, 407, 408, -1, + 410, 411, -1, -1, 414, 415, 416, 417, 418, -1, + 420, 421, 422, 423, 424, 425, 426, 427, -1, -1, + 430, 431, 432, 433, 434, -1, -1, 437, 438, 439, + 440, 441, 442, 443, -1, 445, -1, 447, 448, 449, + 450, -1, -1, 453, -1, -1, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 473, 474, 475, 476, 3, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 19, 20, 21, 22, 23, 24, 25, + 26, -1, 28, 29, 30, -1, -1, -1, -1, -1, + -1, -1, 38, 39, -1, 41, 42, 43, -1, 45, + 46, 47, 48, 49, -1, 51, 52, -1, 54, 55, + 56, 57, 58, 59, -1, -1, 62, 63, 64, 65, + 66, -1, 68, 69, 70, 71, 72, -1, -1, -1, + 76, 77, 78, 79, 80, 81, -1, 83, 84, 85, + -1, 87, 88, 89, 90, 91, 92, -1, -1, 95, + 96, 97, -1, -1, -1, -1, -1, -1, -1, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, -1, + 116, -1, 118, 119, 120, 121, 122, 123, -1, 125, + 126, 127, 128, 129, -1, -1, 132, 133, 134, 135, + 136, -1, 138, 139, 140, -1, 142, 143, 144, -1, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, + -1, 157, -1, 159, 160, 161, 162, -1, 164, -1, + 166, -1, -1, -1, 170, 171, 172, -1, 174, -1, + 176, -1, 178, 179, 180, -1, 182, 183, 184, 185, + 186, 187, 188, -1, 190, 191, 192, 193, -1, 195, + 196, 197, 198, 199, 200, -1, 202, -1, 204, 205, + 206, 207, 208, 209, 210, 211, -1, 213, -1, 215, + -1, -1, 218, -1, 220, 221, 222, 223, 224, -1, + -1, 227, -1, 229, -1, -1, 232, 233, 234, -1, + -1, 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, -1, 263, 264, 265, + 266, 267, -1, 269, 270, -1, 272, -1, 274, 275, + 276, 277, 278, 279, -1, 281, 282, -1, -1, 285, + 286, 287, -1, -1, 290, 291, -1, 293, -1, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + -1, 307, 308, 309, 310, 311, 312, 313, 314, 315, + -1, 317, 318, 319, 320, 321, 322, -1, 324, 325, + 326, 327, 328, 329, 330, 331, -1, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, + -1, 347, 348, -1, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 361, 362, 363, 364, -1, + 366, 367, 368, 369, 370, -1, 372, 373, 374, 375, + 376, -1, 378, 379, 380, 381, -1, 383, 384, 385, + 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, -1, 399, 400, -1, 402, -1, 404, 405, + 406, 407, 408, -1, 410, 411, -1, -1, 414, 415, + 416, 417, 418, -1, 420, 421, 422, 423, 424, 425, + 426, 427, -1, -1, 430, 431, 432, 433, 434, -1, + -1, 437, 438, 439, 440, 441, 442, 443, -1, 445, + -1, 447, 448, 449, 450, -1, -1, 453, -1, -1, + 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, + 476, 3, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 19, 20, 21, + 22, 23, 24, 25, 26, -1, 28, 29, 30, -1, + -1, -1, -1, -1, -1, -1, 38, 39, -1, 41, + 42, 43, -1, 45, 46, 47, 48, 49, -1, 51, + 52, -1, 54, 55, 56, 57, 58, 59, -1, -1, + 62, 63, 64, 65, 66, -1, 68, 69, 70, 71, + 72, -1, -1, -1, 76, 77, 78, 79, 80, 81, + -1, 83, 84, 85, -1, 87, 88, 89, 90, 91, + 92, -1, -1, 95, 96, 97, -1, -1, -1, -1, + -1, -1, -1, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, -1, 116, -1, 118, 119, 120, 121, + 122, 123, -1, 125, 126, 127, 128, 129, -1, -1, + 132, 133, 134, 135, 136, -1, 138, 139, 140, -1, + 142, 143, 144, -1, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, -1, 157, -1, 159, 160, 161, + 162, -1, 164, -1, 166, -1, -1, -1, 170, 171, + 172, -1, 174, -1, 176, -1, 178, 179, 180, -1, + 182, 183, 184, 185, 186, 187, 188, -1, 190, 191, + 192, 193, -1, 195, 196, 197, 198, 199, 200, -1, + 202, -1, 204, 205, 206, 207, 208, 209, 210, 211, + -1, 213, -1, 215, -1, -1, 218, -1, 220, 221, + 222, 223, 224, -1, -1, 227, -1, 229, -1, -1, + 232, 233, 234, -1, -1, 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, + -1, 263, 264, 265, 266, 267, -1, 269, 270, -1, + 272, -1, 274, 275, 276, 277, 278, 279, -1, 281, + 282, -1, -1, 285, 286, 287, -1, -1, 290, 291, + -1, 293, -1, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, -1, 307, 308, 309, 310, 311, + 312, 313, 314, 315, -1, 317, 318, 319, 320, 321, + 322, -1, 324, 325, 326, 327, 328, 329, 330, 331, + -1, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 343, 344, 345, -1, 347, 348, -1, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, -1, 366, 367, 368, 369, 370, -1, + 372, 373, 374, 375, 376, -1, 378, 379, 380, 381, + -1, 383, 384, 385, 386, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, -1, 399, 400, -1, + 402, -1, 404, 405, 406, 407, 408, -1, 410, 411, + -1, -1, 414, 415, 416, 417, 418, -1, 420, 421, + 422, 423, 424, 425, 426, 427, -1, -1, 430, 431, + 432, 433, 434, -1, -1, 437, 438, 439, 440, 441, + 442, 443, -1, 445, -1, 447, 448, 449, 450, -1, + -1, 453, -1, -1, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 473, 474, 475, 476, 3, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 19, 20, 21, 22, 23, 24, 25, 26, -1, + 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, + 38, 39, -1, 41, 42, 43, -1, 45, 46, 47, + 48, 49, -1, 51, 52, -1, 54, 55, 56, 57, + 58, 59, -1, -1, 62, 63, 64, 65, 66, -1, + 68, 69, 70, 71, 72, -1, -1, -1, 76, 77, + 78, 79, 80, 81, -1, 83, 84, 85, -1, 87, + 88, 89, 90, 91, 92, -1, -1, 95, 96, 97, + -1, -1, -1, -1, -1, -1, -1, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, -1, 116, -1, + 118, 119, 120, 121, 122, 123, -1, 125, 126, 127, + 128, 129, -1, -1, 132, 133, 134, 135, 136, -1, + 138, 139, 140, -1, 142, 143, 144, -1, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, -1, 157, + -1, 159, 160, 161, 162, -1, 164, -1, 166, -1, + -1, -1, 170, 171, 172, -1, 174, -1, 176, -1, + 178, 179, 180, -1, 182, 183, 184, 185, 186, 187, + 188, -1, 190, 191, 192, 193, -1, 195, 196, 197, + 198, 199, 200, -1, 202, -1, 204, 205, 206, 207, + 208, 209, 210, 211, -1, 213, -1, 215, -1, -1, + 218, -1, 220, 221, 222, 223, 224, -1, -1, 227, + -1, 229, -1, -1, 232, 233, 234, -1, -1, 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, -1, 263, 264, 265, 266, 267, + -1, 269, 270, -1, 272, -1, 274, 275, 276, 277, + 278, 279, -1, 281, 282, -1, -1, 285, 286, 287, + -1, -1, 290, 291, -1, 293, -1, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, -1, 307, + 308, 309, 310, 311, 312, 313, 314, 315, -1, 317, + 318, 319, 320, 321, 322, -1, 324, 325, 326, 327, + 328, 329, 330, 331, -1, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 343, 344, 345, -1, 347, + 348, -1, 350, 351, 352, 353, 354, 355, 356, 357, + 358, 359, 360, 361, 362, 363, 364, -1, 366, 367, + 368, 369, 370, -1, 372, 373, 374, 375, 376, -1, + 378, 379, 380, 381, -1, 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + -1, 399, 400, -1, 402, -1, 404, 405, 406, 407, + 408, -1, 410, 411, -1, -1, 414, 415, 416, 417, + 418, -1, 420, 421, 422, 423, 424, 425, 426, 427, + -1, -1, 430, 431, 432, 433, 434, -1, -1, 437, + 438, 439, 440, 441, 442, 443, -1, 445, -1, 447, + 448, 449, 450, -1, -1, 453, -1, -1, 456, 457, + 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 473, 474, 475, 476, 3, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 19, 20, 21, 22, 23, + 24, 25, 26, -1, 28, 29, 30, -1, -1, -1, + -1, -1, -1, -1, 38, 39, -1, 41, 42, 43, + -1, 45, 46, 47, 48, 49, -1, 51, 52, -1, + 54, 55, 56, 57, 58, 59, -1, -1, 62, 63, + 64, 65, 66, -1, 68, 69, 70, 71, 72, -1, + -1, -1, 76, 77, 78, 79, 80, 81, -1, 83, + 84, 85, -1, 87, 88, 89, 90, 91, 92, -1, + -1, 95, 96, 97, -1, -1, -1, -1, -1, -1, + -1, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, -1, 116, -1, 118, 119, 120, 121, 122, 123, + -1, 125, 126, 127, 128, 129, -1, -1, 132, 133, + 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, + 144, -1, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, -1, 157, -1, 159, 160, 161, 162, -1, + 164, -1, 166, -1, -1, -1, 170, 171, 172, -1, + 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, + 184, 185, 186, 187, 188, -1, 190, 191, 192, 193, + -1, 195, 196, 197, 198, 199, 200, -1, 202, -1, + 204, 205, 206, 207, 208, 209, 210, 211, -1, 213, + -1, 215, -1, -1, 218, -1, 220, 221, 222, 223, + 224, -1, -1, 227, -1, 229, -1, -1, 232, 233, + 234, -1, -1, 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, -1, 263, + 264, 265, 266, 267, -1, 269, 270, -1, 272, -1, + 274, 275, 276, 277, 278, 279, -1, 281, 282, -1, + -1, 285, 286, 287, -1, -1, 290, 291, -1, 293, + -1, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, -1, 307, 308, 309, 310, 311, 312, 313, + 314, 315, -1, 317, 318, 319, 320, 321, 322, -1, + 324, 325, 326, 327, 328, 329, 330, 331, -1, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, + 344, 345, -1, 347, 348, -1, 350, 351, 352, 353, + 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, + 364, -1, 366, 367, 368, 369, 370, -1, 372, 373, + 374, 375, 376, -1, 378, 379, 380, 381, -1, 383, + 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, -1, 399, 400, -1, 402, -1, + 404, 405, 406, 407, 408, -1, 410, 411, -1, -1, + 414, 415, 416, 417, 418, -1, 420, 421, 422, 423, + 424, 425, 426, 427, -1, -1, 430, 431, 432, 433, + 434, -1, -1, 437, 438, 439, 440, 441, 442, 443, + -1, 445, -1, 447, 448, 449, 450, -1, -1, 453, + -1, -1, 456, 457, 458, 459, 460, 461, 462, 463, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, + 474, 475, 476, 3, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, + 20, 21, 22, 23, 24, 25, 26, -1, 28, 29, + 30, -1, -1, -1, -1, -1, -1, -1, 38, 39, + -1, 41, 42, 43, -1, 45, 46, 47, 48, 49, + -1, 51, 52, -1, 54, 55, 56, 57, 58, 59, + -1, -1, 62, 63, 64, 65, 66, -1, 68, 69, + 70, 71, 72, -1, -1, -1, 76, 77, 78, 79, + 80, 81, -1, 83, 84, 85, -1, 87, 88, 89, + 90, 91, 92, -1, -1, 95, 96, 97, -1, -1, + -1, -1, -1, -1, -1, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, -1, 116, -1, 118, 119, + 120, 121, 122, 123, -1, 125, 126, 127, 128, 129, + -1, -1, 132, 133, 134, 135, 136, -1, 138, 139, + 140, -1, 142, 143, 144, -1, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, -1, 157, -1, 159, + 160, 161, 162, -1, 164, -1, 166, -1, -1, -1, + 170, 171, 172, -1, 174, -1, 176, -1, 178, 179, + 180, -1, 182, 183, 184, 185, 186, 187, 188, -1, + 190, 191, 192, 193, -1, 195, 196, 197, 198, 199, + 200, -1, 202, -1, 204, 205, 206, 207, 208, 209, + 210, 211, -1, 213, -1, 215, -1, -1, 218, -1, + 220, 221, 222, 223, 224, -1, -1, 227, -1, 229, + -1, -1, 232, 233, 234, -1, -1, 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, -1, 263, 264, 265, 266, 267, -1, 269, + 270, -1, 272, -1, 274, 275, 276, 277, 278, 279, + -1, 281, 282, -1, -1, 285, 286, 287, -1, -1, + 290, 291, -1, 293, -1, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, -1, 307, 308, 309, + 310, 311, 312, 313, 314, 315, -1, 317, 318, 319, + 320, 321, 322, -1, 324, 325, 326, 327, 328, 329, + 330, 331, -1, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 343, 344, 345, -1, 347, 348, -1, + 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, + 360, 361, 362, 363, 364, -1, 366, 367, 368, 369, + 370, -1, 372, 373, 374, 375, 376, -1, 378, 379, + 380, 381, -1, 383, 384, 385, 386, 387, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, -1, 399, + 400, -1, 402, -1, 404, 405, 406, 407, 408, -1, + 410, 411, -1, -1, 414, 415, 416, 417, 418, -1, + 420, 421, 422, 423, 424, 425, 426, 427, -1, -1, + 430, 431, 432, 433, 434, -1, -1, 437, 438, 439, + 440, 441, 442, 443, -1, 445, -1, 447, 448, 449, + 450, -1, -1, 453, -1, -1, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 473, 474, 475, 476, 3, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 19, 20, 21, 22, 23, 24, 25, + 26, -1, 28, 29, 30, -1, -1, -1, -1, -1, + -1, -1, 38, 39, -1, 41, 42, 43, -1, 45, + 46, 47, 48, 49, -1, 51, 52, -1, 54, 55, + 56, 57, 58, 59, -1, -1, 62, 63, 64, 65, + 66, -1, 68, 69, 70, 71, 72, -1, -1, -1, + 76, 77, 78, 79, 80, 81, -1, 83, 84, 85, + -1, 87, 88, 89, 90, 91, 92, -1, -1, 95, + 96, 97, -1, -1, -1, -1, -1, -1, -1, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, -1, + 116, -1, 118, 119, 120, 121, 122, 123, -1, 125, + 126, 127, 128, 129, -1, -1, 132, 133, 134, 135, + 136, -1, 138, 139, 140, -1, 142, 143, 144, -1, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, + -1, 157, -1, 159, 160, 161, 162, -1, 164, -1, + 166, -1, -1, -1, 170, 171, 172, -1, 174, -1, + 176, -1, 178, 179, 180, -1, 182, 183, 184, 185, + 186, 187, 188, -1, 190, 191, 192, 193, -1, 195, + 196, 197, 198, 199, 200, -1, 202, -1, 204, 205, + 206, 207, 208, 209, 210, 211, -1, 213, -1, 215, + -1, -1, 218, -1, 220, 221, 222, 223, 224, -1, + -1, 227, -1, 229, -1, -1, 232, 233, 234, -1, + -1, 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, -1, 263, 264, 265, + 266, 267, -1, 269, 270, -1, 272, -1, 274, 275, + 276, 277, 278, 279, -1, 281, 282, -1, -1, 285, + 286, 287, -1, -1, 290, 291, -1, 293, -1, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + -1, 307, 308, 309, 310, 311, 312, 313, 314, 315, + -1, 317, 318, 319, 320, 321, 322, -1, 324, 325, + 326, 327, 328, 329, 330, 331, -1, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, + -1, 347, 348, -1, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 361, 362, 363, 364, -1, + 366, 367, 368, 369, 370, -1, 372, 373, 374, 375, + 376, -1, 378, 379, 380, 381, -1, 383, 384, 385, + 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, -1, 399, 400, -1, 402, -1, 404, 405, + 406, 407, 408, -1, 410, 411, -1, -1, 414, 415, + 416, 417, 418, -1, 420, 421, 422, 423, 424, 425, + 426, 427, -1, -1, 430, 431, 432, 433, 434, -1, + -1, 437, 438, 439, 440, 441, 442, 443, -1, 445, + -1, 447, 448, 449, 450, -1, -1, 453, -1, -1, + 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, + 476, 3, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 19, 20, 21, + 22, 23, 24, 25, 26, -1, 28, 29, 30, -1, + -1, -1, -1, -1, 36, -1, 38, 39, -1, 41, + 42, 43, -1, 45, 46, 47, 48, 49, -1, 51, + 52, -1, 54, 55, 56, 57, 58, 59, -1, -1, + 62, 63, 64, 65, 66, -1, 68, 69, 70, 71, + 72, -1, -1, -1, 76, 77, 78, 79, 80, 81, + -1, 83, 84, 85, -1, 87, 88, 89, 90, 91, + 92, -1, -1, 95, 96, 97, -1, -1, -1, -1, + -1, -1, -1, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, -1, 116, -1, 118, 119, 120, 121, + 122, 123, -1, 125, 126, 127, 128, 129, -1, -1, + 132, 133, 134, 135, 136, -1, 138, 139, 140, -1, + 142, 143, 144, -1, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, -1, 157, -1, 159, 160, 161, + 162, -1, 164, -1, 166, -1, -1, -1, 170, 171, + 172, -1, 174, -1, 176, -1, 178, 179, 180, -1, + 182, 183, 184, 185, 186, 187, 188, -1, 190, 191, + 192, 193, -1, 195, 196, 197, 198, 199, 200, -1, + 202, -1, 204, 205, 206, 207, 208, 209, 210, 211, + -1, 213, -1, 215, -1, -1, 218, -1, 220, 221, + 222, 223, 224, -1, -1, 227, -1, 229, -1, -1, + 232, 233, 234, -1, -1, 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, + -1, 263, 264, 265, 266, 267, -1, 269, 270, -1, + 272, -1, 274, 275, 276, 277, 278, 279, -1, 281, + 282, -1, -1, 285, 286, 287, -1, -1, 290, 291, + -1, 293, -1, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, -1, 307, 308, 309, 310, 311, + 312, 313, 314, 315, -1, 317, 318, 319, 320, 321, + 322, -1, 324, 325, 326, 327, 328, 329, 330, 331, + -1, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 343, 344, 345, -1, 347, 348, -1, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, -1, 366, 367, 368, 369, 370, -1, + -1, 373, 374, 375, 376, -1, 378, 379, 380, 381, + -1, 383, 384, 385, 386, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, -1, 399, 400, -1, + 402, -1, 404, 405, 406, 407, 408, -1, 410, 411, + -1, -1, 414, 415, 416, 417, 418, -1, 420, 421, + 422, 423, 424, 425, 426, 427, -1, -1, 430, 431, + 432, 433, 434, -1, -1, 437, 438, 439, 440, 441, + 442, 443, -1, 445, -1, 447, 448, 449, 450, -1, + -1, 453, -1, -1, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 473, 474, 475, 476, 3, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 19, 20, 21, 22, 23, 24, 25, 26, -1, + 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, + 38, 39, -1, 41, 42, 43, -1, 45, 46, 47, + 48, 49, -1, 51, 52, -1, 54, 55, 56, 57, + 58, 59, -1, -1, 62, 63, 64, 65, 66, -1, + 68, 69, 70, 71, 72, -1, -1, -1, 76, 77, + 78, 79, 80, 81, -1, 83, 84, 85, -1, 87, + 88, 89, 90, 91, 92, -1, -1, 95, 96, 97, + -1, -1, -1, -1, -1, -1, -1, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, -1, 116, -1, + 118, 119, 120, 121, 122, 123, -1, 125, 126, 127, + 128, 129, -1, -1, 132, 133, 134, 135, 136, -1, + 138, 139, 140, -1, 142, 143, 144, -1, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, -1, 157, + -1, 159, 160, 161, 162, -1, 164, -1, 166, -1, + -1, -1, 170, 171, 172, -1, 174, -1, 176, -1, + 178, 179, 180, -1, 182, 183, 184, 185, 186, 187, + 188, -1, 190, 191, 192, 193, -1, 195, 196, 197, + 198, 199, 200, -1, 202, -1, 204, 205, 206, 207, + 208, 209, 210, 211, -1, 213, -1, 215, -1, -1, + 218, -1, 220, 221, 222, 223, 224, -1, -1, 227, + -1, 229, -1, -1, 232, 233, 234, -1, -1, 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, -1, 263, 264, 265, 266, 267, + -1, 269, 270, -1, 272, -1, 274, 275, 276, 277, + 278, 279, -1, 281, 282, -1, -1, 285, 286, 287, + -1, -1, 290, 291, -1, 293, -1, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, -1, 307, + 308, 309, 310, 311, 312, 313, 314, 315, -1, 317, + 318, 319, 320, 321, 322, -1, 324, 325, 326, 327, + 328, 329, 330, 331, -1, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 343, 344, 345, -1, 347, + 348, -1, 350, 351, 352, 353, 354, 355, 356, 357, + 358, 359, 360, 361, 362, 363, 364, -1, 366, 367, + 368, 369, 370, -1, 372, 373, 374, 375, 376, -1, + 378, 379, 380, 381, -1, 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + -1, 399, 400, -1, 402, -1, 404, 405, 406, 407, + 408, -1, 410, 411, -1, -1, 414, 415, 416, 417, + 418, -1, 420, 421, 422, 423, 424, 425, 426, 427, + -1, -1, 430, 431, 432, 433, 434, -1, -1, 437, + 438, 439, 440, 441, 442, 443, -1, 445, -1, 447, + 448, 449, 450, -1, -1, 453, -1, -1, 456, 457, + 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 473, 474, 475, 476, 3, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 19, 20, 21, 22, 23, + 24, 25, 26, -1, 28, 29, 30, -1, -1, -1, + -1, -1, -1, -1, 38, 39, -1, 41, 42, 43, + -1, 45, 46, 47, 48, 49, -1, 51, 52, -1, + 54, 55, 56, 57, 58, 59, -1, -1, 62, 63, + 64, 65, 66, -1, 68, 69, 70, 71, 72, -1, + -1, -1, 76, 77, 78, 79, 80, 81, -1, 83, + 84, 85, -1, 87, 88, 89, 90, 91, 92, -1, + -1, 95, 96, 97, -1, -1, -1, -1, -1, -1, + -1, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, -1, 116, -1, 118, 119, 120, 121, 122, 123, + -1, 125, 126, 127, 128, 129, -1, -1, 132, 133, + 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, + 144, -1, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, -1, 157, -1, 159, 160, 161, 162, -1, + 164, -1, 166, -1, -1, -1, 170, 171, 172, -1, + 174, -1, 176, -1, 178, 179, 180, -1, 182, 183, + 184, 185, 186, 187, 188, -1, 190, 191, 192, 193, + -1, 195, 196, 197, 198, 199, 200, -1, 202, -1, + 204, 205, 206, 207, 208, 209, 210, 211, -1, 213, + -1, 215, -1, -1, 218, -1, 220, 221, 222, 223, + 224, -1, -1, 227, -1, 229, -1, -1, 232, 233, + 234, -1, -1, 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, -1, 263, + 264, 265, 266, 267, -1, 269, 270, -1, 272, -1, + 274, 275, 276, 277, 278, 279, -1, 281, 282, -1, + -1, 285, 286, 287, -1, -1, 290, 291, -1, 293, + -1, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, -1, 307, 308, 309, 310, 311, 312, 313, + 314, 315, -1, 317, 318, 319, 320, 321, 322, -1, + 324, 325, 326, 327, 328, 329, 330, 331, -1, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, + 344, 345, -1, 347, 348, -1, 350, 351, 352, 353, + 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, + 364, -1, 366, 367, 368, 369, 370, -1, 372, 373, + 374, 375, 376, -1, 378, 379, 380, 381, -1, 383, + 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, -1, 399, 400, -1, 402, -1, + 404, 405, 406, 407, 408, -1, 410, 411, -1, -1, + 414, 415, 416, 417, 418, -1, 420, 421, 422, 423, + 424, 425, 426, 427, -1, -1, 430, 431, 432, 433, + 434, -1, -1, 437, 438, 439, 440, 441, 442, 443, + -1, 445, -1, 447, 448, 449, 450, -1, -1, 453, + -1, -1, 456, 457, 458, 459, 460, 461, 462, 463, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, + 474, 475, 476, 3, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, + 20, 21, 22, 23, 24, 25, 26, -1, 28, 29, + 30, -1, -1, -1, -1, -1, -1, -1, 38, 39, + -1, 41, 42, 43, -1, 45, 46, 47, 48, 49, + -1, 51, 52, -1, 54, 55, 56, 57, 58, 59, + -1, -1, 62, 63, 64, 65, 66, -1, 68, 69, + 70, 71, 72, -1, -1, -1, 76, 77, 78, 79, + 80, 81, -1, 83, 84, 85, -1, 87, 88, 89, + 90, 91, 92, -1, -1, 95, 96, 97, -1, -1, + -1, -1, -1, -1, -1, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, -1, 116, -1, 118, 119, + 120, 121, 122, 123, -1, 125, 126, 127, 128, 129, + -1, -1, 132, 133, 134, 135, 136, -1, 138, 139, + 140, -1, 142, 143, 144, -1, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, -1, 157, -1, 159, + 160, 161, 162, -1, 164, -1, 166, -1, -1, -1, + 170, 171, 172, -1, 174, -1, 176, -1, 178, 179, + 180, -1, 182, 183, 184, 185, 186, 187, 188, -1, + 190, 191, 192, 193, -1, 195, 196, 197, 198, 199, + 200, -1, 202, -1, 204, 205, 206, 207, 208, 209, + 210, 211, -1, 213, -1, 215, -1, -1, 218, -1, + 220, 221, 222, 223, 224, -1, -1, 227, -1, 229, + -1, -1, 232, 233, 234, -1, -1, 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, -1, 263, 264, 265, 266, 267, -1, 269, + 270, -1, 272, -1, 274, 275, 276, 277, 278, 279, + -1, 281, 282, -1, -1, 285, 286, 287, -1, -1, + 290, 291, -1, 293, -1, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, -1, 307, 308, 309, + 310, 311, 312, 313, 314, 315, -1, 317, 318, 319, + 320, 321, 322, -1, 324, 325, 326, 327, 328, 329, + 330, 331, -1, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 343, 344, 345, -1, 347, 348, -1, + 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, + 360, 361, 362, 363, 364, -1, 366, 367, 368, 369, + 370, -1, 372, 373, 374, 375, 376, -1, 378, 379, + 380, 381, -1, 383, 384, 385, 386, 387, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, -1, 399, + 400, -1, 402, -1, 404, 405, 406, 407, 408, -1, + 410, 411, -1, -1, 414, 415, 416, 417, 418, -1, + 420, 421, 422, 423, 424, 425, 426, 427, -1, -1, + 430, 431, 432, 433, 434, -1, -1, 437, 438, 439, + 440, 441, 442, 443, -1, 445, -1, 447, 448, 449, + 450, -1, -1, 453, -1, -1, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 473, 474, 475, 476, 3, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 19, 20, 21, 22, 23, 24, 25, + 26, -1, 28, 29, 30, -1, -1, -1, -1, -1, + -1, -1, 38, 39, -1, 41, 42, 43, -1, 45, + 46, 47, 48, 49, -1, 51, 52, -1, 54, 55, + 56, 57, 58, 59, -1, -1, 62, 63, 64, 65, + 66, -1, 68, 69, 70, 71, 72, -1, -1, -1, + 76, 77, 78, 79, 80, 81, -1, 83, 84, 85, + -1, 87, 88, 89, 90, 91, 92, -1, -1, 95, + 96, 97, -1, -1, -1, -1, -1, -1, -1, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, -1, + 116, -1, 118, 119, 120, 121, 122, 123, -1, 125, + 126, 127, 128, 129, -1, -1, 132, 133, 134, 135, + 136, -1, 138, 139, 140, -1, 142, 143, 144, -1, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, + -1, 157, -1, 159, 160, 161, 162, -1, 164, -1, + 166, -1, -1, -1, 170, 171, 172, -1, 174, -1, + 176, -1, 178, 179, 180, -1, 182, 183, 184, 185, + 186, 187, 188, -1, 190, 191, 192, 193, -1, 195, + 196, 197, 198, 199, 200, -1, 202, -1, 204, 205, + 206, 207, 208, 209, 210, 211, -1, 213, -1, 215, + -1, -1, 218, -1, 220, 221, 222, 223, 224, -1, + -1, 227, -1, 229, -1, -1, 232, 233, 234, -1, + -1, 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, -1, 263, 264, 265, + 266, 267, -1, 269, 270, -1, 272, -1, 274, 275, + 276, 277, 278, 279, -1, 281, 282, -1, -1, 285, + 286, 287, -1, -1, 290, 291, -1, 293, -1, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + -1, 307, 308, 309, 310, 311, 312, 313, 314, 315, + -1, 317, 318, 319, 320, 321, 322, -1, 324, 325, + 326, 327, 328, 329, 330, 331, -1, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, + -1, 347, 348, -1, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 361, 362, 363, 364, -1, + 366, 367, 368, 369, 370, -1, 372, 373, 374, 375, + 376, -1, 378, 379, 380, 381, -1, 383, 384, 385, + 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, -1, 399, 400, -1, 402, -1, 404, 405, + 406, 407, 408, -1, 410, 411, -1, -1, 414, 415, + 416, 417, 418, -1, 420, 421, 422, 423, 424, 425, + 426, 427, -1, -1, 430, 431, 432, 433, 434, -1, + -1, 437, 438, 439, 440, 441, 442, 443, -1, 445, + -1, 447, 448, 449, 450, -1, -1, 453, -1, -1, + 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, + 476, 3, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 19, 20, 21, + 22, 23, 24, 25, 26, -1, 28, 29, 30, -1, + -1, -1, -1, -1, -1, -1, 38, 39, -1, 41, + 42, 43, -1, 45, 46, 47, 48, 49, -1, 51, + 52, -1, 54, 55, 56, 57, 58, 59, -1, -1, + 62, 63, 64, 65, 66, -1, 68, 69, 70, 71, + 72, -1, -1, -1, 76, 77, 78, 79, 80, 81, + -1, 83, 84, 85, -1, 87, 88, 89, 90, 91, + 92, -1, -1, 95, 96, 97, -1, -1, -1, -1, + -1, -1, -1, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, -1, 116, -1, 118, 119, 120, 121, + 122, 123, -1, 125, 126, 127, 128, 129, -1, -1, + 132, 133, 134, 135, 136, -1, 138, 139, 140, -1, + 142, 143, 144, -1, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, -1, 157, -1, 159, 160, 161, + 162, -1, 164, -1, 166, -1, -1, -1, 170, 171, + 172, -1, 174, -1, 176, -1, 178, 179, 180, -1, + 182, 183, 184, 185, 186, 187, 188, -1, 190, 191, + 192, 193, -1, 195, 196, 197, 198, 199, 200, -1, + 202, -1, 204, 205, 206, 207, 208, 209, 210, 211, + -1, 213, -1, 215, -1, -1, 218, -1, 220, 221, + 222, 223, 224, -1, -1, 227, -1, 229, -1, -1, + 232, 233, 234, -1, -1, 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, + -1, 263, 264, 265, 266, 267, -1, 269, 270, -1, + 272, -1, 274, 275, 276, 277, 278, 279, -1, 281, + 282, -1, -1, 285, 286, 287, -1, -1, 290, 291, + -1, 293, -1, 295, 296, 297, 298, 299, 300, 301, + -1, 303, 304, 305, -1, 307, 308, 309, 310, 311, + 312, 313, 314, 315, -1, 317, 318, 319, 320, 321, + 322, -1, 324, -1, 326, 327, 328, 329, 330, 331, + -1, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 343, 344, 345, -1, 347, 348, -1, 350, 351, + 352, 353, -1, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, -1, 366, 367, 368, 369, 370, -1, + 372, 373, 374, 375, 376, -1, 378, 379, 380, 381, + -1, 383, 384, 385, 386, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, -1, 399, 400, -1, + 402, -1, 404, 405, 406, 407, 408, -1, 410, 411, + -1, -1, 414, 415, 416, 417, 418, -1, 420, 421, + 422, 423, 424, 425, 426, 427, -1, -1, 430, 431, + 432, 433, 434, -1, -1, 437, 438, 439, 440, 441, + 442, 443, -1, 445, -1, 447, 448, 449, 450, -1, + -1, 453, -1, -1, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 473, 474, 475, 476, 3, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 19, 20, 21, 22, 23, 24, 25, 26, -1, + 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, + 38, 39, -1, 41, 42, 43, 44, 45, 46, 47, + -1, 49, 50, 51, 52, -1, 54, 55, 56, 57, + 58, 59, -1, -1, 62, 63, 64, 65, 66, -1, + 68, 69, 70, 71, -1, -1, 74, -1, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 85, -1, 87, + 88, 89, 90, 91, 92, -1, 94, 95, 96, 97, + -1, -1, -1, 101, -1, -1, -1, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, -1, 116, -1, + 118, 119, 120, 121, 122, 123, -1, 125, 126, 127, + 128, 129, -1, -1, 132, 133, 134, 135, 136, -1, + 138, 139, 140, -1, 142, 143, 144, -1, 146, 147, + 148, 149, -1, 151, 152, 153, 154, -1, -1, 157, + -1, 159, 160, 161, 162, -1, 164, -1, 166, 167, + -1, 169, 170, 171, 172, 173, 174, -1, 176, -1, + -1, -1, 180, -1, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, 193, -1, 195, 196, 197, + 198, 199, 200, -1, 202, 203, -1, 205, 206, 207, + 208, 209, 210, 211, -1, 213, -1, 215, 216, 217, + 218, 219, 220, 221, 222, 223, 224, -1, -1, 227, + 228, 229, 230, -1, 232, 233, 234, -1, -1, 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, -1, + -1, 269, 270, 271, 272, -1, -1, 275, 276, 277, + 278, 279, -1, 281, 282, -1, -1, 285, 286, 287, + -1, -1, 290, -1, 292, 293, 294, -1, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, -1, 307, + 308, -1, 310, 311, -1, 313, 314, 315, -1, 317, + 318, 319, 320, 321, 322, -1, 324, 325, 326, 327, + 328, 329, 330, 331, -1, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 343, 344, 345, -1, 347, + 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, + 358, 359, 360, 361, 362, 363, 364, -1, 366, 367, + 368, 369, 370, -1, 372, 373, 374, 375, 376, 377, + 378, 379, 380, 381, -1, 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, 393, 394, 395, -1, 397, + -1, 399, 400, -1, 402, 403, 404, 405, 406, 407, + 408, -1, 410, 411, -1, -1, 414, 415, -1, 417, + -1, -1, 420, 421, 422, 423, 424, 425, 426, 427, + -1, -1, 430, 431, 432, 433, 434, -1, -1, 437, + 438, 439, 440, 441, -1, 443, -1, 445, 446, 447, + 448, 449, 450, -1, -1, 453, -1, -1, 456, 457, + 458, 459, 460, 461, 3, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 473, 474, 475, 476, -1, + 19, 20, 21, 22, 23, 24, 25, 26, -1, 28, + 29, 30, -1, -1, -1, -1, -1, -1, -1, 38, + 39, -1, 41, 42, 43, 44, 45, 46, 47, -1, + 49, 50, 51, 52, -1, 54, 55, 56, 57, 58, + 59, -1, -1, 62, 63, 64, 65, 66, -1, 68, + 69, 70, 71, -1, -1, 74, -1, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, -1, 87, 88, + 89, 90, 91, 92, -1, 94, 95, 96, 97, -1, + -1, -1, 101, -1, -1, -1, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, -1, 116, -1, 118, + 119, 120, 121, 122, 123, -1, 125, 126, 127, 128, + 129, -1, -1, 132, 133, 134, 135, 136, -1, 138, + 139, 140, -1, 142, 143, 144, -1, 146, 147, 148, + 149, -1, 151, 152, 153, 154, -1, -1, 157, -1, + 159, 160, 161, 162, -1, 164, -1, 166, 167, -1, + 169, 170, 171, 172, 173, 174, -1, 176, -1, -1, + -1, 180, -1, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, -1, 195, 196, 197, 198, + 199, 200, -1, 202, 203, -1, 205, 206, 207, 208, + 209, 210, 211, -1, 213, -1, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, -1, -1, 227, 228, + 229, 230, -1, 232, 233, 234, -1, -1, 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, -1, -1, + 269, 270, 271, 272, -1, -1, 275, 276, 277, 278, + 279, -1, 281, 282, -1, -1, 285, 286, 287, -1, + -1, 290, -1, 292, 293, 294, -1, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, -1, 307, 308, + -1, 310, 311, -1, 313, 314, 315, -1, 317, 318, + 319, 320, 321, 322, -1, 324, 325, 326, 327, 328, + 329, 330, 331, -1, 333, 334, 335, 336, 337, 338, + 339, 340, 341, 342, 343, 344, 345, -1, 347, 348, + 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, + 359, 360, 361, 362, 363, 364, -1, 366, 367, 368, + 369, 370, -1, 372, 373, 374, 375, 376, 377, 378, + 379, 380, 381, -1, 383, 384, 385, 386, 387, 388, + 389, 390, 391, 392, 393, 394, 395, -1, 397, -1, + 399, 400, -1, 402, 403, 404, 405, 406, 407, 408, + -1, 410, 411, -1, -1, 414, 415, -1, 417, -1, + -1, 420, 421, 422, 423, 424, 425, 426, 427, -1, + -1, 430, 431, 432, 433, 434, -1, -1, 437, 438, + 439, 440, 441, -1, 443, -1, 445, 446, 447, 448, + 449, 450, -1, -1, 453, -1, -1, 456, 457, 458, + 459, 460, 461, 3, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 473, 474, 475, 476, -1, 19, + 20, 21, 22, 23, 24, 25, 26, -1, 28, 29, + 30, -1, -1, -1, -1, -1, -1, -1, 38, 39, + -1, 41, 42, 43, 44, 45, 46, 47, -1, 49, + 50, 51, 52, -1, 54, 55, 56, 57, 58, 59, + -1, -1, 62, 63, 64, 65, 66, -1, 68, 69, + 70, 71, -1, -1, 74, -1, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, -1, 87, 88, 89, + 90, 91, 92, -1, 94, 95, 96, 97, -1, -1, + -1, 101, -1, -1, -1, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, -1, 116, -1, 118, 119, + 120, 121, 122, 123, -1, 125, 126, 127, 128, 129, + -1, -1, 132, 133, 134, 135, 136, -1, 138, 139, + 140, -1, 142, 143, 144, -1, 146, 147, 148, 149, + -1, 151, 152, 153, 154, -1, -1, 157, -1, 159, + 160, 161, 162, -1, 164, -1, 166, 167, -1, 169, + 170, 171, 172, 173, 174, -1, 176, -1, -1, -1, + 180, -1, 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 192, 193, -1, 195, 196, 197, 198, 199, + 200, -1, 202, 203, -1, 205, 206, 207, 208, 209, + 210, 211, -1, 213, -1, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, -1, -1, 227, 228, 229, + 230, -1, 232, 233, 234, -1, -1, 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, -1, -1, 269, + 270, 271, 272, -1, -1, 275, 276, 277, 278, 279, + -1, 281, 282, -1, -1, 285, 286, 287, -1, -1, + 290, -1, 292, 293, 294, -1, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, -1, 307, 308, -1, + 310, 311, -1, 313, 314, 315, -1, 317, 318, 319, + 320, 321, 322, -1, 324, 325, 326, 327, 328, 329, + 330, 331, -1, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 343, 344, 345, -1, 347, 348, 349, + 350, 351, 352, -1, 354, 355, 356, 357, 358, 359, + 360, 361, 362, 363, 364, -1, 366, 367, 368, 369, + 370, -1, 372, -1, 374, 375, 376, 377, 378, 379, + 380, 381, -1, 383, 384, 385, 386, 387, 388, 389, + 390, 391, 392, 393, 394, 395, -1, 397, -1, 399, + 400, -1, 402, 403, 404, 405, 406, 407, 408, -1, + 410, 411, -1, -1, 414, 415, -1, 417, -1, -1, + 420, 421, 422, 423, 424, 425, 426, 427, -1, -1, + 430, 431, 432, 433, 434, -1, -1, 437, 438, 439, + 440, 441, -1, 443, -1, 445, 446, 447, 448, 449, + 450, -1, -1, 453, -1, -1, 456, 457, 458, 459, + 460, 461, 3, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 473, 474, 475, 476, -1, 19, 20, 21, 22, 23, 24, 25, 26, -1, 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, 41, 42, 43, 44, 45, 46, 47, -1, 49, 50, @@ -229084,80 +245131,35 @@ static const yytype_int16 yycheck[] = 161, 162, -1, 164, -1, 166, 167, -1, 169, 170, 171, 172, 173, 174, -1, 176, -1, -1, -1, 180, -1, 182, 183, 184, 185, 186, 187, 188, 189, 190, - 191, 192, -1, 194, 195, 196, 197, 198, 199, -1, - 201, 202, -1, 204, 205, 206, 207, 208, 209, -1, - 211, -1, 213, 214, 215, 216, 217, 218, 219, 220, - 221, 222, -1, -1, 225, 226, 227, 228, -1, 230, - 231, 232, -1, -1, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, + 191, 192, 193, -1, 195, 196, 197, 198, 199, 200, + -1, 202, 203, -1, 205, 206, 207, 208, 209, 210, + 211, -1, 213, -1, 215, 216, 217, 218, 219, 220, + 221, 222, 223, 224, -1, -1, 227, 228, 229, 230, + -1, 232, 233, 234, -1, -1, 237, 238, 239, 240, + 241, -1, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, -1, -1, 267, 268, 269, 270, - -1, -1, 273, 274, 275, 276, 277, -1, 279, 280, - -1, -1, 283, 284, 285, -1, -1, 288, -1, 290, - 291, 292, -1, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, -1, 305, 306, -1, 308, 309, -1, - 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, -1, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, -1, 343, 344, 345, 346, 347, 348, -1, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - -1, 362, 363, 364, 365, 366, -1, 368, -1, 370, - 371, 372, 373, 374, 375, 376, 377, -1, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, -1, 393, -1, 395, 396, -1, 398, 399, 400, - 401, 402, 403, 404, -1, 406, 407, -1, -1, 410, - 411, -1, 413, -1, -1, 416, 417, 418, 419, 420, - 421, 422, 423, -1, -1, 426, 427, 428, 429, 430, - -1, -1, 433, 434, 435, 436, 437, -1, 439, -1, - 441, 442, 443, 444, 445, 446, -1, -1, 449, -1, - -1, 452, 453, 454, 455, 456, 457, 3, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 469, 470, - 471, 472, -1, 19, 20, 21, 22, 23, 24, 25, - 26, -1, 28, 29, 30, -1, -1, -1, -1, -1, - -1, -1, 38, 39, -1, 41, 42, 43, 44, 45, - 46, 47, -1, 49, 50, 51, 52, -1, 54, 55, - 56, 57, 58, 59, -1, -1, 62, 63, 64, 65, - 66, -1, 68, 69, 70, 71, -1, -1, 74, -1, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - -1, 87, 88, 89, 90, 91, 92, -1, 94, 95, - 96, 97, -1, -1, -1, 101, -1, -1, -1, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, -1, - 116, -1, 118, 119, 120, 121, 122, 123, -1, 125, - 126, 127, 128, 129, -1, -1, 132, 133, 134, 135, - 136, -1, 138, 139, 140, -1, 142, 143, 144, -1, - 146, 147, 148, 149, -1, 151, 152, 153, 154, -1, - -1, 157, -1, 159, 160, 161, 162, -1, 164, -1, - 166, 167, -1, 169, 170, 171, 172, 173, 174, -1, - 176, -1, -1, -1, 180, -1, 182, 183, 184, 185, - 186, 187, 188, 189, 190, 191, 192, -1, 194, 195, - 196, 197, 198, 199, -1, 201, 202, -1, 204, 205, - 206, 207, 208, 209, -1, 211, -1, 213, 214, 215, - 216, 217, 218, 219, 220, 221, 222, -1, -1, 225, - 226, 227, 228, -1, 230, 231, 232, -1, -1, 235, - 236, 237, 238, 239, -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, -1, - -1, 267, 268, 269, 270, -1, -1, 273, 274, 275, - 276, 277, -1, 279, 280, -1, -1, 283, 284, 285, - -1, -1, 288, -1, 290, 291, 292, -1, 294, 295, - 296, 297, 298, 299, 300, 301, 302, 303, -1, 305, - 306, -1, 308, 309, -1, 311, 312, 313, -1, 315, - 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, - 326, 327, 328, -1, 330, 331, 332, 333, 334, 335, - 336, 337, 338, 339, 340, 341, -1, 343, 344, 345, - 346, 347, 348, -1, 350, 351, 352, 353, 354, 355, - 356, 357, 358, 359, 360, -1, 362, 363, 364, 365, - 366, -1, 368, -1, 370, 371, 372, 373, 374, 375, - 376, 377, -1, 379, 380, 381, 382, 383, 384, 385, - 386, 387, 388, 389, -1, 391, -1, 393, -1, 395, - 396, -1, 398, 399, 400, 401, 402, 403, 404, -1, - 406, 407, -1, -1, 410, 411, -1, 413, -1, -1, - 416, 417, 418, 419, 420, 421, 422, 423, -1, -1, - 426, 427, 428, 429, 430, -1, -1, 433, 434, 435, - 436, 437, -1, 439, -1, 441, 442, 443, 444, 445, - 446, -1, -1, 449, -1, -1, 452, 453, 454, 455, - 456, 457, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 469, 470, 471, 472 + 261, 262, 263, 264, 265, 266, -1, -1, 269, 270, + 271, 272, -1, -1, 275, 276, 277, 278, 279, -1, + 281, 282, -1, -1, 285, 286, 287, -1, -1, 290, + -1, 292, 293, 294, -1, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 305, -1, 307, 308, -1, 310, + 311, -1, 313, 314, 315, -1, 317, 318, 319, 320, + 321, 322, -1, 324, 325, 326, 327, 328, 329, 330, + 331, -1, 333, 334, 335, 336, 337, 338, 339, 340, + 341, 342, 343, 344, 345, -1, 347, 348, 349, 350, + 351, 352, -1, 354, 355, 356, 357, 358, 359, 360, + 361, 362, 363, 364, -1, 366, 367, 368, 369, 370, + -1, 372, -1, 374, 375, 376, 377, 378, 379, 380, + 381, -1, 383, 384, 385, 386, 387, 388, 389, 390, + 391, 392, 393, -1, 395, -1, 397, -1, 399, 400, + -1, 402, 403, 404, 405, 406, 407, 408, -1, 410, + 411, -1, -1, 414, 415, -1, 417, -1, -1, 420, + 421, 422, 423, 424, 425, 426, 427, -1, -1, 430, + 431, 432, 433, 434, -1, -1, 437, 438, 439, 440, + 441, -1, 443, -1, 445, 446, 447, 448, 449, 450, + -1, -1, 453, -1, -1, 456, 457, 458, 459, 460, + 461, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 473, 474, 475, 476 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -229165,301 +245167,305 @@ static const yytype_int16 yycheck[] = static const yytype_uint16 yystos[] = { 0, 19, 29, 31, 32, 47, 56, 68, 79, 91, - 93, 111, 125, 135, 141, 149, 151, 152, 164, 192, - 231, 308, 311, 339, 347, 361, 368, 372, 382, 393, - 397, 433, 438, 451, 475, 489, 500, 501, 502, 503, - 514, 515, 518, 520, 524, 538, 539, 541, 543, 550, - 552, 598, 605, 608, 609, 626, 627, 628, 629, 630, - 631, 679, 816, 819, 822, 829, 830, 831, 832, 833, - 840, 844, 850, 852, 857, 861, 862, 865, 866, 868, - 869, 871, 410, 454, 551, 196, 354, 362, 397, 444, - 551, 3, 19, 20, 21, 22, 23, 24, 25, 26, - 28, 29, 30, 38, 39, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 54, 55, 56, - 57, 58, 59, 62, 63, 64, 65, 66, 68, 69, - 70, 71, 72, 74, 76, 77, 78, 79, 80, 81, - 82, 83, 84, 85, 87, 88, 89, 90, 91, 92, - 94, 95, 96, 97, 101, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 116, 118, 119, 120, 121, - 122, 123, 125, 126, 127, 128, 129, 132, 133, 134, - 135, 136, 138, 139, 140, 142, 143, 144, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, 157, 159, - 160, 161, 162, 164, 166, 167, 169, 170, 171, 172, - 173, 174, 176, 178, 179, 180, 182, 183, 184, 185, - 186, 187, 188, 189, 190, 191, 192, 194, 195, 196, - 197, 198, 199, 201, 202, 203, 204, 205, 206, 207, - 208, 209, 211, 213, 214, 215, 216, 217, 218, 219, - 220, 221, 222, 225, 226, 227, 228, 230, 231, 232, - 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, 267, 268, 269, 270, 272, 273, 274, 275, 276, - 277, 279, 280, 283, 284, 285, 288, 289, 290, 291, - 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, - 302, 303, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 315, 316, 317, 318, 319, 320, 321, 322, 323, - 324, 325, 326, 327, 328, 330, 331, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 343, 344, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 357, 358, 359, 360, 362, 363, 364, 365, 366, - 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, - 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, - 389, 390, 391, 392, 393, 395, 396, 398, 399, 400, - 401, 402, 403, 404, 406, 407, 410, 411, 412, 413, - 414, 416, 417, 418, 419, 420, 421, 422, 423, 426, - 427, 428, 429, 430, 433, 434, 435, 436, 437, 438, - 439, 441, 442, 443, 444, 445, 446, 449, 452, 453, - 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 471, 472, 735, - 801, 805, 808, 874, 875, 876, 551, 50, 489, 621, - 170, 174, 232, 239, 286, 354, 401, 403, 419, 425, - 428, 596, 606, 828, 3, 27, 240, 311, 390, 799, - 805, 874, 21, 74, 90, 144, 153, 165, 170, 196, - 239, 243, 306, 320, 351, 354, 362, 365, 384, 397, - 404, 413, 419, 444, 599, 600, 603, 551, 799, 93, - 442, 489, 520, 608, 626, 836, 840, 857, 871, 108, - 68, 108, 5, 804, 851, 805, 799, 27, 406, 410, - 805, 863, 864, 867, 551, 27, 130, 638, 639, 174, - 232, 354, 366, 406, 845, 846, 867, 551, 438, 626, - 631, 867, 5, 282, 690, 797, 805, 806, 169, 489, - 854, 489, 327, 632, 633, 799, 632, 627, 628, 0, - 492, 120, 206, 430, 145, 210, 287, 424, 640, 641, - 627, 629, 630, 493, 442, 834, 27, 406, 410, 626, - 867, 187, 797, 799, 187, 797, 187, 690, 187, 797, - 489, 487, 491, 783, 785, 520, 608, 626, 818, 857, - 797, 401, 403, 401, 403, 337, 187, 805, 805, 810, - 327, 362, 397, 444, 797, 196, 27, 799, 245, 413, - 107, 397, 444, 357, 3, 44, 49, 50, 51, 52, - 64, 65, 74, 82, 94, 101, 112, 113, 134, 161, - 167, 169, 173, 187, 188, 202, 208, 209, 211, 214, - 215, 217, 226, 228, 240, 259, 260, 261, 269, 274, - 290, 292, 324, 345, 349, 369, 373, 376, 390, 399, - 406, 407, 418, 439, 442, 604, 701, 702, 704, 706, - 708, 710, 712, 713, 714, 716, 717, 718, 720, 721, - 809, 874, 877, 187, 601, 810, 187, 798, 799, 187, - 799, 489, 542, 596, 836, 3, 48, 49, 51, 52, - 64, 65, 72, 112, 113, 150, 155, 161, 178, 179, - 203, 208, 209, 211, 240, 259, 261, 265, 272, 274, - 289, 293, 307, 310, 324, 349, 369, 376, 390, 392, - 406, 407, 412, 414, 418, 438, 439, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 837, 839, - 840, 842, 843, 874, 878, 834, 804, 804, 478, 489, - 489, 817, 472, 216, 491, 281, 4, 6, 7, 8, - 9, 10, 35, 49, 51, 52, 60, 61, 64, 65, - 72, 74, 98, 99, 100, 101, 102, 103, 104, 112, - 113, 115, 150, 155, 156, 161, 178, 179, 208, 209, - 211, 233, 234, 259, 261, 266, 271, 272, 274, 283, - 293, 307, 324, 349, 367, 376, 392, 406, 407, 412, - 414, 415, 418, 431, 439, 473, 480, 481, 482, 487, - 489, 494, 496, 497, 627, 670, 705, 708, 711, 712, - 713, 715, 716, 717, 720, 721, 732, 734, 735, 736, - 738, 751, 752, 758, 777, 782, 789, 790, 801, 802, - 803, 804, 805, 788, 789, 845, 845, 804, 845, 472, - 168, 408, 478, 489, 797, 482, 785, 3, 167, 169, - 442, 840, 853, 855, 167, 856, 732, 762, 805, 632, - 493, 489, 812, 490, 490, 502, 168, 212, 690, 858, - 27, 130, 637, 637, 54, 637, 158, 163, 229, 278, - 646, 648, 649, 672, 674, 675, 676, 640, 641, 489, - 797, 472, 216, 150, 23, 29, 135, 285, 335, 339, - 368, 435, 508, 511, 512, 335, 150, 36, 55, 106, - 195, 244, 252, 264, 295, 335, 340, 362, 368, 382, - 511, 544, 547, 150, 335, 368, 511, 150, 335, 368, - 511, 3, 27, 44, 50, 74, 82, 94, 101, 130, - 167, 169, 173, 188, 202, 214, 215, 217, 226, 228, - 240, 260, 269, 290, 292, 345, 373, 390, 399, 418, - 440, 442, 482, 490, 732, 764, 765, 807, 813, 874, - 879, 732, 784, 3, 27, 31, 32, 33, 34, 35, - 36, 37, 40, 53, 60, 61, 67, 73, 75, 86, - 93, 98, 99, 100, 102, 103, 104, 115, 117, 124, - 130, 131, 137, 141, 145, 156, 158, 163, 165, 168, - 175, 177, 181, 193, 200, 210, 212, 223, 224, 229, - 233, 234, 266, 271, 278, 281, 282, 286, 287, 304, - 314, 329, 342, 361, 367, 378, 394, 397, 405, 408, - 409, 415, 424, 425, 431, 432, 438, 440, 447, 448, - 450, 451, 800, 814, 874, 878, 880, 783, 490, 489, - 586, 596, 266, 820, 491, 811, 36, 444, 187, 797, - 187, 797, 873, 797, 489, 607, 82, 825, 455, 83, - 127, 298, 402, 441, 719, 719, 719, 489, 707, 707, - 310, 489, 709, 150, 489, 64, 65, 719, 707, 704, - 453, 475, 489, 722, 489, 722, 58, 341, 493, 602, - 489, 35, 703, 489, 109, 110, 184, 185, 246, 247, - 248, 249, 250, 251, 254, 255, 358, 359, 469, 470, - 489, 723, 724, 725, 726, 727, 728, 729, 730, 731, - 707, 150, 493, 602, 150, 493, 602, 150, 281, 762, - 397, 490, 493, 4, 156, 281, 415, 480, 481, 546, - 549, 803, 804, 835, 837, 838, 841, 836, 489, 616, - 620, 546, 841, 847, 849, 764, 702, 766, 36, 227, - 805, 489, 786, 487, 732, 781, 489, 489, 163, 489, - 489, 627, 489, 489, 489, 732, 489, 489, 489, 489, - 489, 489, 489, 489, 489, 732, 732, 732, 146, 791, - 792, 762, 763, 627, 732, 762, 753, 754, 805, 806, - 9, 786, 785, 489, 804, 489, 803, 804, 3, 8, - 11, 16, 17, 18, 33, 36, 41, 48, 73, 173, - 188, 193, 214, 215, 228, 266, 269, 283, 286, 373, - 473, 476, 477, 478, 480, 481, 482, 483, 484, 485, - 756, 757, 758, 760, 452, 739, 786, 15, 292, 732, - 15, 212, 493, 634, 489, 804, 786, 491, 785, 634, - 3, 115, 232, 546, 721, 804, 848, 97, 115, 849, - 115, 849, 797, 490, 493, 834, 490, 493, 633, 798, - 36, 858, 522, 797, 36, 805, 368, 629, 629, 642, - 643, 732, 629, 160, 263, 662, 218, 264, 323, 371, - 430, 27, 657, 732, 480, 481, 658, 659, 732, 734, - 672, 673, 649, 648, 646, 647, 163, 675, 276, 677, - 646, 672, 762, 812, 227, 797, 67, 75, 86, 165, - 187, 314, 425, 567, 577, 592, 805, 75, 86, 519, - 86, 519, 489, 408, 489, 565, 238, 428, 565, 86, - 493, 408, 797, 704, 546, 54, 548, 546, 546, 106, - 244, 252, 54, 408, 451, 475, 545, 257, 354, 545, - 547, 690, 86, 408, 519, 354, 797, 408, 354, 764, - 764, 765, 490, 493, 640, 641, 13, 14, 488, 498, - 408, 585, 590, 805, 451, 619, 327, 397, 444, 150, - 93, 539, 552, 821, 822, 869, 800, 491, 142, 797, - 266, 540, 544, 266, 489, 586, 36, 586, 490, 764, - 36, 187, 580, 805, 826, 489, 762, 803, 604, 766, - 719, 719, 35, 703, 406, 406, 803, 803, 702, 700, - 805, 487, 487, 803, 803, 408, 408, 408, 408, 601, - 810, 798, 799, 799, 810, 490, 187, 797, 873, 836, - 842, 4, 803, 4, 803, 618, 625, 814, 50, 95, - 121, 139, 143, 164, 167, 182, 271, 279, 321, 622, - 493, 490, 493, 490, 493, 818, 762, 783, 763, 447, - 778, 779, 732, 762, 489, 803, 803, 3, 723, 724, - 725, 726, 727, 728, 729, 730, 767, 768, 804, 803, - 803, 732, 8, 16, 17, 18, 476, 477, 478, 480, - 481, 482, 483, 484, 485, 756, 761, 805, 732, 769, - 480, 481, 489, 733, 734, 758, 771, 782, 490, 762, - 732, 762, 772, 732, 53, 168, 224, 409, 732, 762, - 775, 732, 489, 805, 337, 795, 488, 490, 493, 493, - 495, 498, 762, 732, 731, 731, 702, 732, 732, 732, - 732, 5, 814, 815, 406, 40, 394, 787, 810, 732, - 732, 489, 627, 776, 130, 156, 266, 271, 276, 415, - 426, 732, 271, 489, 732, 408, 48, 173, 188, 193, - 228, 373, 732, 732, 732, 732, 732, 732, 732, 732, - 732, 732, 27, 34, 378, 755, 177, 159, 740, 732, - 349, 489, 752, 732, 174, 232, 397, 401, 403, 428, - 635, 797, 790, 168, 680, 764, 482, 680, 489, 804, - 490, 797, 853, 797, 861, 732, 490, 489, 432, 860, - 115, 294, 489, 521, 626, 36, 805, 489, 526, 535, - 537, 805, 493, 37, 124, 432, 644, 349, 350, 480, - 481, 659, 661, 734, 371, 218, 282, 493, 4, 660, - 803, 660, 349, 350, 661, 796, 797, 270, 375, 678, - 673, 647, 490, 335, 511, 489, 187, 577, 799, 218, - 266, 218, 432, 489, 570, 702, 799, 805, 187, 799, - 187, 805, 23, 135, 368, 507, 510, 560, 575, 814, - 799, 569, 589, 814, 799, 508, 799, 335, 368, 511, - 544, 546, 810, 799, 546, 810, 799, 546, 335, 368, - 511, 799, 799, 799, 799, 335, 368, 511, 799, 799, - 640, 640, 640, 440, 765, 490, 732, 732, 732, 784, - 319, 615, 490, 493, 279, 168, 408, 610, 444, 797, - 797, 805, 596, 800, 489, 489, 150, 150, 228, 567, - 577, 581, 584, 593, 595, 805, 451, 453, 572, 149, - 626, 451, 827, 490, 732, 266, 281, 762, 490, 490, - 602, 490, 487, 472, 472, 490, 490, 490, 493, 702, - 803, 488, 803, 490, 490, 724, 726, 727, 728, 727, - 728, 728, 602, 602, 281, 602, 266, 36, 490, 493, - 482, 489, 546, 617, 841, 36, 614, 804, 614, 266, - 271, 321, 614, 614, 847, 702, 490, 488, 732, 137, - 779, 780, 36, 490, 732, 490, 490, 490, 168, 490, - 490, 493, 490, 491, 304, 770, 490, 733, 733, 732, - 11, 16, 17, 18, 193, 214, 283, 476, 477, 478, - 480, 481, 482, 483, 484, 485, 758, 733, 490, 490, - 163, 168, 773, 774, 490, 36, 775, 762, 775, 775, - 168, 490, 36, 798, 489, 732, 793, 786, 732, 753, - 732, 490, 490, 472, 733, 733, 143, 762, 168, 130, - 156, 271, 276, 415, 426, 489, 143, 761, 732, 394, - 787, 732, 776, 732, 408, 489, 627, 489, 489, 291, - 744, 401, 403, 401, 403, 797, 397, 636, 636, 636, - 223, 350, 489, 627, 681, 682, 683, 690, 691, 735, - 737, 738, 805, 448, 696, 640, 792, 696, 803, 731, - 812, 818, 681, 448, 859, 438, 396, 431, 530, 525, - 534, 805, 281, 527, 805, 531, 537, 493, 680, 478, - 786, 643, 283, 756, 759, 474, 645, 4, 803, 661, - 282, 430, 658, 493, 237, 408, 732, 266, 592, 489, - 150, 489, 570, 196, 590, 553, 285, 563, 553, 23, - 135, 339, 340, 368, 504, 505, 506, 512, 513, 150, - 602, 150, 602, 560, 575, 560, 490, 493, 556, 804, - 490, 493, 478, 491, 408, 354, 86, 408, 519, 354, - 408, 408, 408, 354, 490, 490, 490, 765, 488, 385, - 386, 624, 804, 585, 615, 797, 489, 586, 820, 397, - 516, 517, 804, 590, 797, 797, 873, 797, 490, 493, - 279, 565, 279, 281, 564, 799, 451, 872, 565, 36, - 150, 797, 490, 703, 803, 722, 722, 703, 805, 488, - 488, 810, 150, 618, 612, 623, 841, 804, 804, 271, - 590, 482, 590, 804, 804, 405, 732, 141, 702, 490, - 732, 732, 761, 732, 773, 702, 733, 733, 733, 733, - 130, 266, 276, 733, 733, 733, 733, 733, 733, 733, - 733, 733, 733, 732, 732, 774, 773, 702, 490, 490, - 490, 762, 702, 490, 732, 793, 794, 36, 490, 731, - 732, 33, 33, 732, 490, 732, 168, 489, 766, 732, - 490, 143, 733, 733, 143, 143, 732, 732, 641, 448, - 489, 745, 805, 636, 636, 636, 636, 797, 797, 797, - 627, 691, 168, 627, 682, 683, 36, 684, 685, 805, - 493, 94, 169, 202, 217, 226, 260, 345, 687, 685, - 36, 684, 686, 805, 475, 695, 785, 732, 177, 663, - 490, 795, 663, 490, 490, 732, 342, 529, 437, 490, - 493, 786, 84, 529, 490, 493, 526, 859, 732, 489, - 645, 160, 222, 282, 797, 799, 490, 150, 590, 577, - 590, 553, 580, 490, 117, 200, 264, 266, 576, 489, - 587, 172, 115, 186, 266, 565, 545, 107, 115, 172, - 266, 384, 387, 547, 565, 368, 506, 419, 799, 805, - 510, 589, 3, 44, 50, 74, 82, 94, 101, 167, - 169, 173, 188, 202, 214, 215, 217, 226, 228, 240, - 260, 265, 269, 283, 290, 292, 345, 369, 373, 390, - 399, 418, 442, 480, 481, 546, 554, 591, 702, 759, - 804, 807, 874, 880, 814, 799, 799, 799, 799, 799, - 799, 799, 799, 799, 799, 640, 545, 624, 489, 584, - 827, 187, 797, 490, 493, 490, 540, 489, 36, 574, - 572, 581, 79, 542, 107, 264, 626, 580, 432, 824, - 488, 702, 602, 873, 490, 493, 590, 732, 490, 490, - 774, 168, 130, 276, 489, 490, 490, 490, 493, 805, - 732, 732, 732, 766, 490, 732, 33, 33, 732, 732, - 143, 490, 490, 732, 746, 805, 797, 797, 797, 797, - 685, 686, 489, 490, 805, 806, 399, 654, 655, 489, - 682, 217, 290, 688, 682, 688, 217, 687, 688, 217, - 655, 489, 805, 655, 489, 288, 54, 181, 671, 804, - 671, 804, 789, 626, 294, 626, 525, 281, 489, 523, - 478, 537, 529, 761, 553, 577, 490, 490, 451, 583, - 118, 189, 198, 117, 434, 560, 578, 67, 73, 86, - 115, 117, 172, 200, 266, 271, 314, 329, 425, 432, - 558, 559, 571, 30, 54, 597, 187, 271, 546, 732, - 597, 271, 480, 481, 549, 805, 702, 602, 602, 240, - 390, 807, 811, 478, 408, 408, 490, 616, 432, 611, - 613, 590, 490, 36, 266, 489, 804, 827, 584, 149, - 626, 147, 194, 564, 120, 135, 313, 872, 107, 451, - 870, 281, 805, 823, 489, 36, 623, 733, 168, 489, - 766, 793, 490, 732, 732, 732, 490, 300, 747, 692, - 693, 737, 684, 489, 4, 9, 650, 652, 653, 805, - 798, 682, 281, 432, 689, 682, 217, 682, 697, 698, - 805, 489, 697, 805, 96, 178, 348, 489, 664, 665, - 666, 667, 668, 669, 732, 732, 450, 741, 741, 530, - 86, 489, 528, 536, 737, 805, 131, 732, 490, 329, - 583, 489, 573, 553, 490, 493, 489, 810, 799, 733, - 597, 118, 189, 117, 271, 218, 797, 583, 81, 115, - 36, 150, 73, 699, 811, 484, 554, 799, 799, 545, - 122, 490, 572, 626, 150, 36, 490, 799, 872, 27, - 78, 87, 116, 186, 197, 384, 387, 568, 568, 350, - 350, 59, 67, 232, 797, 536, 733, 766, 490, 54, - 640, 490, 493, 36, 694, 798, 303, 484, 303, 350, - 484, 489, 489, 490, 732, 489, 682, 689, 490, 493, - 702, 697, 490, 489, 370, 489, 490, 493, 742, 743, - 805, 432, 651, 651, 437, 799, 732, 490, 493, 73, - 532, 532, 267, 430, 797, 553, 579, 582, 814, 560, - 732, 266, 559, 36, 583, 586, 799, 186, 810, 432, - 509, 484, 419, 616, 804, 827, 564, 870, 797, 626, - 572, 542, 67, 284, 67, 824, 490, 490, 762, 322, - 350, 748, 695, 692, 489, 490, 805, 650, 798, 698, - 699, 490, 762, 489, 762, 665, 493, 36, 352, 626, - 490, 696, 528, 810, 533, 810, 533, 368, 586, 490, - 493, 478, 490, 186, 242, 594, 489, 555, 732, 419, - 36, 489, 870, 564, 872, 284, 284, 489, 827, 48, - 97, 421, 732, 749, 750, 749, 490, 697, 490, 493, - 490, 490, 490, 664, 490, 743, 745, 653, 532, 644, - 644, 535, 594, 582, 554, 264, 566, 555, 169, 299, - 374, 281, 561, 562, 588, 544, 626, 536, 696, 750, - 349, 162, 309, 162, 309, 490, 9, 336, 656, 490, - 533, 645, 645, 696, 562, 198, 120, 430, 281, 588, - 281, 561, 490, 870, 490, 33, 490, 489, 644, 553, - 58, 264, 341, 368, 557, 557, 827, 750, 9, 645, - 22, 115, 271, 696, 490 + 93, 111, 125, 135, 141, 149, 151, 152, 164, 193, + 208, 233, 310, 313, 342, 351, 365, 372, 376, 386, + 397, 401, 437, 442, 455, 479, 493, 504, 505, 506, + 507, 518, 519, 522, 524, 528, 542, 543, 545, 547, + 554, 556, 602, 609, 612, 613, 630, 631, 632, 633, + 634, 635, 685, 822, 825, 828, 835, 836, 837, 838, + 839, 846, 850, 856, 858, 863, 867, 868, 871, 872, + 874, 875, 877, 414, 458, 555, 197, 358, 366, 401, + 448, 555, 3, 19, 20, 21, 22, 23, 24, 25, + 26, 28, 29, 30, 38, 39, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 54, 55, + 56, 57, 58, 59, 62, 63, 64, 65, 66, 68, + 69, 70, 71, 72, 74, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 87, 88, 89, 90, 91, + 92, 94, 95, 96, 97, 101, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 116, 118, 119, 120, + 121, 122, 123, 125, 126, 127, 128, 129, 132, 133, + 134, 135, 136, 138, 139, 140, 142, 143, 144, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 157, + 159, 160, 161, 162, 164, 166, 167, 169, 170, 171, + 172, 173, 174, 176, 178, 179, 180, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 195, + 196, 197, 198, 199, 200, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 213, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 227, 228, 229, 230, + 232, 233, 234, 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, 269, 270, 271, 272, 274, 275, + 276, 277, 278, 279, 281, 282, 285, 286, 287, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 305, 307, 308, 309, 310, 311, + 312, 313, 314, 315, 317, 318, 319, 320, 321, 322, + 324, 325, 326, 327, 328, 329, 330, 331, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 345, 347, 348, 349, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 361, 362, 363, 364, 366, + 367, 368, 369, 370, 372, 373, 374, 375, 376, 377, + 378, 379, 380, 381, 383, 384, 385, 386, 387, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, 399, + 400, 402, 403, 404, 405, 406, 407, 408, 410, 411, + 414, 415, 416, 417, 418, 420, 421, 422, 423, 424, + 425, 426, 427, 430, 431, 432, 433, 434, 437, 438, + 439, 440, 441, 442, 443, 445, 446, 447, 448, 449, + 450, 453, 456, 457, 458, 459, 460, 461, 462, 463, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, + 474, 475, 476, 741, 807, 811, 814, 880, 881, 882, + 555, 50, 493, 625, 170, 174, 234, 241, 288, 358, + 405, 407, 423, 429, 432, 600, 610, 834, 3, 27, + 242, 313, 394, 805, 811, 880, 21, 74, 90, 144, + 153, 165, 170, 197, 241, 245, 308, 322, 355, 358, + 366, 369, 388, 401, 408, 417, 423, 448, 603, 604, + 607, 555, 805, 93, 446, 493, 524, 612, 630, 842, + 846, 863, 877, 108, 68, 208, 108, 5, 810, 811, + 857, 857, 811, 805, 27, 410, 414, 811, 869, 870, + 873, 555, 27, 130, 642, 643, 174, 234, 358, 370, + 410, 851, 852, 873, 555, 442, 630, 635, 873, 5, + 284, 696, 803, 811, 812, 169, 493, 860, 493, 330, + 636, 637, 805, 636, 631, 632, 0, 496, 120, 207, + 434, 145, 212, 289, 428, 645, 646, 631, 633, 634, + 497, 446, 840, 27, 410, 414, 630, 873, 187, 803, + 805, 187, 803, 187, 696, 187, 803, 493, 491, 495, + 789, 791, 524, 612, 630, 824, 863, 803, 405, 407, + 405, 407, 340, 187, 811, 811, 816, 330, 366, 401, + 448, 803, 197, 27, 805, 247, 417, 107, 401, 448, + 361, 3, 44, 49, 50, 51, 52, 64, 65, 74, + 82, 94, 101, 112, 113, 134, 161, 167, 169, 173, + 187, 189, 203, 210, 211, 213, 216, 217, 219, 228, + 230, 242, 261, 262, 263, 271, 276, 292, 294, 327, + 349, 353, 373, 377, 380, 394, 403, 410, 411, 422, + 443, 446, 608, 707, 708, 710, 712, 714, 716, 718, + 719, 720, 722, 723, 724, 726, 727, 815, 880, 883, + 187, 605, 816, 187, 804, 805, 187, 805, 493, 546, + 600, 842, 3, 48, 49, 51, 52, 64, 65, 72, + 112, 113, 150, 155, 161, 178, 179, 204, 210, 211, + 213, 242, 261, 263, 267, 274, 276, 291, 295, 309, + 312, 327, 353, 373, 380, 394, 396, 410, 411, 416, + 418, 422, 442, 443, 462, 463, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 843, 845, 846, 848, 849, + 880, 884, 840, 810, 857, 810, 482, 493, 493, 823, + 476, 218, 495, 283, 4, 6, 7, 8, 9, 10, + 35, 49, 51, 52, 60, 61, 64, 65, 72, 74, + 98, 99, 100, 101, 102, 103, 104, 112, 113, 115, + 150, 155, 156, 161, 178, 179, 210, 211, 213, 235, + 236, 261, 263, 268, 273, 274, 276, 285, 295, 309, + 327, 353, 371, 380, 396, 410, 411, 416, 418, 419, + 422, 435, 443, 477, 484, 485, 486, 491, 493, 498, + 500, 501, 631, 675, 711, 714, 717, 718, 719, 721, + 722, 723, 726, 727, 738, 740, 741, 742, 744, 757, + 758, 764, 783, 788, 795, 796, 807, 808, 809, 810, + 811, 794, 795, 851, 851, 810, 851, 476, 168, 412, + 482, 493, 803, 486, 791, 3, 167, 169, 446, 846, + 859, 861, 167, 862, 738, 768, 811, 636, 497, 493, + 818, 494, 494, 506, 168, 214, 696, 864, 27, 130, + 641, 641, 54, 641, 158, 163, 231, 280, 651, 653, + 654, 678, 680, 681, 682, 645, 646, 493, 803, 476, + 218, 150, 23, 29, 135, 287, 338, 342, 372, 439, + 512, 515, 516, 338, 150, 36, 55, 106, 196, 246, + 254, 266, 297, 338, 344, 366, 372, 386, 515, 548, + 551, 150, 338, 372, 515, 150, 338, 372, 515, 3, + 27, 44, 50, 74, 82, 94, 101, 130, 167, 169, + 173, 189, 203, 216, 217, 219, 228, 230, 242, 262, + 271, 292, 294, 349, 377, 394, 403, 422, 444, 446, + 486, 494, 738, 770, 771, 813, 819, 880, 885, 738, + 790, 3, 27, 31, 32, 33, 34, 35, 36, 37, + 40, 53, 60, 61, 67, 73, 75, 86, 93, 98, + 99, 100, 102, 103, 104, 115, 117, 124, 130, 131, + 137, 141, 145, 156, 158, 163, 165, 168, 175, 177, + 181, 194, 201, 212, 214, 225, 226, 231, 235, 236, + 268, 273, 280, 283, 284, 288, 289, 306, 316, 323, + 332, 346, 365, 371, 382, 398, 401, 409, 412, 413, + 419, 428, 429, 435, 436, 442, 444, 451, 452, 454, + 455, 806, 820, 880, 884, 886, 789, 494, 493, 590, + 600, 268, 826, 495, 817, 36, 448, 187, 803, 187, + 803, 879, 803, 493, 611, 82, 831, 459, 83, 127, + 300, 406, 445, 725, 725, 725, 493, 713, 713, 312, + 493, 715, 150, 493, 64, 65, 725, 713, 710, 457, + 479, 493, 728, 493, 728, 58, 345, 497, 606, 493, + 35, 709, 493, 109, 110, 184, 185, 248, 249, 250, + 251, 252, 253, 256, 257, 362, 363, 473, 474, 493, + 729, 730, 731, 732, 733, 734, 735, 736, 737, 713, + 150, 497, 606, 150, 497, 606, 150, 283, 768, 401, + 494, 497, 4, 156, 283, 419, 484, 485, 550, 553, + 809, 810, 841, 843, 844, 847, 842, 493, 620, 624, + 550, 847, 853, 855, 770, 708, 772, 36, 229, 811, + 493, 792, 491, 738, 787, 493, 493, 163, 493, 493, + 631, 493, 493, 493, 738, 493, 493, 493, 493, 493, + 493, 493, 493, 493, 738, 738, 738, 146, 797, 798, + 768, 769, 631, 738, 768, 759, 760, 811, 812, 9, + 792, 791, 493, 810, 493, 809, 810, 3, 8, 11, + 16, 17, 18, 33, 36, 41, 48, 73, 173, 189, + 194, 216, 217, 230, 268, 271, 285, 288, 377, 477, + 480, 481, 482, 484, 485, 486, 487, 488, 489, 762, + 763, 764, 766, 456, 745, 792, 15, 294, 738, 15, + 214, 497, 638, 493, 810, 792, 495, 791, 638, 3, + 115, 234, 550, 727, 810, 854, 97, 115, 855, 115, + 855, 803, 494, 497, 840, 494, 497, 637, 804, 36, + 864, 526, 803, 36, 811, 372, 633, 633, 27, 486, + 647, 648, 738, 633, 160, 265, 667, 220, 266, 326, + 375, 434, 4, 9, 27, 662, 738, 484, 485, 663, + 664, 738, 740, 678, 679, 654, 653, 651, 652, 163, + 681, 278, 683, 651, 678, 768, 818, 229, 803, 67, + 75, 86, 165, 187, 316, 429, 571, 581, 596, 811, + 75, 86, 523, 86, 523, 493, 412, 493, 569, 240, + 432, 569, 86, 497, 412, 803, 710, 550, 54, 552, + 550, 550, 106, 246, 254, 54, 412, 455, 479, 549, + 259, 358, 549, 551, 696, 86, 412, 523, 358, 803, + 412, 358, 770, 770, 771, 494, 497, 645, 646, 13, + 14, 492, 502, 412, 589, 594, 811, 455, 623, 330, + 401, 448, 150, 93, 543, 556, 827, 828, 875, 806, + 495, 142, 803, 268, 544, 548, 268, 493, 590, 36, + 590, 494, 770, 36, 187, 584, 811, 832, 493, 768, + 809, 608, 772, 725, 725, 35, 709, 410, 410, 809, + 809, 708, 706, 811, 491, 491, 809, 809, 412, 412, + 412, 412, 605, 816, 804, 805, 805, 816, 494, 187, + 803, 879, 842, 848, 4, 809, 4, 809, 622, 629, + 820, 50, 95, 121, 139, 143, 164, 167, 182, 273, + 281, 324, 626, 497, 494, 497, 494, 497, 824, 768, + 789, 769, 451, 784, 785, 738, 768, 493, 809, 809, + 3, 729, 730, 731, 732, 733, 734, 735, 736, 773, + 774, 810, 809, 809, 738, 8, 16, 17, 18, 480, + 481, 482, 484, 485, 486, 487, 488, 489, 762, 767, + 811, 738, 775, 484, 485, 493, 739, 740, 764, 777, + 788, 494, 768, 738, 768, 778, 738, 53, 168, 226, + 413, 738, 768, 781, 738, 493, 811, 340, 801, 492, + 494, 497, 497, 499, 502, 768, 738, 737, 737, 708, + 738, 738, 738, 738, 5, 820, 821, 410, 40, 398, + 793, 816, 738, 738, 493, 631, 782, 130, 156, 268, + 273, 278, 419, 430, 738, 273, 493, 738, 412, 48, + 173, 189, 194, 230, 377, 738, 738, 738, 738, 738, + 738, 738, 738, 738, 738, 27, 34, 382, 761, 177, + 159, 746, 738, 353, 493, 758, 738, 174, 234, 401, + 405, 407, 432, 639, 803, 796, 168, 686, 770, 486, + 686, 493, 810, 494, 803, 859, 803, 867, 738, 494, + 493, 436, 866, 115, 296, 493, 525, 630, 36, 811, + 493, 530, 539, 541, 811, 37, 124, 649, 649, 497, + 436, 649, 353, 354, 484, 485, 664, 666, 740, 375, + 220, 284, 305, 305, 497, 488, 4, 665, 809, 665, + 353, 354, 666, 802, 803, 272, 379, 684, 679, 652, + 494, 338, 515, 493, 187, 581, 805, 220, 268, 220, + 436, 493, 574, 708, 805, 811, 187, 805, 187, 811, + 23, 135, 372, 511, 514, 564, 579, 820, 805, 573, + 593, 820, 805, 512, 805, 338, 372, 515, 548, 550, + 816, 805, 550, 816, 805, 550, 338, 372, 515, 805, + 805, 805, 805, 338, 372, 515, 805, 805, 645, 645, + 645, 444, 771, 188, 343, 644, 738, 738, 738, 790, + 321, 619, 494, 497, 281, 168, 412, 614, 448, 803, + 803, 811, 600, 806, 493, 493, 150, 150, 230, 571, + 581, 585, 588, 597, 599, 811, 455, 457, 576, 149, + 630, 455, 833, 494, 738, 268, 283, 768, 494, 494, + 606, 494, 491, 476, 476, 494, 494, 494, 497, 708, + 809, 492, 809, 494, 494, 730, 732, 733, 734, 733, + 734, 734, 606, 606, 283, 606, 268, 36, 494, 497, + 486, 493, 550, 621, 847, 36, 618, 810, 618, 268, + 273, 324, 618, 618, 853, 708, 494, 492, 738, 137, + 785, 786, 36, 494, 738, 494, 494, 494, 168, 494, + 494, 497, 494, 495, 306, 776, 494, 739, 739, 738, + 11, 16, 17, 18, 194, 216, 285, 480, 481, 482, + 484, 485, 486, 487, 488, 489, 764, 739, 494, 494, + 163, 168, 779, 780, 494, 36, 781, 768, 781, 781, + 168, 494, 36, 804, 493, 738, 799, 792, 738, 759, + 738, 494, 494, 476, 739, 739, 143, 768, 168, 130, + 156, 273, 278, 419, 430, 493, 143, 767, 738, 398, + 793, 738, 782, 738, 412, 493, 631, 493, 493, 293, + 750, 405, 407, 405, 407, 803, 401, 640, 640, 640, + 225, 354, 493, 631, 687, 688, 689, 696, 697, 741, + 743, 744, 811, 452, 702, 645, 798, 702, 809, 737, + 818, 824, 687, 452, 865, 442, 400, 435, 534, 529, + 538, 811, 283, 531, 811, 535, 541, 497, 686, 482, + 792, 478, 650, 650, 648, 285, 762, 765, 650, 4, + 809, 666, 284, 434, 663, 497, 239, 412, 738, 268, + 596, 493, 150, 493, 574, 197, 594, 557, 287, 567, + 557, 23, 135, 342, 344, 372, 508, 509, 510, 516, + 517, 150, 606, 150, 606, 564, 579, 564, 494, 497, + 560, 810, 494, 497, 482, 495, 412, 358, 86, 412, + 523, 358, 412, 412, 412, 358, 644, 644, 644, 771, + 275, 275, 494, 492, 389, 390, 628, 810, 589, 619, + 803, 493, 590, 826, 401, 520, 521, 810, 594, 803, + 803, 879, 803, 494, 497, 281, 569, 281, 283, 568, + 805, 455, 878, 569, 36, 150, 803, 494, 709, 809, + 728, 728, 709, 811, 492, 492, 816, 150, 622, 616, + 627, 847, 810, 810, 273, 594, 486, 594, 810, 810, + 409, 738, 141, 708, 494, 738, 738, 767, 738, 779, + 708, 739, 739, 739, 739, 130, 268, 278, 739, 739, + 739, 739, 739, 739, 739, 739, 739, 739, 738, 738, + 780, 779, 708, 494, 494, 494, 768, 708, 494, 738, + 799, 800, 36, 494, 737, 738, 33, 33, 738, 494, + 738, 168, 493, 772, 738, 494, 143, 739, 739, 143, + 143, 738, 738, 646, 452, 493, 751, 811, 640, 640, + 640, 640, 803, 803, 803, 631, 697, 168, 631, 688, + 689, 36, 690, 691, 811, 497, 94, 169, 203, 219, + 228, 262, 349, 693, 691, 36, 690, 692, 811, 479, + 701, 791, 738, 177, 668, 644, 801, 668, 494, 494, + 738, 346, 533, 441, 494, 497, 792, 84, 533, 494, + 497, 530, 865, 738, 160, 224, 493, 650, 284, 803, + 805, 494, 150, 594, 581, 594, 557, 584, 494, 117, + 201, 266, 268, 580, 493, 591, 172, 115, 186, 268, + 569, 549, 107, 115, 172, 268, 388, 391, 551, 569, + 372, 510, 423, 805, 811, 514, 593, 3, 44, 50, + 74, 82, 94, 101, 167, 169, 173, 189, 203, 216, + 217, 219, 228, 230, 242, 262, 267, 271, 285, 292, + 294, 349, 373, 377, 394, 403, 422, 446, 484, 485, + 550, 558, 595, 708, 765, 810, 813, 880, 886, 820, + 805, 805, 805, 805, 805, 805, 805, 805, 805, 805, + 494, 494, 494, 645, 549, 628, 493, 588, 833, 187, + 803, 494, 497, 494, 544, 493, 36, 578, 576, 585, + 79, 546, 107, 266, 630, 584, 436, 830, 492, 708, + 606, 879, 494, 497, 594, 738, 494, 494, 780, 168, + 130, 278, 493, 494, 494, 494, 497, 811, 738, 738, + 738, 772, 494, 738, 33, 33, 738, 738, 143, 494, + 494, 738, 752, 811, 803, 803, 803, 803, 691, 692, + 493, 494, 811, 812, 403, 659, 660, 493, 688, 219, + 292, 694, 688, 694, 219, 693, 694, 219, 660, 493, + 811, 660, 493, 290, 54, 181, 676, 494, 676, 810, + 795, 630, 296, 630, 529, 283, 493, 527, 482, 541, + 533, 767, 557, 581, 494, 494, 455, 587, 118, 190, + 199, 117, 438, 564, 582, 67, 73, 86, 115, 117, + 172, 201, 268, 273, 316, 332, 429, 436, 562, 563, + 575, 30, 54, 601, 187, 273, 550, 738, 601, 273, + 484, 485, 553, 811, 708, 606, 606, 242, 394, 813, + 817, 482, 412, 412, 644, 620, 436, 615, 617, 594, + 494, 36, 268, 493, 810, 833, 588, 149, 630, 147, + 195, 568, 120, 135, 315, 878, 107, 455, 876, 283, + 811, 829, 493, 36, 627, 739, 168, 493, 772, 799, + 494, 738, 738, 738, 494, 302, 753, 698, 699, 743, + 690, 493, 4, 9, 655, 657, 658, 811, 804, 688, + 283, 436, 695, 688, 219, 688, 703, 704, 811, 493, + 703, 811, 27, 96, 178, 352, 486, 493, 669, 670, + 671, 672, 673, 674, 738, 738, 454, 747, 810, 747, + 534, 86, 493, 532, 540, 743, 811, 131, 738, 494, + 332, 587, 493, 577, 557, 494, 497, 493, 816, 805, + 739, 601, 118, 190, 117, 273, 220, 803, 587, 81, + 115, 36, 150, 73, 705, 817, 488, 558, 805, 805, + 494, 549, 122, 494, 576, 630, 150, 36, 494, 805, + 878, 27, 78, 87, 116, 186, 198, 388, 391, 572, + 572, 354, 354, 59, 67, 234, 803, 540, 739, 772, + 494, 54, 645, 494, 497, 36, 700, 804, 305, 488, + 305, 354, 488, 493, 493, 494, 738, 493, 688, 695, + 494, 497, 708, 703, 494, 493, 374, 493, 494, 497, + 748, 749, 811, 323, 677, 677, 441, 805, 738, 494, + 497, 73, 536, 536, 269, 434, 803, 557, 583, 586, + 820, 564, 738, 268, 563, 36, 587, 590, 805, 186, + 816, 436, 513, 488, 423, 620, 810, 833, 568, 876, + 803, 630, 576, 546, 67, 286, 67, 830, 494, 494, + 768, 325, 354, 754, 701, 698, 493, 494, 811, 655, + 804, 704, 705, 494, 768, 493, 768, 670, 497, 36, + 738, 436, 656, 656, 630, 494, 702, 532, 816, 537, + 816, 537, 372, 590, 494, 497, 482, 494, 186, 244, + 598, 493, 559, 738, 423, 36, 493, 876, 568, 878, + 286, 286, 493, 833, 48, 97, 425, 738, 755, 756, + 755, 494, 703, 494, 497, 494, 494, 494, 669, 494, + 749, 751, 356, 536, 649, 649, 539, 598, 586, 558, + 266, 570, 559, 169, 301, 378, 283, 565, 566, 592, + 548, 630, 540, 702, 756, 353, 162, 311, 162, 311, + 494, 9, 339, 661, 494, 658, 537, 650, 650, 702, + 566, 199, 120, 434, 283, 592, 283, 565, 494, 876, + 494, 33, 494, 493, 649, 557, 58, 266, 345, 372, + 561, 561, 833, 756, 9, 650, 22, 115, 273, 702, + 494 }; #define yyerrok (yyerrstatus = 0) @@ -230302,14 +246308,14 @@ YYLTYPE yylloc; switch (yyn) { case 2: -#line 465 "third_party/libpg_query/grammar/grammar.y" +#line 466 "third_party/libpg_query/grammar/grammar.y" { pg_yyget_extra(yyscanner)->parsetree = (yyvsp[(1) - (1)].list); ;} break; case 3: -#line 481 "third_party/libpg_query/grammar/grammar.y" +#line 482 "third_party/libpg_query/grammar/grammar.y" { if ((yyvsp[(1) - (3)].list) != NIL) { @@ -230324,7 +246330,7 @@ YYLTYPE yylloc; break; case 4: -#line 493 "third_party/libpg_query/grammar/grammar.y" +#line 494 "third_party/libpg_query/grammar/grammar.y" { if ((yyvsp[(1) - (1)].node) != NULL) (yyval.list) = list_make1(makeRawStmt((yyvsp[(1) - (1)].node), 0)); @@ -230334,7 +246340,7 @@ YYLTYPE yylloc; break; case 39: -#line 536 "third_party/libpg_query/grammar/grammar.y" +#line 537 "third_party/libpg_query/grammar/grammar.y" { (yyval.node) = NULL; ;} break; @@ -233579,42 +249585,44 @@ YYLTYPE yylloc; #line 158 "third_party/libpg_query/grammar/statements/select.y" { PGSelectStmt *n = makeNode(PGSelectStmt); - n->targetList = (yyvsp[(3) - (10)].list); - n->intoClause = (yyvsp[(4) - (10)].into); - n->fromClause = (yyvsp[(5) - (10)].list); - n->whereClause = (yyvsp[(6) - (10)].node); - n->groupClause = (yyvsp[(7) - (10)].list); - n->havingClause = (yyvsp[(8) - (10)].node); - n->windowClause = (yyvsp[(9) - (10)].list); - n->sampleOptions = (yyvsp[(10) - (10)].node); + n->targetList = (yyvsp[(3) - (11)].list); + n->intoClause = (yyvsp[(4) - (11)].into); + n->fromClause = (yyvsp[(5) - (11)].list); + n->whereClause = (yyvsp[(6) - (11)].node); + n->groupClause = (yyvsp[(7) - (11)].list); + n->havingClause = (yyvsp[(8) - (11)].node); + n->windowClause = (yyvsp[(9) - (11)].list); + n->qualifyClause = (yyvsp[(10) - (11)].node); + n->sampleOptions = (yyvsp[(11) - (11)].node); (yyval.node) = (PGNode *)n; ;} break; case 455: -#line 173 "third_party/libpg_query/grammar/statements/select.y" +#line 174 "third_party/libpg_query/grammar/statements/select.y" { PGSelectStmt *n = makeNode(PGSelectStmt); - n->distinctClause = (yyvsp[(2) - (10)].list); - n->targetList = (yyvsp[(3) - (10)].list); - n->intoClause = (yyvsp[(4) - (10)].into); - n->fromClause = (yyvsp[(5) - (10)].list); - n->whereClause = (yyvsp[(6) - (10)].node); - n->groupClause = (yyvsp[(7) - (10)].list); - n->havingClause = (yyvsp[(8) - (10)].node); - n->windowClause = (yyvsp[(9) - (10)].list); - n->sampleOptions = (yyvsp[(10) - (10)].node); + n->distinctClause = (yyvsp[(2) - (11)].list); + n->targetList = (yyvsp[(3) - (11)].list); + n->intoClause = (yyvsp[(4) - (11)].into); + n->fromClause = (yyvsp[(5) - (11)].list); + n->whereClause = (yyvsp[(6) - (11)].node); + n->groupClause = (yyvsp[(7) - (11)].list); + n->havingClause = (yyvsp[(8) - (11)].node); + n->windowClause = (yyvsp[(9) - (11)].list); + n->qualifyClause = (yyvsp[(10) - (11)].node); + n->sampleOptions = (yyvsp[(11) - (11)].node); (yyval.node) = (PGNode *)n; ;} break; case 456: -#line 186 "third_party/libpg_query/grammar/statements/select.y" +#line 188 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; case 457: -#line 188 "third_party/libpg_query/grammar/statements/select.y" +#line 190 "third_party/libpg_query/grammar/statements/select.y" { /* same as SELECT * FROM relation_expr */ PGColumnRef *cr = makeNode(PGColumnRef); @@ -233636,28 +249644,28 @@ YYLTYPE yylloc; break; case 458: -#line 207 "third_party/libpg_query/grammar/statements/select.y" +#line 209 "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 459: -#line 211 "third_party/libpg_query/grammar/statements/select.y" +#line 213 "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 460: -#line 215 "third_party/libpg_query/grammar/statements/select.y" +#line 217 "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 461: -#line 232 "third_party/libpg_query/grammar/statements/select.y" +#line 234 "third_party/libpg_query/grammar/statements/select.y" { (yyval.with) = makeNode(PGWithClause); (yyval.with)->ctes = (yyvsp[(2) - (2)].list); @@ -233667,7 +249675,7 @@ YYLTYPE yylloc; break; case 462: -#line 239 "third_party/libpg_query/grammar/statements/select.y" +#line 241 "third_party/libpg_query/grammar/statements/select.y" { (yyval.with) = makeNode(PGWithClause); (yyval.with)->ctes = (yyvsp[(2) - (2)].list); @@ -233677,7 +249685,7 @@ YYLTYPE yylloc; break; case 463: -#line 246 "third_party/libpg_query/grammar/statements/select.y" +#line 248 "third_party/libpg_query/grammar/statements/select.y" { (yyval.with) = makeNode(PGWithClause); (yyval.with)->ctes = (yyvsp[(3) - (3)].list); @@ -233687,17 +249695,17 @@ YYLTYPE yylloc; break; case 464: -#line 255 "third_party/libpg_query/grammar/statements/select.y" +#line 257 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; case 465: -#line 256 "third_party/libpg_query/grammar/statements/select.y" +#line 258 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;} break; case 466: -#line 260 "third_party/libpg_query/grammar/statements/select.y" +#line 262 "third_party/libpg_query/grammar/statements/select.y" { PGCommonTableExpr *n = makeNode(PGCommonTableExpr); n->ctename = (yyvsp[(1) - (6)].str); @@ -233709,7 +249717,7 @@ YYLTYPE yylloc; break; case 467: -#line 272 "third_party/libpg_query/grammar/statements/select.y" +#line 274 "third_party/libpg_query/grammar/statements/select.y" { (yyval.into) = makeNode(PGIntoClause); (yyval.into)->rel = (yyvsp[(2) - (2)].range); @@ -233722,12 +249730,12 @@ YYLTYPE yylloc; break; case 468: -#line 282 "third_party/libpg_query/grammar/statements/select.y" +#line 284 "third_party/libpg_query/grammar/statements/select.y" { (yyval.into) = NULL; ;} break; case 469: -#line 291 "third_party/libpg_query/grammar/statements/select.y" +#line 293 "third_party/libpg_query/grammar/statements/select.y" { (yyval.range) = (yyvsp[(3) - (3)].range); (yyval.range)->relpersistence = PG_RELPERSISTENCE_TEMP; @@ -233735,7 +249743,7 @@ YYLTYPE yylloc; break; case 470: -#line 296 "third_party/libpg_query/grammar/statements/select.y" +#line 298 "third_party/libpg_query/grammar/statements/select.y" { (yyval.range) = (yyvsp[(3) - (3)].range); (yyval.range)->relpersistence = PG_RELPERSISTENCE_TEMP; @@ -233743,7 +249751,7 @@ YYLTYPE yylloc; break; case 471: -#line 301 "third_party/libpg_query/grammar/statements/select.y" +#line 303 "third_party/libpg_query/grammar/statements/select.y" { (yyval.range) = (yyvsp[(4) - (4)].range); (yyval.range)->relpersistence = PG_RELPERSISTENCE_TEMP; @@ -233751,7 +249759,7 @@ YYLTYPE yylloc; break; case 472: -#line 306 "third_party/libpg_query/grammar/statements/select.y" +#line 308 "third_party/libpg_query/grammar/statements/select.y" { (yyval.range) = (yyvsp[(4) - (4)].range); (yyval.range)->relpersistence = PG_RELPERSISTENCE_TEMP; @@ -233759,7 +249767,7 @@ YYLTYPE yylloc; break; case 473: -#line 311 "third_party/libpg_query/grammar/statements/select.y" +#line 313 "third_party/libpg_query/grammar/statements/select.y" { ereport(PGWARNING, (errmsg("GLOBAL is deprecated in temporary table creation"), @@ -233770,7 +249778,7 @@ YYLTYPE yylloc; break; case 474: -#line 319 "third_party/libpg_query/grammar/statements/select.y" +#line 321 "third_party/libpg_query/grammar/statements/select.y" { ereport(PGWARNING, (errmsg("GLOBAL is deprecated in temporary table creation"), @@ -233781,7 +249789,7 @@ YYLTYPE yylloc; break; case 475: -#line 327 "third_party/libpg_query/grammar/statements/select.y" +#line 329 "third_party/libpg_query/grammar/statements/select.y" { (yyval.range) = (yyvsp[(3) - (3)].range); (yyval.range)->relpersistence = PG_RELPERSISTENCE_UNLOGGED; @@ -233789,7 +249797,7 @@ YYLTYPE yylloc; break; case 476: -#line 332 "third_party/libpg_query/grammar/statements/select.y" +#line 334 "third_party/libpg_query/grammar/statements/select.y" { (yyval.range) = (yyvsp[(2) - (2)].range); (yyval.range)->relpersistence = RELPERSISTENCE_PERMANENT; @@ -233797,7 +249805,7 @@ YYLTYPE yylloc; break; case 477: -#line 337 "third_party/libpg_query/grammar/statements/select.y" +#line 339 "third_party/libpg_query/grammar/statements/select.y" { (yyval.range) = (yyvsp[(1) - (1)].range); (yyval.range)->relpersistence = RELPERSISTENCE_PERMANENT; @@ -233805,77 +249813,118 @@ YYLTYPE yylloc; break; case 478: -#line 343 "third_party/libpg_query/grammar/statements/select.y" +#line 345 "third_party/libpg_query/grammar/statements/select.y" {;} break; case 479: -#line 344 "third_party/libpg_query/grammar/statements/select.y" +#line 346 "third_party/libpg_query/grammar/statements/select.y" {;} break; case 480: -#line 348 "third_party/libpg_query/grammar/statements/select.y" +#line 350 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = true; ;} break; case 481: -#line 349 "third_party/libpg_query/grammar/statements/select.y" +#line 351 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = false; ;} break; case 482: -#line 350 "third_party/libpg_query/grammar/statements/select.y" +#line 352 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = false; ;} break; case 483: -#line 357 "third_party/libpg_query/grammar/statements/select.y" +#line 359 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(NIL); ;} break; case 484: -#line 358 "third_party/libpg_query/grammar/statements/select.y" +#line 360 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(4) - (5)].list); ;} break; case 485: -#line 362 "third_party/libpg_query/grammar/statements/select.y" +#line 364 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL;;} break; case 486: -#line 363 "third_party/libpg_query/grammar/statements/select.y" +#line 365 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; case 487: -#line 367 "third_party/libpg_query/grammar/statements/select.y" - { (yyval.list) = (yyvsp[(1) - (1)].list);;} +#line 369 "third_party/libpg_query/grammar/statements/select.y" + { (yyval.boolean) = true;;} break; case 488: -#line 368 "third_party/libpg_query/grammar/statements/select.y" - { (yyval.list) = NIL; ;} +#line 370 "third_party/libpg_query/grammar/statements/select.y" + { (yyval.boolean) = false;;} break; case 489: -#line 372 "third_party/libpg_query/grammar/statements/select.y" - { (yyval.list) = (yyvsp[(3) - (3)].list); ;} +#line 371 "third_party/libpg_query/grammar/statements/select.y" + { (yyval.boolean) = false; ;} break; case 490: +#line 375 "third_party/libpg_query/grammar/statements/select.y" + { (yyval.list) = (yyvsp[(1) - (1)].list);;} + break; + + case 491: #line 376 "third_party/libpg_query/grammar/statements/select.y" + { (yyval.list) = NIL; ;} + break; + + case 492: +#line 380 "third_party/libpg_query/grammar/statements/select.y" + { (yyval.list) = (yyvsp[(3) - (3)].list); ;} + break; + + case 493: +#line 382 "third_party/libpg_query/grammar/statements/select.y" + { + PGSortBy *sort = makeNode(PGSortBy); + sort->node = (PGNode *) makeNode(PGAStar); + sort->sortby_dir = (yyvsp[(4) - (5)].sortorder); + sort->sortby_nulls = (yyvsp[(5) - (5)].nullorder); + sort->useOp = NIL; + sort->location = -1; /* no operator */ + (yyval.list) = list_make1(sort); + ;} + break; + + case 494: +#line 392 "third_party/libpg_query/grammar/statements/select.y" + { + PGSortBy *sort = makeNode(PGSortBy); + sort->node = (PGNode *) makeNode(PGAStar); + sort->sortby_dir = (yyvsp[(4) - (5)].sortorder); + sort->sortby_nulls = (yyvsp[(5) - (5)].nullorder); + sort->useOp = NIL; + sort->location = -1; /* no operator */ + (yyval.list) = list_make1(sort); + ;} + break; + + case 495: +#line 404 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].sortby)); ;} break; - case 491: -#line 377 "third_party/libpg_query/grammar/statements/select.y" + case 496: +#line 405 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].sortby)); ;} break; - case 492: -#line 381 "third_party/libpg_query/grammar/statements/select.y" + case 497: +#line 409 "third_party/libpg_query/grammar/statements/select.y" { (yyval.sortby) = makeNode(PGSortBy); (yyval.sortby)->node = (yyvsp[(1) - (4)].node); @@ -233886,8 +249935,8 @@ YYLTYPE yylloc; ;} break; - case 493: -#line 390 "third_party/libpg_query/grammar/statements/select.y" + case 498: +#line 418 "third_party/libpg_query/grammar/statements/select.y" { (yyval.sortby) = makeNode(PGSortBy); (yyval.sortby)->node = (yyvsp[(1) - (3)].node); @@ -233898,73 +249947,73 @@ YYLTYPE yylloc; ;} break; - case 494: -#line 400 "third_party/libpg_query/grammar/statements/select.y" + case 499: +#line 428 "third_party/libpg_query/grammar/statements/select.y" { (yyval.sortorder) = PG_SORTBY_ASC; ;} break; - case 495: -#line 401 "third_party/libpg_query/grammar/statements/select.y" + case 500: +#line 429 "third_party/libpg_query/grammar/statements/select.y" { (yyval.sortorder) = PG_SORTBY_DESC; ;} break; - case 496: -#line 402 "third_party/libpg_query/grammar/statements/select.y" + case 501: +#line 430 "third_party/libpg_query/grammar/statements/select.y" { (yyval.sortorder) = PG_SORTBY_DEFAULT; ;} break; - case 497: -#line 405 "third_party/libpg_query/grammar/statements/select.y" + case 502: +#line 433 "third_party/libpg_query/grammar/statements/select.y" { (yyval.nullorder) = PG_SORTBY_NULLS_FIRST; ;} break; - case 498: -#line 406 "third_party/libpg_query/grammar/statements/select.y" + case 503: +#line 434 "third_party/libpg_query/grammar/statements/select.y" { (yyval.nullorder) = PG_SORTBY_NULLS_LAST; ;} break; - case 499: -#line 407 "third_party/libpg_query/grammar/statements/select.y" + case 504: +#line 435 "third_party/libpg_query/grammar/statements/select.y" { (yyval.nullorder) = PG_SORTBY_NULLS_DEFAULT; ;} break; - case 500: -#line 411 "third_party/libpg_query/grammar/statements/select.y" + case 505: +#line 439 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2((yyvsp[(2) - (2)].node), (yyvsp[(1) - (2)].node)); ;} break; - case 501: -#line 412 "third_party/libpg_query/grammar/statements/select.y" + case 506: +#line 440 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node)); ;} break; - case 502: -#line 413 "third_party/libpg_query/grammar/statements/select.y" + case 507: +#line 441 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2(NULL, (yyvsp[(1) - (1)].node)); ;} break; - case 503: -#line 414 "third_party/libpg_query/grammar/statements/select.y" + case 508: +#line 442 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2((yyvsp[(1) - (1)].node), NULL); ;} break; - case 504: -#line 418 "third_party/libpg_query/grammar/statements/select.y" + case 509: +#line 446 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 505: -#line 419 "third_party/libpg_query/grammar/statements/select.y" + case 510: +#line 447 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2(NULL,NULL); ;} break; - case 506: -#line 424 "third_party/libpg_query/grammar/statements/select.y" + case 511: +#line 452 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 507: -#line 426 "third_party/libpg_query/grammar/statements/select.y" + case 512: +#line 454 "third_party/libpg_query/grammar/statements/select.y" { /* Disabled because it was too confusing, bjm 2002-02-18 */ ereport(ERROR, @@ -233975,333 +250024,374 @@ YYLTYPE yylloc; ;} break; - case 508: -#line 442 "third_party/libpg_query/grammar/statements/select.y" + case 513: +#line 470 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(3) - (5)].node); ;} break; - case 509: -#line 444 "third_party/libpg_query/grammar/statements/select.y" + case 514: +#line 472 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeIntConst(1, -1); ;} break; - case 510: -#line 449 "third_party/libpg_query/grammar/statements/select.y" + case 515: +#line 477 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 511: -#line 452 "third_party/libpg_query/grammar/statements/select.y" + case 516: +#line 480 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (3)].node); ;} break; - case 512: -#line 460 "third_party/libpg_query/grammar/statements/select.y" + case 517: +#line 488 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSampleSize(makeFloat((yyvsp[(1) - (2)].str)), true); ;} break; - case 513: -#line 464 "third_party/libpg_query/grammar/statements/select.y" + case 518: +#line 492 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSampleSize(makeInteger((yyvsp[(1) - (2)].ival)), true); ;} break; - case 514: -#line 468 "third_party/libpg_query/grammar/statements/select.y" + case 519: +#line 496 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSampleSize(makeFloat((yyvsp[(1) - (2)].str)), true); ;} break; - case 515: -#line 472 "third_party/libpg_query/grammar/statements/select.y" + case 520: +#line 500 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSampleSize(makeInteger((yyvsp[(1) - (2)].ival)), true); ;} break; - case 516: -#line 476 "third_party/libpg_query/grammar/statements/select.y" + case 521: +#line 504 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSampleSize(makeInteger((yyvsp[(1) - (1)].ival)), false); ;} break; - case 517: -#line 480 "third_party/libpg_query/grammar/statements/select.y" + case 522: +#line 508 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSampleSize(makeInteger((yyvsp[(1) - (2)].ival)), false); ;} break; - case 518: -#line 487 "third_party/libpg_query/grammar/statements/select.y" + case 523: +#line 515 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(3) - (3)].node); ;} break; - case 519: -#line 491 "third_party/libpg_query/grammar/statements/select.y" + case 524: +#line 519 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 520: -#line 498 "third_party/libpg_query/grammar/statements/select.y" + case 525: +#line 526 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 521: -#line 499 "third_party/libpg_query/grammar/statements/select.y" + case 526: +#line 527 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = NULL; ;} break; - case 522: -#line 504 "third_party/libpg_query/grammar/statements/select.y" + case 527: +#line 532 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSampleOptions((yyvsp[(3) - (5)].node), (yyvsp[(1) - (5)].str), (yyvsp[(5) - (5)].ival), (yylsp[(1) - (5)])); ;} break; - case 523: -#line 508 "third_party/libpg_query/grammar/statements/select.y" + case 528: +#line 536 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSampleOptions((yyvsp[(1) - (1)].node), NULL, -1, (yylsp[(1) - (1)])); ;} break; - case 524: -#line 512 "third_party/libpg_query/grammar/statements/select.y" + case 529: +#line 540 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSampleOptions((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].str), -1, (yylsp[(1) - (4)])); ;} break; - case 525: -#line 516 "third_party/libpg_query/grammar/statements/select.y" + case 530: +#line 544 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSampleOptions((yyvsp[(1) - (6)].node), (yyvsp[(3) - (6)].str), (yyvsp[(5) - (6)].ival), (yylsp[(1) - (6)])); ;} break; - case 526: -#line 523 "third_party/libpg_query/grammar/statements/select.y" + case 531: +#line 551 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 527: -#line 529 "third_party/libpg_query/grammar/statements/select.y" + case 532: +#line 557 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 528: -#line 530 "third_party/libpg_query/grammar/statements/select.y" + case 533: +#line 558 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 529: -#line 535 "third_party/libpg_query/grammar/statements/select.y" + case 534: +#line 563 "third_party/libpg_query/grammar/statements/select.y" { (yyval.ival) = (yyvsp[(3) - (4)].ival); ;} break; - case 530: -#line 536 "third_party/libpg_query/grammar/statements/select.y" + case 535: +#line 564 "third_party/libpg_query/grammar/statements/select.y" { (yyval.ival) = -1; ;} break; - case 531: -#line 540 "third_party/libpg_query/grammar/statements/select.y" + case 536: +#line 568 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 532: -#line 542 "third_party/libpg_query/grammar/statements/select.y" + case 537: +#line 570 "third_party/libpg_query/grammar/statements/select.y" { /* LIMIT ALL is represented as a NULL constant */ (yyval.node) = makeNullAConst((yylsp[(1) - (1)])); ;} break; - case 533: -#line 549 "third_party/libpg_query/grammar/statements/select.y" + case 538: +#line 575 "third_party/libpg_query/grammar/statements/select.y" + { (yyval.node) = makeLimitPercent((yyvsp[(1) - (2)].node)); ;} + break; + + case 539: +#line 577 "third_party/libpg_query/grammar/statements/select.y" + { (yyval.node) = makeLimitPercent(makeFloatConst((yyvsp[(1) - (2)].str),(yylsp[(1) - (2)]))); ;} + break; + + case 540: +#line 579 "third_party/libpg_query/grammar/statements/select.y" + { (yyval.node) = makeLimitPercent(makeIntConst((yyvsp[(1) - (2)].ival),(yylsp[(1) - (2)]))); ;} + break; + + case 541: +#line 583 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 534: -#line 569 "third_party/libpg_query/grammar/statements/select.y" + case 542: +#line 603 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 535: -#line 571 "third_party/libpg_query/grammar/statements/select.y" + case 543: +#line 605 "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 536: -#line 573 "third_party/libpg_query/grammar/statements/select.y" + case 544: +#line 607 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = doNegate((yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;} break; - case 537: -#line 577 "third_party/libpg_query/grammar/statements/select.y" + case 545: +#line 611 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeIntConst((yyvsp[(1) - (1)].ival),(yylsp[(1) - (1)])); ;} break; - case 538: -#line 578 "third_party/libpg_query/grammar/statements/select.y" + case 546: +#line 612 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeFloatConst((yyvsp[(1) - (1)].str),(yylsp[(1) - (1)])); ;} break; - case 539: -#line 582 "third_party/libpg_query/grammar/statements/select.y" + case 547: +#line 616 "third_party/libpg_query/grammar/statements/select.y" { (yyval.ival) = 0; ;} break; - case 540: -#line 583 "third_party/libpg_query/grammar/statements/select.y" + case 548: +#line 617 "third_party/libpg_query/grammar/statements/select.y" { (yyval.ival) = 0; ;} break; - case 541: -#line 586 "third_party/libpg_query/grammar/statements/select.y" + case 549: +#line 620 "third_party/libpg_query/grammar/statements/select.y" { (yyval.ival) = 0; ;} break; - case 542: -#line 587 "third_party/libpg_query/grammar/statements/select.y" + case 550: +#line 621 "third_party/libpg_query/grammar/statements/select.y" { (yyval.ival) = 0; ;} break; - case 543: -#line 612 "third_party/libpg_query/grammar/statements/select.y" + case 551: +#line 646 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (3)].list); ;} break; - case 544: -#line 613 "third_party/libpg_query/grammar/statements/select.y" + case 552: +#line 648 "third_party/libpg_query/grammar/statements/select.y" + { + PGNode *node = (PGNode *) makeGroupingSet(GROUPING_SET_ALL, NIL, (yylsp[(3) - (3)])); + (yyval.list) = list_make1(node); + ;} + break; + + case 553: +#line 653 "third_party/libpg_query/grammar/statements/select.y" + { + PGNode *node = (PGNode *) makeGroupingSet(GROUPING_SET_ALL, NIL, (yylsp[(3) - (3)])); + (yyval.list) = list_make1(node); + ;} + break; + + case 554: +#line 657 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 545: -#line 617 "third_party/libpg_query/grammar/statements/select.y" + case 555: +#line 661 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 546: -#line 618 "third_party/libpg_query/grammar/statements/select.y" + case 556: +#line 662 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list),(yyvsp[(3) - (3)].node)); ;} break; - case 547: -#line 622 "third_party/libpg_query/grammar/statements/select.y" + case 557: +#line 666 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 548: -#line 623 "third_party/libpg_query/grammar/statements/select.y" + case 558: +#line 667 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 549: -#line 624 "third_party/libpg_query/grammar/statements/select.y" + case 559: +#line 668 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 550: -#line 625 "third_party/libpg_query/grammar/statements/select.y" + case 560: +#line 669 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 551: -#line 626 "third_party/libpg_query/grammar/statements/select.y" + case 561: +#line 670 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 552: -#line 631 "third_party/libpg_query/grammar/statements/select.y" + case 562: +#line 675 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeGroupingSet(GROUPING_SET_EMPTY, NIL, (yylsp[(1) - (2)])); ;} break; - case 553: -#line 644 "third_party/libpg_query/grammar/statements/select.y" + case 563: +#line 688 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeGroupingSet(GROUPING_SET_ROLLUP, (yyvsp[(3) - (4)].list), (yylsp[(1) - (4)])); ;} break; - case 554: -#line 651 "third_party/libpg_query/grammar/statements/select.y" + case 564: +#line 695 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeGroupingSet(GROUPING_SET_CUBE, (yyvsp[(3) - (4)].list), (yylsp[(1) - (4)])); ;} break; - case 555: -#line 658 "third_party/libpg_query/grammar/statements/select.y" + case 565: +#line 702 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeGroupingSet(GROUPING_SET_SETS, (yyvsp[(4) - (5)].list), (yylsp[(1) - (5)])); ;} break; - case 556: -#line 664 "third_party/libpg_query/grammar/statements/select.y" + case 566: +#line 708 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 557: -#line 665 "third_party/libpg_query/grammar/statements/select.y" + case 567: +#line 709 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 558: -#line 669 "third_party/libpg_query/grammar/statements/select.y" + case 568: +#line 713 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 559: -#line 670 "third_party/libpg_query/grammar/statements/select.y" + case 569: +#line 714 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 560: -#line 674 "third_party/libpg_query/grammar/statements/select.y" + case 570: +#line 718 "third_party/libpg_query/grammar/statements/select.y" + { (yyval.node) = (yyvsp[(2) - (2)].node); ;} + break; + + case 571: +#line 719 "third_party/libpg_query/grammar/statements/select.y" + { (yyval.node) = NULL; ;} + break; + + case 572: +#line 723 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 561: -#line 675 "third_party/libpg_query/grammar/statements/select.y" + case 573: +#line 724 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 562: -#line 679 "third_party/libpg_query/grammar/statements/select.y" + case 574: +#line 728 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 563: -#line 680 "third_party/libpg_query/grammar/statements/select.y" + case 575: +#line 729 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 564: -#line 684 "third_party/libpg_query/grammar/statements/select.y" + case 576: +#line 733 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 565: -#line 685 "third_party/libpg_query/grammar/statements/select.y" + case 577: +#line 734 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node)); ;} break; - case 566: -#line 690 "third_party/libpg_query/grammar/statements/select.y" + case 578: +#line 739 "third_party/libpg_query/grammar/statements/select.y" { PGLockingClause *n = makeNode(PGLockingClause); n->lockedRels = (yyvsp[(2) - (3)].list); @@ -234311,53 +250401,53 @@ YYLTYPE yylloc; ;} break; - case 567: -#line 700 "third_party/libpg_query/grammar/statements/select.y" + case 579: +#line 749 "third_party/libpg_query/grammar/statements/select.y" { (yyval.lockstrength) = LCS_FORUPDATE; ;} break; - case 568: -#line 701 "third_party/libpg_query/grammar/statements/select.y" + case 580: +#line 750 "third_party/libpg_query/grammar/statements/select.y" { (yyval.lockstrength) = PG_LCS_FORNOKEYUPDATE; ;} break; - case 569: -#line 702 "third_party/libpg_query/grammar/statements/select.y" + case 581: +#line 751 "third_party/libpg_query/grammar/statements/select.y" { (yyval.lockstrength) = PG_LCS_FORSHARE; ;} break; - case 570: -#line 703 "third_party/libpg_query/grammar/statements/select.y" + case 582: +#line 752 "third_party/libpg_query/grammar/statements/select.y" { (yyval.lockstrength) = PG_LCS_FORKEYSHARE; ;} break; - case 571: -#line 707 "third_party/libpg_query/grammar/statements/select.y" + case 583: +#line 756 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(2) - (2)].list); ;} break; - case 572: -#line 708 "third_party/libpg_query/grammar/statements/select.y" + case 584: +#line 757 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 573: -#line 713 "third_party/libpg_query/grammar/statements/select.y" + case 585: +#line 762 "third_party/libpg_query/grammar/statements/select.y" { (yyval.lockwaitpolicy) = LockWaitError; ;} break; - case 574: -#line 714 "third_party/libpg_query/grammar/statements/select.y" + case 586: +#line 763 "third_party/libpg_query/grammar/statements/select.y" { (yyval.lockwaitpolicy) = PGLockWaitSkip; ;} break; - case 575: -#line 715 "third_party/libpg_query/grammar/statements/select.y" + case 587: +#line 764 "third_party/libpg_query/grammar/statements/select.y" { (yyval.lockwaitpolicy) = PGLockWaitBlock; ;} break; - case 576: -#line 725 "third_party/libpg_query/grammar/statements/select.y" + case 588: +#line 774 "third_party/libpg_query/grammar/statements/select.y" { PGSelectStmt *n = makeNode(PGSelectStmt); n->valuesLists = list_make1((yyvsp[(3) - (4)].list)); @@ -234365,8 +250455,8 @@ YYLTYPE yylloc; ;} break; - case 577: -#line 731 "third_party/libpg_query/grammar/statements/select.y" + case 589: +#line 780 "third_party/libpg_query/grammar/statements/select.y" { PGSelectStmt *n = (PGSelectStmt *) (yyvsp[(1) - (5)].node); n->valuesLists = lappend(n->valuesLists, (yyvsp[(4) - (5)].list)); @@ -234374,28 +250464,28 @@ YYLTYPE yylloc; ;} break; - case 578: -#line 748 "third_party/libpg_query/grammar/statements/select.y" + case 590: +#line 797 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(2) - (2)].list); ;} break; - case 579: -#line 749 "third_party/libpg_query/grammar/statements/select.y" + case 591: +#line 798 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 580: -#line 753 "third_party/libpg_query/grammar/statements/select.y" + case 592: +#line 802 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 581: -#line 754 "third_party/libpg_query/grammar/statements/select.y" + case 593: +#line 803 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;} break; - case 582: -#line 761 "third_party/libpg_query/grammar/statements/select.y" + case 594: +#line 810 "third_party/libpg_query/grammar/statements/select.y" { (yyvsp[(1) - (3)].range)->alias = (yyvsp[(2) - (3)].alias); (yyvsp[(1) - (3)].range)->sample = (yyvsp[(3) - (3)].node); @@ -234403,8 +250493,8 @@ YYLTYPE yylloc; ;} break; - case 583: -#line 767 "third_party/libpg_query/grammar/statements/select.y" + case 595: +#line 816 "third_party/libpg_query/grammar/statements/select.y" { PGRangeFunction *n = (PGRangeFunction *) (yyvsp[(1) - (3)].node); n->alias = (PGAlias*) linitial((yyvsp[(2) - (3)].list)); @@ -234414,8 +250504,8 @@ YYLTYPE yylloc; ;} break; - case 584: -#line 775 "third_party/libpg_query/grammar/statements/select.y" + case 596: +#line 824 "third_party/libpg_query/grammar/statements/select.y" { PGRangeFunction *n = (PGRangeFunction *) (yyvsp[(2) - (3)].node); n->lateral = true; @@ -234425,8 +250515,8 @@ YYLTYPE yylloc; ;} break; - case 585: -#line 783 "third_party/libpg_query/grammar/statements/select.y" + case 597: +#line 832 "third_party/libpg_query/grammar/statements/select.y" { PGRangeSubselect *n = makeNode(PGRangeSubselect); n->lateral = false; @@ -234437,8 +250527,8 @@ YYLTYPE yylloc; ;} break; - case 586: -#line 792 "third_party/libpg_query/grammar/statements/select.y" + case 598: +#line 841 "third_party/libpg_query/grammar/statements/select.y" { PGRangeSubselect *n = makeNode(PGRangeSubselect); n->lateral = true; @@ -234449,30 +250539,30 @@ YYLTYPE yylloc; ;} break; - case 587: -#line 801 "third_party/libpg_query/grammar/statements/select.y" + case 599: +#line 850 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) (yyvsp[(1) - (1)].jexpr); ;} break; - case 588: -#line 805 "third_party/libpg_query/grammar/statements/select.y" + case 600: +#line 854 "third_party/libpg_query/grammar/statements/select.y" { (yyvsp[(2) - (4)].jexpr)->alias = (yyvsp[(4) - (4)].alias); (yyval.node) = (PGNode *) (yyvsp[(2) - (4)].jexpr); ;} break; - case 589: -#line 831 "third_party/libpg_query/grammar/statements/select.y" + case 601: +#line 880 "third_party/libpg_query/grammar/statements/select.y" { (yyval.jexpr) = (yyvsp[(2) - (3)].jexpr); ;} break; - case 590: -#line 835 "third_party/libpg_query/grammar/statements/select.y" + case 602: +#line 884 "third_party/libpg_query/grammar/statements/select.y" { /* CROSS JOIN is same as unqualified inner join */ PGJoinExpr *n = makeNode(PGJoinExpr); @@ -234487,8 +250577,8 @@ YYLTYPE yylloc; ;} break; - case 591: -#line 848 "third_party/libpg_query/grammar/statements/select.y" + case 603: +#line 897 "third_party/libpg_query/grammar/statements/select.y" { PGJoinExpr *n = makeNode(PGJoinExpr); n->jointype = (yyvsp[(2) - (5)].jtype); @@ -234504,8 +250594,8 @@ YYLTYPE yylloc; ;} break; - case 592: -#line 862 "third_party/libpg_query/grammar/statements/select.y" + case 604: +#line 911 "third_party/libpg_query/grammar/statements/select.y" { /* letting join_type reduce to empty doesn't work */ PGJoinExpr *n = makeNode(PGJoinExpr); @@ -234522,8 +250612,8 @@ YYLTYPE yylloc; ;} break; - case 593: -#line 877 "third_party/libpg_query/grammar/statements/select.y" + case 605: +#line 926 "third_party/libpg_query/grammar/statements/select.y" { PGJoinExpr *n = makeNode(PGJoinExpr); n->jointype = (yyvsp[(3) - (5)].jtype); @@ -234537,8 +250627,8 @@ YYLTYPE yylloc; ;} break; - case 594: -#line 889 "third_party/libpg_query/grammar/statements/select.y" + case 606: +#line 938 "third_party/libpg_query/grammar/statements/select.y" { /* letting join_type reduce to empty doesn't work */ PGJoinExpr *n = makeNode(PGJoinExpr); @@ -234553,8 +250643,8 @@ YYLTYPE yylloc; ;} break; - case 595: -#line 905 "third_party/libpg_query/grammar/statements/select.y" + case 607: +#line 954 "third_party/libpg_query/grammar/statements/select.y" { (yyval.alias) = makeNode(PGAlias); (yyval.alias)->aliasname = (yyvsp[(2) - (5)].str); @@ -234562,16 +250652,16 @@ YYLTYPE yylloc; ;} break; - case 596: -#line 911 "third_party/libpg_query/grammar/statements/select.y" + case 608: +#line 960 "third_party/libpg_query/grammar/statements/select.y" { (yyval.alias) = makeNode(PGAlias); (yyval.alias)->aliasname = (yyvsp[(2) - (2)].str); ;} break; - case 597: -#line 916 "third_party/libpg_query/grammar/statements/select.y" + case 609: +#line 965 "third_party/libpg_query/grammar/statements/select.y" { (yyval.alias) = makeNode(PGAlias); (yyval.alias)->aliasname = (yyvsp[(1) - (4)].str); @@ -234579,40 +250669,40 @@ YYLTYPE yylloc; ;} break; - case 598: -#line 922 "third_party/libpg_query/grammar/statements/select.y" + case 610: +#line 971 "third_party/libpg_query/grammar/statements/select.y" { (yyval.alias) = makeNode(PGAlias); (yyval.alias)->aliasname = (yyvsp[(1) - (1)].str); ;} break; - case 599: -#line 928 "third_party/libpg_query/grammar/statements/select.y" + case 611: +#line 977 "third_party/libpg_query/grammar/statements/select.y" { (yyval.alias) = (yyvsp[(1) - (1)].alias); ;} break; - case 600: -#line 929 "third_party/libpg_query/grammar/statements/select.y" + case 612: +#line 978 "third_party/libpg_query/grammar/statements/select.y" { (yyval.alias) = NULL; ;} break; - case 601: -#line 938 "third_party/libpg_query/grammar/statements/select.y" + case 613: +#line 987 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2((yyvsp[(1) - (1)].alias), NIL); ;} break; - case 602: -#line 942 "third_party/libpg_query/grammar/statements/select.y" + case 614: +#line 991 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2(NULL, (yyvsp[(3) - (4)].list)); ;} break; - case 603: -#line 946 "third_party/libpg_query/grammar/statements/select.y" + case 615: +#line 995 "third_party/libpg_query/grammar/statements/select.y" { PGAlias *a = makeNode(PGAlias); a->aliasname = (yyvsp[(2) - (5)].str); @@ -234620,8 +250710,8 @@ YYLTYPE yylloc; ;} break; - case 604: -#line 952 "third_party/libpg_query/grammar/statements/select.y" + case 616: +#line 1001 "third_party/libpg_query/grammar/statements/select.y" { PGAlias *a = makeNode(PGAlias); a->aliasname = (yyvsp[(1) - (4)].str); @@ -234629,55 +250719,55 @@ YYLTYPE yylloc; ;} break; - case 605: -#line 958 "third_party/libpg_query/grammar/statements/select.y" + case 617: +#line 1007 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2(NULL, NIL); ;} break; - case 606: -#line 963 "third_party/libpg_query/grammar/statements/select.y" + case 618: +#line 1012 "third_party/libpg_query/grammar/statements/select.y" { (yyval.jtype) = PG_JOIN_FULL; ;} break; - case 607: -#line 964 "third_party/libpg_query/grammar/statements/select.y" + case 619: +#line 1013 "third_party/libpg_query/grammar/statements/select.y" { (yyval.jtype) = PG_JOIN_LEFT; ;} break; - case 608: -#line 965 "third_party/libpg_query/grammar/statements/select.y" + case 620: +#line 1014 "third_party/libpg_query/grammar/statements/select.y" { (yyval.jtype) = PG_JOIN_RIGHT; ;} break; - case 609: -#line 966 "third_party/libpg_query/grammar/statements/select.y" + case 621: +#line 1015 "third_party/libpg_query/grammar/statements/select.y" { (yyval.jtype) = PG_JOIN_INNER; ;} break; - case 610: -#line 970 "third_party/libpg_query/grammar/statements/select.y" + case 622: +#line 1019 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 611: -#line 971 "third_party/libpg_query/grammar/statements/select.y" + case 623: +#line 1020 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 612: -#line 983 "third_party/libpg_query/grammar/statements/select.y" + case 624: +#line 1032 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) (yyvsp[(3) - (4)].list); ;} break; - case 613: -#line 984 "third_party/libpg_query/grammar/statements/select.y" + case 625: +#line 1033 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 614: -#line 990 "third_party/libpg_query/grammar/statements/select.y" + case 626: +#line 1039 "third_party/libpg_query/grammar/statements/select.y" { /* inheritance query, implicitly */ (yyval.range) = (yyvsp[(1) - (1)].range); @@ -234686,8 +250776,8 @@ YYLTYPE yylloc; ;} break; - case 615: -#line 997 "third_party/libpg_query/grammar/statements/select.y" + case 627: +#line 1046 "third_party/libpg_query/grammar/statements/select.y" { /* inheritance query, explicitly */ (yyval.range) = (yyvsp[(1) - (2)].range); @@ -234696,8 +250786,8 @@ YYLTYPE yylloc; ;} break; - case 616: -#line 1004 "third_party/libpg_query/grammar/statements/select.y" + case 628: +#line 1053 "third_party/libpg_query/grammar/statements/select.y" { /* no inheritance */ (yyval.range) = (yyvsp[(2) - (2)].range); @@ -234706,8 +250796,8 @@ YYLTYPE yylloc; ;} break; - case 617: -#line 1011 "third_party/libpg_query/grammar/statements/select.y" + case 629: +#line 1060 "third_party/libpg_query/grammar/statements/select.y" { /* no inheritance, SQL99-style syntax */ (yyval.range) = (yyvsp[(3) - (4)].range); @@ -234716,8 +250806,8 @@ YYLTYPE yylloc; ;} break; - case 618: -#line 1043 "third_party/libpg_query/grammar/statements/select.y" + case 630: +#line 1092 "third_party/libpg_query/grammar/statements/select.y" { PGRangeFunction *n = makeNode(PGRangeFunction); n->lateral = false; @@ -234730,8 +250820,8 @@ YYLTYPE yylloc; ;} break; - case 619: -#line 1054 "third_party/libpg_query/grammar/statements/select.y" + case 631: +#line 1103 "third_party/libpg_query/grammar/statements/select.y" { PGRangeFunction *n = makeNode(PGRangeFunction); n->lateral = false; @@ -234744,67 +250834,67 @@ YYLTYPE yylloc; ;} break; - case 620: -#line 1067 "third_party/libpg_query/grammar/statements/select.y" + case 632: +#line 1116 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].list)); ;} break; - case 621: -#line 1071 "third_party/libpg_query/grammar/statements/select.y" + case 633: +#line 1120 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].list)); ;} break; - case 622: -#line 1072 "third_party/libpg_query/grammar/statements/select.y" + case 634: +#line 1121 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); ;} break; - case 623: -#line 1075 "third_party/libpg_query/grammar/statements/select.y" + case 635: +#line 1124 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (4)].list); ;} break; - case 624: -#line 1076 "third_party/libpg_query/grammar/statements/select.y" + case 636: +#line 1125 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 625: -#line 1079 "third_party/libpg_query/grammar/statements/select.y" + case 637: +#line 1128 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = true; ;} break; - case 626: -#line 1080 "third_party/libpg_query/grammar/statements/select.y" + case 638: +#line 1129 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = false; ;} break; - case 627: -#line 1085 "third_party/libpg_query/grammar/statements/select.y" + case 639: +#line 1134 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 628: -#line 1086 "third_party/libpg_query/grammar/statements/select.y" + case 640: +#line 1135 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 629: -#line 1092 "third_party/libpg_query/grammar/statements/select.y" + case 641: +#line 1141 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 630: -#line 1096 "third_party/libpg_query/grammar/statements/select.y" + case 642: +#line 1145 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;} break; - case 631: -#line 1102 "third_party/libpg_query/grammar/statements/select.y" + case 643: +#line 1151 "third_party/libpg_query/grammar/statements/select.y" { PGColumnDef *n = makeNode(PGColumnDef); n->colname = (yyvsp[(1) - (3)].str); @@ -234824,8 +250914,8 @@ YYLTYPE yylloc; ;} break; - case 632: -#line 1123 "third_party/libpg_query/grammar/statements/select.y" + case 644: +#line 1172 "third_party/libpg_query/grammar/statements/select.y" { PGCollateClause *n = makeNode(PGCollateClause); n->arg = NULL; @@ -234835,35 +250925,35 @@ YYLTYPE yylloc; ;} break; - case 633: -#line 1130 "third_party/libpg_query/grammar/statements/select.y" + case 645: +#line 1179 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 634: -#line 1143 "third_party/libpg_query/grammar/statements/select.y" + case 646: +#line 1192 "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 635: -#line 1146 "third_party/libpg_query/grammar/statements/select.y" + case 647: +#line 1195 "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 638: -#line 1153 "third_party/libpg_query/grammar/statements/select.y" + case 650: +#line 1202 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (2)].typnam); (yyval.typnam)->arrayBounds = (yyvsp[(2) - (2)].list); ;} break; - case 639: -#line 1158 "third_party/libpg_query/grammar/statements/select.y" + case 651: +#line 1207 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(2) - (3)].typnam); (yyval.typnam)->arrayBounds = (yyvsp[(3) - (3)].list); @@ -234871,16 +250961,16 @@ YYLTYPE yylloc; ;} break; - case 640: -#line 1165 "third_party/libpg_query/grammar/statements/select.y" + case 652: +#line 1214 "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 641: -#line 1170 "third_party/libpg_query/grammar/statements/select.y" + case 653: +#line 1219 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(2) - (6)].typnam); (yyval.typnam)->arrayBounds = list_make1(makeInteger((yyvsp[(5) - (6)].ival))); @@ -234888,16 +250978,16 @@ YYLTYPE yylloc; ;} break; - case 642: -#line 1176 "third_party/libpg_query/grammar/statements/select.y" + case 654: +#line 1225 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (2)].typnam); (yyval.typnam)->arrayBounds = list_make1(makeInteger(-1)); ;} break; - case 643: -#line 1181 "third_party/libpg_query/grammar/statements/select.y" + case 655: +#line 1230 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(2) - (3)].typnam); (yyval.typnam)->arrayBounds = list_make1(makeInteger(-1)); @@ -234905,8 +250995,8 @@ YYLTYPE yylloc; ;} break; - case 644: -#line 1186 "third_party/libpg_query/grammar/statements/select.y" + case 656: +#line 1235 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("struct"); (yyval.typnam)->arrayBounds = (yyvsp[(5) - (5)].list); @@ -234915,8 +251005,8 @@ YYLTYPE yylloc; ;} break; - case 645: -#line 1192 "third_party/libpg_query/grammar/statements/select.y" + case 657: +#line 1241 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("map"); (yyval.typnam)->arrayBounds = (yyvsp[(5) - (5)].list); @@ -234925,56 +251015,56 @@ YYLTYPE yylloc; ;} break; - case 646: -#line 1202 "third_party/libpg_query/grammar/statements/select.y" + case 658: +#line 1251 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), makeInteger(-1)); ;} break; - case 647: -#line 1204 "third_party/libpg_query/grammar/statements/select.y" + case 659: +#line 1253 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (4)].list), makeInteger((yyvsp[(3) - (4)].ival))); ;} break; - case 648: -#line 1206 "third_party/libpg_query/grammar/statements/select.y" + case 660: +#line 1255 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 649: -#line 1210 "third_party/libpg_query/grammar/statements/select.y" + case 661: +#line 1259 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 650: -#line 1211 "third_party/libpg_query/grammar/statements/select.y" + case 662: +#line 1260 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 651: -#line 1212 "third_party/libpg_query/grammar/statements/select.y" + case 663: +#line 1261 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 652: -#line 1213 "third_party/libpg_query/grammar/statements/select.y" + case 664: +#line 1262 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 653: -#line 1214 "third_party/libpg_query/grammar/statements/select.y" + case 665: +#line 1263 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 654: -#line 1216 "third_party/libpg_query/grammar/statements/select.y" + case 666: +#line 1265 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (2)].typnam); (yyval.typnam)->typmods = (yyvsp[(2) - (2)].list); ;} break; - case 655: -#line 1221 "third_party/libpg_query/grammar/statements/select.y" + case 667: +#line 1270 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (4)].typnam); (yyval.typnam)->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1), @@ -234982,28 +251072,28 @@ YYLTYPE yylloc; ;} break; - case 656: -#line 1240 "third_party/libpg_query/grammar/statements/select.y" + case 668: +#line 1289 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 657: -#line 1241 "third_party/libpg_query/grammar/statements/select.y" + case 669: +#line 1290 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 658: -#line 1242 "third_party/libpg_query/grammar/statements/select.y" + case 670: +#line 1291 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 659: -#line 1243 "third_party/libpg_query/grammar/statements/select.y" + case 671: +#line 1292 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 660: -#line 1255 "third_party/libpg_query/grammar/statements/select.y" + case 672: +#line 1304 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = makeTypeName((yyvsp[(1) - (2)].str)); (yyval.typnam)->typmods = (yyvsp[(2) - (2)].list); @@ -235011,74 +251101,74 @@ YYLTYPE yylloc; ;} break; - case 661: -#line 1268 "third_party/libpg_query/grammar/statements/select.y" + case 673: +#line 1317 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(2) - (3)].list); ;} break; - case 662: -#line 1269 "third_party/libpg_query/grammar/statements/select.y" + case 674: +#line 1318 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 663: -#line 1276 "third_party/libpg_query/grammar/statements/select.y" + case 675: +#line 1325 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("int4"); (yyval.typnam)->location = (yylsp[(1) - (1)]); ;} break; - case 664: -#line 1281 "third_party/libpg_query/grammar/statements/select.y" + case 676: +#line 1330 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("int4"); (yyval.typnam)->location = (yylsp[(1) - (1)]); ;} break; - case 665: -#line 1286 "third_party/libpg_query/grammar/statements/select.y" + case 677: +#line 1335 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("int2"); (yyval.typnam)->location = (yylsp[(1) - (1)]); ;} break; - case 666: -#line 1291 "third_party/libpg_query/grammar/statements/select.y" + case 678: +#line 1340 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("int8"); (yyval.typnam)->location = (yylsp[(1) - (1)]); ;} break; - case 667: -#line 1296 "third_party/libpg_query/grammar/statements/select.y" + case 679: +#line 1345 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("float4"); (yyval.typnam)->location = (yylsp[(1) - (1)]); ;} break; - case 668: -#line 1301 "third_party/libpg_query/grammar/statements/select.y" + case 680: +#line 1350 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(2) - (2)].typnam); (yyval.typnam)->location = (yylsp[(1) - (2)]); ;} break; - case 669: -#line 1306 "third_party/libpg_query/grammar/statements/select.y" + case 681: +#line 1355 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("float8"); (yyval.typnam)->location = (yylsp[(1) - (2)]); ;} break; - case 670: -#line 1311 "third_party/libpg_query/grammar/statements/select.y" + case 682: +#line 1360 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("numeric"); (yyval.typnam)->typmods = (yyvsp[(2) - (2)].list); @@ -235086,8 +251176,8 @@ YYLTYPE yylloc; ;} break; - case 671: -#line 1317 "third_party/libpg_query/grammar/statements/select.y" + case 683: +#line 1366 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("numeric"); (yyval.typnam)->typmods = (yyvsp[(2) - (2)].list); @@ -235095,8 +251185,8 @@ YYLTYPE yylloc; ;} break; - case 672: -#line 1323 "third_party/libpg_query/grammar/statements/select.y" + case 684: +#line 1372 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("numeric"); (yyval.typnam)->typmods = (yyvsp[(2) - (2)].list); @@ -235104,16 +251194,16 @@ YYLTYPE yylloc; ;} break; - case 673: -#line 1329 "third_party/libpg_query/grammar/statements/select.y" + case 685: +#line 1378 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("bool"); (yyval.typnam)->location = (yylsp[(1) - (1)]); ;} break; - case 674: -#line 1336 "third_party/libpg_query/grammar/statements/select.y" + case 686: +#line 1385 "third_party/libpg_query/grammar/statements/select.y" { /* * Check FLOAT() precision limits assuming IEEE floating @@ -235136,44 +251226,44 @@ YYLTYPE yylloc; ;} break; - case 675: -#line 1357 "third_party/libpg_query/grammar/statements/select.y" + case 687: +#line 1406 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("float4"); ;} break; - case 676: -#line 1367 "third_party/libpg_query/grammar/statements/select.y" + case 688: +#line 1416 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 677: -#line 1371 "third_party/libpg_query/grammar/statements/select.y" + case 689: +#line 1420 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 678: -#line 1379 "third_party/libpg_query/grammar/statements/select.y" + case 690: +#line 1428 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 679: -#line 1383 "third_party/libpg_query/grammar/statements/select.y" + case 691: +#line 1432 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); (yyval.typnam)->typmods = NIL; ;} break; - case 680: -#line 1391 "third_party/libpg_query/grammar/statements/select.y" + case 692: +#line 1440 "third_party/libpg_query/grammar/statements/select.y" { const char *typname; @@ -235184,8 +251274,8 @@ YYLTYPE yylloc; ;} break; - case 681: -#line 1403 "third_party/libpg_query/grammar/statements/select.y" + case 693: +#line 1452 "third_party/libpg_query/grammar/statements/select.y" { /* bit defaults to bit(1), varbit to no limit */ if ((yyvsp[(2) - (2)].boolean)) @@ -235201,29 +251291,29 @@ YYLTYPE yylloc; ;} break; - case 682: -#line 1424 "third_party/libpg_query/grammar/statements/select.y" + case 694: +#line 1473 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 683: -#line 1428 "third_party/libpg_query/grammar/statements/select.y" + case 695: +#line 1477 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 684: -#line 1434 "third_party/libpg_query/grammar/statements/select.y" + case 696: +#line 1483 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 685: -#line 1438 "third_party/libpg_query/grammar/statements/select.y" + case 697: +#line 1487 "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 @@ -235236,8 +251326,8 @@ YYLTYPE yylloc; ;} break; - case 686: -#line 1451 "third_party/libpg_query/grammar/statements/select.y" + case 698: +#line 1500 "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)]))); @@ -235245,8 +251335,8 @@ YYLTYPE yylloc; ;} break; - case 687: -#line 1459 "third_party/libpg_query/grammar/statements/select.y" + case 699: +#line 1508 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName((yyvsp[(1) - (1)].conststr)); /* char defaults to char(1), varchar to no limit */ @@ -235256,48 +251346,48 @@ YYLTYPE yylloc; ;} break; - case 688: -#line 1469 "third_party/libpg_query/grammar/statements/select.y" + case 700: +#line 1518 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = (yyvsp[(2) - (2)].boolean) ? "varchar": "bpchar"; ;} break; - case 689: -#line 1471 "third_party/libpg_query/grammar/statements/select.y" + case 701: +#line 1520 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = (yyvsp[(2) - (2)].boolean) ? "varchar": "bpchar"; ;} break; - case 690: -#line 1473 "third_party/libpg_query/grammar/statements/select.y" + case 702: +#line 1522 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "varchar"; ;} break; - case 691: -#line 1475 "third_party/libpg_query/grammar/statements/select.y" + case 703: +#line 1524 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = (yyvsp[(3) - (3)].boolean) ? "varchar": "bpchar"; ;} break; - case 692: -#line 1477 "third_party/libpg_query/grammar/statements/select.y" + case 704: +#line 1526 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = (yyvsp[(3) - (3)].boolean) ? "varchar": "bpchar"; ;} break; - case 693: -#line 1479 "third_party/libpg_query/grammar/statements/select.y" + case 705: +#line 1528 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = (yyvsp[(2) - (2)].boolean) ? "varchar": "bpchar"; ;} break; - case 694: -#line 1483 "third_party/libpg_query/grammar/statements/select.y" + case 706: +#line 1532 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = true; ;} break; - case 695: -#line 1484 "third_party/libpg_query/grammar/statements/select.y" + case 707: +#line 1533 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = false; ;} break; - case 696: -#line 1492 "third_party/libpg_query/grammar/statements/select.y" + case 708: +#line 1541 "third_party/libpg_query/grammar/statements/select.y" { if ((yyvsp[(5) - (5)].boolean)) (yyval.typnam) = SystemTypeName("timestamptz"); @@ -235308,8 +251398,8 @@ YYLTYPE yylloc; ;} break; - case 697: -#line 1501 "third_party/libpg_query/grammar/statements/select.y" + case 709: +#line 1550 "third_party/libpg_query/grammar/statements/select.y" { if ((yyvsp[(2) - (2)].boolean)) (yyval.typnam) = SystemTypeName("timestamptz"); @@ -235319,8 +251409,8 @@ YYLTYPE yylloc; ;} break; - case 698: -#line 1509 "third_party/libpg_query/grammar/statements/select.y" + case 710: +#line 1558 "third_party/libpg_query/grammar/statements/select.y" { if ((yyvsp[(5) - (5)].boolean)) (yyval.typnam) = SystemTypeName("timetz"); @@ -235331,8 +251421,8 @@ YYLTYPE yylloc; ;} break; - case 699: -#line 1518 "third_party/libpg_query/grammar/statements/select.y" + case 711: +#line 1567 "third_party/libpg_query/grammar/statements/select.y" { if ((yyvsp[(2) - (2)].boolean)) (yyval.typnam) = SystemTypeName("timetz"); @@ -235342,87 +251432,87 @@ YYLTYPE yylloc; ;} break; - case 700: -#line 1529 "third_party/libpg_query/grammar/statements/select.y" + case 712: +#line 1578 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("interval"); (yyval.typnam)->location = (yylsp[(1) - (1)]); ;} break; - case 701: -#line 1536 "third_party/libpg_query/grammar/statements/select.y" + case 713: +#line 1585 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = true; ;} break; - case 702: -#line 1537 "third_party/libpg_query/grammar/statements/select.y" + case 714: +#line 1586 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = false; ;} break; - case 703: -#line 1538 "third_party/libpg_query/grammar/statements/select.y" + case 715: +#line 1587 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = false; ;} break; - case 720: -#line 1567 "third_party/libpg_query/grammar/statements/select.y" + case 732: +#line 1616 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(YEAR), (yylsp[(1) - (1)]))); ;} break; - case 721: -#line 1569 "third_party/libpg_query/grammar/statements/select.y" + case 733: +#line 1618 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(MONTH), (yylsp[(1) - (1)]))); ;} break; - case 722: -#line 1571 "third_party/libpg_query/grammar/statements/select.y" + case 734: +#line 1620 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(DAY), (yylsp[(1) - (1)]))); ;} break; - case 723: -#line 1573 "third_party/libpg_query/grammar/statements/select.y" + case 735: +#line 1622 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(HOUR), (yylsp[(1) - (1)]))); ;} break; - case 724: -#line 1575 "third_party/libpg_query/grammar/statements/select.y" + case 736: +#line 1624 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(MINUTE), (yylsp[(1) - (1)]))); ;} break; - case 725: -#line 1577 "third_party/libpg_query/grammar/statements/select.y" + case 737: +#line 1626 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(SECOND), (yylsp[(1) - (1)]))); ;} break; - case 726: -#line 1579 "third_party/libpg_query/grammar/statements/select.y" + case 738: +#line 1628 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(MILLISECOND), (yylsp[(1) - (1)]))); ;} break; - case 727: -#line 1581 "third_party/libpg_query/grammar/statements/select.y" + case 739: +#line 1630 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(MICROSECOND), (yylsp[(1) - (1)]))); ;} break; - case 728: -#line 1583 "third_party/libpg_query/grammar/statements/select.y" + case 740: +#line 1632 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(YEAR) | INTERVAL_MASK(MONTH), (yylsp[(1) - (3)]))); ;} break; - case 729: -#line 1588 "third_party/libpg_query/grammar/statements/select.y" + case 741: +#line 1637 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR), (yylsp[(1) - (3)]))); ;} break; - case 730: -#line 1593 "third_party/libpg_query/grammar/statements/select.y" + case 742: +#line 1642 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR) | @@ -235430,8 +251520,8 @@ YYLTYPE yylloc; ;} break; - case 731: -#line 1599 "third_party/libpg_query/grammar/statements/select.y" + case 743: +#line 1648 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR) | @@ -235440,16 +251530,16 @@ YYLTYPE yylloc; ;} break; - case 732: -#line 1606 "third_party/libpg_query/grammar/statements/select.y" + case 744: +#line 1655 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE), (yylsp[(1) - (3)]))); ;} break; - case 733: -#line 1611 "third_party/libpg_query/grammar/statements/select.y" + case 745: +#line 1660 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE) | @@ -235457,31 +251547,31 @@ YYLTYPE yylloc; ;} break; - case 734: -#line 1617 "third_party/libpg_query/grammar/statements/select.y" + case 746: +#line 1666 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND), (yylsp[(1) - (3)]))); ;} break; - case 735: -#line 1622 "third_party/libpg_query/grammar/statements/select.y" + case 747: +#line 1671 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 736: -#line 1653 "third_party/libpg_query/grammar/statements/select.y" + case 748: +#line 1702 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 737: -#line 1656 "third_party/libpg_query/grammar/statements/select.y" + case 749: +#line 1705 "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 738: -#line 1658 "third_party/libpg_query/grammar/statements/select.y" + case 750: +#line 1707 "third_party/libpg_query/grammar/statements/select.y" { PGCollateClause *n = makeNode(PGCollateClause); n->arg = (yyvsp[(1) - (3)].node); @@ -235491,8 +251581,8 @@ YYLTYPE yylloc; ;} break; - case 739: -#line 1666 "third_party/libpg_query/grammar/statements/select.y" + case 751: +#line 1715 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("timezone"), list_make2((yyvsp[(5) - (5)].node), (yyvsp[(1) - (5)].node)), @@ -235500,129 +251590,129 @@ YYLTYPE yylloc; ;} break; - case 740: -#line 1681 "third_party/libpg_query/grammar/statements/select.y" + case 752: +#line 1730 "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 741: -#line 1683 "third_party/libpg_query/grammar/statements/select.y" + case 753: +#line 1732 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = doNegate((yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;} break; - case 742: -#line 1685 "third_party/libpg_query/grammar/statements/select.y" + case 754: +#line 1734 "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 743: -#line 1687 "third_party/libpg_query/grammar/statements/select.y" + case 755: +#line 1736 "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 744: -#line 1689 "third_party/libpg_query/grammar/statements/select.y" + case 756: +#line 1738 "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 745: -#line 1691 "third_party/libpg_query/grammar/statements/select.y" + case 757: +#line 1740 "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 746: -#line 1693 "third_party/libpg_query/grammar/statements/select.y" + case 758: +#line 1742 "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 747: -#line 1695 "third_party/libpg_query/grammar/statements/select.y" + case 759: +#line 1744 "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 748: -#line 1697 "third_party/libpg_query/grammar/statements/select.y" + case 760: +#line 1746 "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 749: -#line 1699 "third_party/libpg_query/grammar/statements/select.y" + case 761: +#line 1748 "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 750: -#line 1701 "third_party/libpg_query/grammar/statements/select.y" + case 762: +#line 1750 "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 751: -#line 1703 "third_party/libpg_query/grammar/statements/select.y" + case 763: +#line 1752 "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 752: -#line 1705 "third_party/libpg_query/grammar/statements/select.y" + case 764: +#line 1754 "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 753: -#line 1707 "third_party/libpg_query/grammar/statements/select.y" + case 765: +#line 1756 "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 754: -#line 1710 "third_party/libpg_query/grammar/statements/select.y" + case 766: +#line 1759 "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 755: -#line 1712 "third_party/libpg_query/grammar/statements/select.y" + case 767: +#line 1761 "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 756: -#line 1714 "third_party/libpg_query/grammar/statements/select.y" + case 768: +#line 1763 "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 757: -#line 1717 "third_party/libpg_query/grammar/statements/select.y" + case 769: +#line 1766 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeAndExpr((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 758: -#line 1719 "third_party/libpg_query/grammar/statements/select.y" + case 770: +#line 1768 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeOrExpr((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 759: -#line 1721 "third_party/libpg_query/grammar/statements/select.y" + case 771: +#line 1770 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeNotExpr((yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;} break; - case 760: -#line 1723 "third_party/libpg_query/grammar/statements/select.y" + case 772: +#line 1772 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeNotExpr((yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;} break; - case 761: -#line 1726 "third_party/libpg_query/grammar/statements/select.y" + case 773: +#line 1775 "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 762: -#line 1731 "third_party/libpg_query/grammar/statements/select.y" + case 774: +#line 1780 "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 763: -#line 1736 "third_party/libpg_query/grammar/statements/select.y" + case 775: +#line 1785 "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)), @@ -235631,16 +251721,16 @@ YYLTYPE yylloc; ;} break; - case 764: -#line 1743 "third_party/libpg_query/grammar/statements/select.y" + case 776: +#line 1792 "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 765: -#line 1748 "third_party/libpg_query/grammar/statements/select.y" + case 777: +#line 1797 "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)), @@ -235649,16 +251739,16 @@ YYLTYPE yylloc; ;} break; - case 766: -#line 1755 "third_party/libpg_query/grammar/statements/select.y" + case 778: +#line 1804 "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 767: -#line 1760 "third_party/libpg_query/grammar/statements/select.y" + case 779: +#line 1809 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("like_escape"), list_make2((yyvsp[(3) - (5)].node), (yyvsp[(5) - (5)].node)), @@ -235668,16 +251758,16 @@ YYLTYPE yylloc; ;} break; - case 768: -#line 1768 "third_party/libpg_query/grammar/statements/select.y" + case 780: +#line 1817 "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 769: -#line 1773 "third_party/libpg_query/grammar/statements/select.y" + case 781: +#line 1822 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("not_like_escape"), list_make2((yyvsp[(4) - (6)].node), (yyvsp[(6) - (6)].node)), @@ -235687,8 +251777,8 @@ YYLTYPE yylloc; ;} break; - case 770: -#line 1782 "third_party/libpg_query/grammar/statements/select.y" + case 782: +#line 1831 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("similar_escape"), list_make2((yyvsp[(4) - (4)].node), makeNullAConst(-1)), @@ -235698,8 +251788,8 @@ YYLTYPE yylloc; ;} break; - case 771: -#line 1790 "third_party/libpg_query/grammar/statements/select.y" + case 783: +#line 1839 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("similar_escape"), list_make2((yyvsp[(4) - (6)].node), (yyvsp[(6) - (6)].node)), @@ -235709,8 +251799,8 @@ YYLTYPE yylloc; ;} break; - case 772: -#line 1798 "third_party/libpg_query/grammar/statements/select.y" + case 784: +#line 1847 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("similar_escape"), list_make2((yyvsp[(5) - (5)].node), makeNullAConst(-1)), @@ -235720,8 +251810,8 @@ YYLTYPE yylloc; ;} break; - case 773: -#line 1806 "third_party/libpg_query/grammar/statements/select.y" + case 785: +#line 1855 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("similar_escape"), list_make2((yyvsp[(5) - (7)].node), (yyvsp[(7) - (7)].node)), @@ -235731,8 +251821,8 @@ YYLTYPE yylloc; ;} break; - case 774: -#line 1824 "third_party/libpg_query/grammar/statements/select.y" + case 786: +#line 1873 "third_party/libpg_query/grammar/statements/select.y" { PGNullTest *n = makeNode(PGNullTest); n->arg = (PGExpr *) (yyvsp[(1) - (3)].node); @@ -235742,8 +251832,8 @@ YYLTYPE yylloc; ;} break; - case 775: -#line 1832 "third_party/libpg_query/grammar/statements/select.y" + case 787: +#line 1881 "third_party/libpg_query/grammar/statements/select.y" { PGNullTest *n = makeNode(PGNullTest); n->arg = (PGExpr *) (yyvsp[(1) - (2)].node); @@ -235753,8 +251843,8 @@ YYLTYPE yylloc; ;} break; - case 776: -#line 1840 "third_party/libpg_query/grammar/statements/select.y" + case 788: +#line 1889 "third_party/libpg_query/grammar/statements/select.y" { PGNullTest *n = makeNode(PGNullTest); n->arg = (PGExpr *) (yyvsp[(1) - (4)].node); @@ -235764,8 +251854,8 @@ YYLTYPE yylloc; ;} break; - case 777: -#line 1848 "third_party/libpg_query/grammar/statements/select.y" + case 789: +#line 1897 "third_party/libpg_query/grammar/statements/select.y" { PGNullTest *n = makeNode(PGNullTest); n->arg = (PGExpr *) (yyvsp[(1) - (3)].node); @@ -235775,8 +251865,8 @@ YYLTYPE yylloc; ;} break; - case 778: -#line 1856 "third_party/libpg_query/grammar/statements/select.y" + case 790: +#line 1905 "third_party/libpg_query/grammar/statements/select.y" { PGNullTest *n = makeNode(PGNullTest); n->arg = (PGExpr *) (yyvsp[(1) - (2)].node); @@ -235786,32 +251876,32 @@ YYLTYPE yylloc; ;} break; - case 779: -#line 1863 "third_party/libpg_query/grammar/statements/select.y" + case 791: +#line 1912 "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 780: -#line 1867 "third_party/libpg_query/grammar/statements/select.y" + case 792: +#line 1916 "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 781: -#line 1871 "third_party/libpg_query/grammar/statements/select.y" + case 793: +#line 1920 "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 782: -#line 1876 "third_party/libpg_query/grammar/statements/select.y" + case 794: +#line 1925 "third_party/libpg_query/grammar/statements/select.y" { PGLambdaFunction *n = makeNode(PGLambdaFunction); n->parameters = (yyvsp[(1) - (3)].list); @@ -235821,8 +251911,8 @@ YYLTYPE yylloc; ;} break; - case 783: -#line 1884 "third_party/libpg_query/grammar/statements/select.y" + case 795: +#line 1933 "third_party/libpg_query/grammar/statements/select.y" { PGLambdaFunction *n = makeNode(PGLambdaFunction); n->parameters = list_make1((yyvsp[(1) - (3)].node)); @@ -235832,8 +251922,8 @@ YYLTYPE yylloc; ;} break; - case 784: -#line 1892 "third_party/libpg_query/grammar/statements/select.y" + case 796: +#line 1941 "third_party/libpg_query/grammar/statements/select.y" { if (list_length((yyvsp[(1) - (3)].list)) != 2) ereport(ERROR, @@ -235851,8 +251941,8 @@ YYLTYPE yylloc; ;} break; - case 785: -#line 1908 "third_party/libpg_query/grammar/statements/select.y" + case 797: +#line 1957 "third_party/libpg_query/grammar/statements/select.y" { PGBooleanTest *b = makeNode(PGBooleanTest); b->arg = (PGExpr *) (yyvsp[(1) - (3)].node); @@ -235862,8 +251952,8 @@ YYLTYPE yylloc; ;} break; - case 786: -#line 1916 "third_party/libpg_query/grammar/statements/select.y" + case 798: +#line 1965 "third_party/libpg_query/grammar/statements/select.y" { PGBooleanTest *b = makeNode(PGBooleanTest); b->arg = (PGExpr *) (yyvsp[(1) - (4)].node); @@ -235873,8 +251963,8 @@ YYLTYPE yylloc; ;} break; - case 787: -#line 1924 "third_party/libpg_query/grammar/statements/select.y" + case 799: +#line 1973 "third_party/libpg_query/grammar/statements/select.y" { PGBooleanTest *b = makeNode(PGBooleanTest); b->arg = (PGExpr *) (yyvsp[(1) - (3)].node); @@ -235884,8 +251974,8 @@ YYLTYPE yylloc; ;} break; - case 788: -#line 1932 "third_party/libpg_query/grammar/statements/select.y" + case 800: +#line 1981 "third_party/libpg_query/grammar/statements/select.y" { PGBooleanTest *b = makeNode(PGBooleanTest); b->arg = (PGExpr *) (yyvsp[(1) - (4)].node); @@ -235895,8 +251985,8 @@ YYLTYPE yylloc; ;} break; - case 789: -#line 1940 "third_party/libpg_query/grammar/statements/select.y" + case 801: +#line 1989 "third_party/libpg_query/grammar/statements/select.y" { PGBooleanTest *b = makeNode(PGBooleanTest); b->arg = (PGExpr *) (yyvsp[(1) - (3)].node); @@ -235906,8 +251996,8 @@ YYLTYPE yylloc; ;} break; - case 790: -#line 1948 "third_party/libpg_query/grammar/statements/select.y" + case 802: +#line 1997 "third_party/libpg_query/grammar/statements/select.y" { PGBooleanTest *b = makeNode(PGBooleanTest); b->arg = (PGExpr *) (yyvsp[(1) - (4)].node); @@ -235917,36 +252007,36 @@ YYLTYPE yylloc; ;} break; - case 791: -#line 1956 "third_party/libpg_query/grammar/statements/select.y" + case 803: +#line 2005 "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 792: -#line 1960 "third_party/libpg_query/grammar/statements/select.y" + case 804: +#line 2009 "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 793: -#line 1964 "third_party/libpg_query/grammar/statements/select.y" + case 805: +#line 2013 "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 794: -#line 1968 "third_party/libpg_query/grammar/statements/select.y" + case 806: +#line 2017 "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 795: -#line 1972 "third_party/libpg_query/grammar/statements/select.y" + case 807: +#line 2021 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_BETWEEN, "BETWEEN", @@ -235956,8 +252046,8 @@ YYLTYPE yylloc; ;} break; - case 796: -#line 1980 "third_party/libpg_query/grammar/statements/select.y" + case 808: +#line 2029 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_NOT_BETWEEN, "NOT BETWEEN", @@ -235967,8 +252057,8 @@ YYLTYPE yylloc; ;} break; - case 797: -#line 1988 "third_party/libpg_query/grammar/statements/select.y" + case 809: +#line 2037 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_BETWEEN_SYM, "BETWEEN SYMMETRIC", @@ -235978,8 +252068,8 @@ YYLTYPE yylloc; ;} break; - case 798: -#line 1996 "third_party/libpg_query/grammar/statements/select.y" + case 810: +#line 2045 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_NOT_BETWEEN_SYM, "NOT BETWEEN SYMMETRIC", @@ -235989,8 +252079,8 @@ YYLTYPE yylloc; ;} break; - case 799: -#line 2004 "third_party/libpg_query/grammar/statements/select.y" + case 811: +#line 2053 "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)) @@ -236012,8 +252102,8 @@ YYLTYPE yylloc; ;} break; - case 800: -#line 2024 "third_party/libpg_query/grammar/statements/select.y" + case 812: +#line 2073 "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)) @@ -236037,8 +252127,8 @@ YYLTYPE yylloc; ;} break; - case 801: -#line 2046 "third_party/libpg_query/grammar/statements/select.y" + case 813: +#line 2095 "third_party/libpg_query/grammar/statements/select.y" { PGSubLink *n = makeNode(PGSubLink); n->subLinkType = (yyvsp[(3) - (4)].subquerytype); @@ -236051,8 +252141,8 @@ YYLTYPE yylloc; ;} break; - case 802: -#line 2057 "third_party/libpg_query/grammar/statements/select.y" + case 814: +#line 2106 "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)])); @@ -236061,8 +252151,8 @@ YYLTYPE yylloc; ;} break; - case 803: -#line 2064 "third_party/libpg_query/grammar/statements/select.y" + case 815: +#line 2113 "third_party/libpg_query/grammar/statements/select.y" { /* * The SQL spec only allows DEFAULT in "contextually typed @@ -236078,8 +252168,8 @@ YYLTYPE yylloc; ;} break; - case 804: -#line 2077 "third_party/libpg_query/grammar/statements/select.y" + case 816: +#line 2126 "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)])); @@ -236087,141 +252177,141 @@ YYLTYPE yylloc; ;} break; - case 805: -#line 2094 "third_party/libpg_query/grammar/statements/select.y" + case 817: +#line 2143 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 806: -#line 2096 "third_party/libpg_query/grammar/statements/select.y" + case 818: +#line 2145 "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 807: -#line 2098 "third_party/libpg_query/grammar/statements/select.y" + case 819: +#line 2147 "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 808: -#line 2100 "third_party/libpg_query/grammar/statements/select.y" + case 820: +#line 2149 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = doNegate((yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;} break; - case 809: -#line 2102 "third_party/libpg_query/grammar/statements/select.y" + case 821: +#line 2151 "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 810: -#line 2104 "third_party/libpg_query/grammar/statements/select.y" + case 822: +#line 2153 "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 811: -#line 2106 "third_party/libpg_query/grammar/statements/select.y" + case 823: +#line 2155 "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 812: -#line 2108 "third_party/libpg_query/grammar/statements/select.y" + case 824: +#line 2157 "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 813: -#line 2110 "third_party/libpg_query/grammar/statements/select.y" + case 825: +#line 2159 "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 814: -#line 2112 "third_party/libpg_query/grammar/statements/select.y" + case 826: +#line 2161 "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 815: -#line 2114 "third_party/libpg_query/grammar/statements/select.y" + case 827: +#line 2163 "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 816: -#line 2116 "third_party/libpg_query/grammar/statements/select.y" + case 828: +#line 2165 "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 817: -#line 2118 "third_party/libpg_query/grammar/statements/select.y" + case 829: +#line 2167 "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 818: -#line 2120 "third_party/libpg_query/grammar/statements/select.y" + case 830: +#line 2169 "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 819: -#line 2122 "third_party/libpg_query/grammar/statements/select.y" + case 831: +#line 2171 "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 820: -#line 2124 "third_party/libpg_query/grammar/statements/select.y" + case 832: +#line 2173 "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 821: -#line 2126 "third_party/libpg_query/grammar/statements/select.y" + case 833: +#line 2175 "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 822: -#line 2128 "third_party/libpg_query/grammar/statements/select.y" + case 834: +#line 2177 "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 823: -#line 2130 "third_party/libpg_query/grammar/statements/select.y" + case 835: +#line 2179 "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 824: -#line 2132 "third_party/libpg_query/grammar/statements/select.y" + case 836: +#line 2181 "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 825: -#line 2136 "third_party/libpg_query/grammar/statements/select.y" + case 837: +#line 2185 "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 826: -#line 2140 "third_party/libpg_query/grammar/statements/select.y" + case 838: +#line 2189 "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 827: -#line 2144 "third_party/libpg_query/grammar/statements/select.y" + case 839: +#line 2193 "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 828: -#line 2157 "third_party/libpg_query/grammar/statements/select.y" + case 840: +#line 2206 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 829: -#line 2158 "third_party/libpg_query/grammar/statements/select.y" + case 841: +#line 2207 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 830: -#line 2160 "third_party/libpg_query/grammar/statements/select.y" + case 842: +#line 2209 "third_party/libpg_query/grammar/statements/select.y" { PGPositionalReference *n = makeNode(PGPositionalReference); n->position = (yyvsp[(2) - (2)].ival); @@ -236230,8 +252320,8 @@ YYLTYPE yylloc; ;} break; - case 831: -#line 2167 "third_party/libpg_query/grammar/statements/select.y" + case 843: +#line 2216 "third_party/libpg_query/grammar/statements/select.y" { if ((yyvsp[(2) - (2)].list)) { @@ -236245,8 +252335,8 @@ YYLTYPE yylloc; ;} break; - case 832: -#line 2179 "third_party/libpg_query/grammar/statements/select.y" + case 844: +#line 2228 "third_party/libpg_query/grammar/statements/select.y" { PGParamRef *p = makeNode(PGParamRef); p->number = (yyvsp[(1) - (2)].ival); @@ -236263,8 +252353,8 @@ YYLTYPE yylloc; ;} break; - case 833: -#line 2194 "third_party/libpg_query/grammar/statements/select.y" + case 845: +#line 2243 "third_party/libpg_query/grammar/statements/select.y" { if ((yyvsp[(4) - (4)].list)) { @@ -236278,13 +252368,13 @@ YYLTYPE yylloc; ;} break; - case 834: -#line 2206 "third_party/libpg_query/grammar/statements/select.y" + case 846: +#line 2255 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 835: -#line 2208 "third_party/libpg_query/grammar/statements/select.y" + case 847: +#line 2257 "third_party/libpg_query/grammar/statements/select.y" { if ((yyvsp[(2) - (2)].list)) { PGAIndirection *n = makeNode(PGAIndirection); @@ -236298,8 +252388,8 @@ YYLTYPE yylloc; ;} break; - case 836: -#line 2220 "third_party/libpg_query/grammar/statements/select.y" + case 848: +#line 2269 "third_party/libpg_query/grammar/statements/select.y" { PGSubLink *n = makeNode(PGSubLink); n->subLinkType = PG_EXPR_SUBLINK; @@ -236312,8 +252402,8 @@ YYLTYPE yylloc; ;} break; - case 837: -#line 2231 "third_party/libpg_query/grammar/statements/select.y" + case 849: +#line 2280 "third_party/libpg_query/grammar/statements/select.y" { /* * Because the select_with_parens nonterminal is designed @@ -236339,8 +252429,8 @@ YYLTYPE yylloc; ;} break; - case 838: -#line 2255 "third_party/libpg_query/grammar/statements/select.y" + case 850: +#line 2304 "third_party/libpg_query/grammar/statements/select.y" { PGSubLink *n = makeNode(PGSubLink); n->subLinkType = PG_EXISTS_SUBLINK; @@ -236353,8 +252443,8 @@ YYLTYPE yylloc; ;} break; - case 839: -#line 2266 "third_party/libpg_query/grammar/statements/select.y" + case 851: +#line 2315 "third_party/libpg_query/grammar/statements/select.y" { PGGroupingFunc *g = makeNode(PGGroupingFunc); g->args = (yyvsp[(3) - (4)].list); @@ -236363,47 +252453,51 @@ YYLTYPE yylloc; ;} break; - case 840: -#line 2275 "third_party/libpg_query/grammar/statements/select.y" + case 852: +#line 2324 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeFuncCall((yyvsp[(1) - (3)].list), NIL, (yylsp[(1) - (3)])); ;} break; - case 841: -#line 2279 "third_party/libpg_query/grammar/statements/select.y" + case 853: +#line 2328 "third_party/libpg_query/grammar/statements/select.y" { - PGFuncCall *n = makeFuncCall((yyvsp[(1) - (5)].list), (yyvsp[(3) - (5)].list), (yylsp[(1) - (5)])); - n->agg_order = (yyvsp[(4) - (5)].list); + PGFuncCall *n = makeFuncCall((yyvsp[(1) - (6)].list), (yyvsp[(3) - (6)].list), (yylsp[(1) - (6)])); + n->agg_order = (yyvsp[(4) - (6)].list); + n->agg_ignore_nulls = (yyvsp[(5) - (6)].boolean); (yyval.node) = (PGNode *)n; ;} break; - case 842: -#line 2285 "third_party/libpg_query/grammar/statements/select.y" + case 854: +#line 2335 "third_party/libpg_query/grammar/statements/select.y" { - PGFuncCall *n = makeFuncCall((yyvsp[(1) - (6)].list), list_make1((yyvsp[(4) - (6)].node)), (yylsp[(1) - (6)])); + PGFuncCall *n = makeFuncCall((yyvsp[(1) - (7)].list), list_make1((yyvsp[(4) - (7)].node)), (yylsp[(1) - (7)])); n->func_variadic = true; - n->agg_order = (yyvsp[(5) - (6)].list); + n->agg_order = (yyvsp[(5) - (7)].list); + n->agg_ignore_nulls = (yyvsp[(6) - (7)].boolean); (yyval.node) = (PGNode *)n; ;} break; - case 843: -#line 2292 "third_party/libpg_query/grammar/statements/select.y" + case 855: +#line 2343 "third_party/libpg_query/grammar/statements/select.y" { - PGFuncCall *n = makeFuncCall((yyvsp[(1) - (8)].list), lappend((yyvsp[(3) - (8)].list), (yyvsp[(6) - (8)].node)), (yylsp[(1) - (8)])); + PGFuncCall *n = makeFuncCall((yyvsp[(1) - (9)].list), lappend((yyvsp[(3) - (9)].list), (yyvsp[(6) - (9)].node)), (yylsp[(1) - (9)])); n->func_variadic = true; - n->agg_order = (yyvsp[(7) - (8)].list); + n->agg_order = (yyvsp[(7) - (9)].list); + n->agg_ignore_nulls = (yyvsp[(8) - (9)].boolean); (yyval.node) = (PGNode *)n; ;} break; - case 844: -#line 2299 "third_party/libpg_query/grammar/statements/select.y" + case 856: +#line 2351 "third_party/libpg_query/grammar/statements/select.y" { - PGFuncCall *n = makeFuncCall((yyvsp[(1) - (6)].list), (yyvsp[(4) - (6)].list), (yylsp[(1) - (6)])); - n->agg_order = (yyvsp[(5) - (6)].list); + PGFuncCall *n = makeFuncCall((yyvsp[(1) - (7)].list), (yyvsp[(4) - (7)].list), (yylsp[(1) - (7)])); + n->agg_order = (yyvsp[(5) - (7)].list); + n->agg_ignore_nulls = (yyvsp[(6) - (7)].boolean); /* Ideally we'd mark the PGFuncCall node to indicate * "must be an aggregate", but there's no provision * for that in PGFuncCall at the moment. @@ -236412,18 +252506,19 @@ YYLTYPE yylloc; ;} break; - case 845: -#line 2309 "third_party/libpg_query/grammar/statements/select.y" + case 857: +#line 2362 "third_party/libpg_query/grammar/statements/select.y" { - PGFuncCall *n = makeFuncCall((yyvsp[(1) - (6)].list), (yyvsp[(4) - (6)].list), (yylsp[(1) - (6)])); - n->agg_order = (yyvsp[(5) - (6)].list); + PGFuncCall *n = makeFuncCall((yyvsp[(1) - (7)].list), (yyvsp[(4) - (7)].list), (yylsp[(1) - (7)])); + n->agg_order = (yyvsp[(5) - (7)].list); + n->agg_ignore_nulls = (yyvsp[(6) - (7)].boolean); n->agg_distinct = true; (yyval.node) = (PGNode *)n; ;} break; - case 846: -#line 2316 "third_party/libpg_query/grammar/statements/select.y" + case 858: +#line 2370 "third_party/libpg_query/grammar/statements/select.y" { /* * We consider AGGREGATE(*) to invoke a parameterless @@ -236441,8 +252536,8 @@ YYLTYPE yylloc; ;} break; - case 847: -#line 2344 "third_party/libpg_query/grammar/statements/select.y" + case 859: +#line 2398 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = (PGFuncCall *) (yyvsp[(1) - (4)].node); /* @@ -236479,23 +252574,23 @@ YYLTYPE yylloc; ;} break; - case 848: -#line 2379 "third_party/libpg_query/grammar/statements/select.y" + case 860: +#line 2433 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 849: -#line 2389 "third_party/libpg_query/grammar/statements/select.y" + case 861: +#line 2443 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 850: -#line 2390 "third_party/libpg_query/grammar/statements/select.y" + case 862: +#line 2444 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 851: -#line 2398 "third_party/libpg_query/grammar/statements/select.y" + case 863: +#line 2452 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("pg_collation_for"), list_make1((yyvsp[(4) - (5)].node)), @@ -236503,130 +252598,130 @@ YYLTYPE yylloc; ;} break; - case 852: -#line 2404 "third_party/libpg_query/grammar/statements/select.y" + case 864: +#line 2458 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_CURRENT_DATE, -1, (yylsp[(1) - (1)])); ;} break; - case 853: -#line 2408 "third_party/libpg_query/grammar/statements/select.y" + case 865: +#line 2462 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_CURRENT_TIME, -1, (yylsp[(1) - (1)])); ;} break; - case 854: -#line 2412 "third_party/libpg_query/grammar/statements/select.y" + case 866: +#line 2466 "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 855: -#line 2416 "third_party/libpg_query/grammar/statements/select.y" + case 867: +#line 2470 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_CURRENT_TIMESTAMP, -1, (yylsp[(1) - (1)])); ;} break; - case 856: -#line 2420 "third_party/libpg_query/grammar/statements/select.y" + case 868: +#line 2474 "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 857: -#line 2424 "third_party/libpg_query/grammar/statements/select.y" + case 869: +#line 2478 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_LOCALTIME, -1, (yylsp[(1) - (1)])); ;} break; - case 858: -#line 2428 "third_party/libpg_query/grammar/statements/select.y" + case 870: +#line 2482 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_LOCALTIME_N, (yyvsp[(3) - (4)].ival), (yylsp[(1) - (4)])); ;} break; - case 859: -#line 2432 "third_party/libpg_query/grammar/statements/select.y" + case 871: +#line 2486 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_LOCALTIMESTAMP, -1, (yylsp[(1) - (1)])); ;} break; - case 860: -#line 2436 "third_party/libpg_query/grammar/statements/select.y" + case 872: +#line 2490 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_LOCALTIMESTAMP_N, (yyvsp[(3) - (4)].ival), (yylsp[(1) - (4)])); ;} break; - case 861: -#line 2440 "third_party/libpg_query/grammar/statements/select.y" + case 873: +#line 2494 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_CURRENT_ROLE, -1, (yylsp[(1) - (1)])); ;} break; - case 862: -#line 2444 "third_party/libpg_query/grammar/statements/select.y" + case 874: +#line 2498 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_CURRENT_USER, -1, (yylsp[(1) - (1)])); ;} break; - case 863: -#line 2448 "third_party/libpg_query/grammar/statements/select.y" + case 875: +#line 2502 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_SESSION_USER, -1, (yylsp[(1) - (1)])); ;} break; - case 864: -#line 2452 "third_party/libpg_query/grammar/statements/select.y" + case 876: +#line 2506 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_USER, -1, (yylsp[(1) - (1)])); ;} break; - case 865: -#line 2456 "third_party/libpg_query/grammar/statements/select.y" + case 877: +#line 2510 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_CURRENT_CATALOG, -1, (yylsp[(1) - (1)])); ;} break; - case 866: -#line 2460 "third_party/libpg_query/grammar/statements/select.y" + case 878: +#line 2514 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_CURRENT_SCHEMA, -1, (yylsp[(1) - (1)])); ;} break; - case 867: -#line 2464 "third_party/libpg_query/grammar/statements/select.y" + case 879: +#line 2518 "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 868: -#line 2466 "third_party/libpg_query/grammar/statements/select.y" + case 880: +#line 2520 "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 869: -#line 2468 "third_party/libpg_query/grammar/statements/select.y" + case 881: +#line 2522 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("date_part"), (yyvsp[(3) - (4)].list), (yylsp[(1) - (4)])); ;} break; - case 870: -#line 2472 "third_party/libpg_query/grammar/statements/select.y" + case 882: +#line 2526 "third_party/libpg_query/grammar/statements/select.y" { /* overlay(A PLACING B FROM C FOR D) is converted to * overlay(A, B, C, D) @@ -236637,16 +252732,16 @@ YYLTYPE yylloc; ;} break; - case 871: -#line 2481 "third_party/libpg_query/grammar/statements/select.y" + case 883: +#line 2535 "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 872: -#line 2486 "third_party/libpg_query/grammar/statements/select.y" + case 884: +#line 2540 "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 @@ -236655,8 +252750,8 @@ YYLTYPE yylloc; ;} break; - case 873: -#line 2493 "third_party/libpg_query/grammar/statements/select.y" + case 885: +#line 2547 "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. @@ -236673,8 +252768,8 @@ YYLTYPE yylloc; ;} break; - case 874: -#line 2508 "third_party/libpg_query/grammar/statements/select.y" + case 886: +#line 2562 "third_party/libpg_query/grammar/statements/select.y" { /* various trim expressions are defined in SQL * - thomas 1997-07-19 @@ -236683,36 +252778,36 @@ YYLTYPE yylloc; ;} break; - case 875: -#line 2515 "third_party/libpg_query/grammar/statements/select.y" + case 887: +#line 2569 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("ltrim"), (yyvsp[(4) - (5)].list), (yylsp[(1) - (5)])); ;} break; - case 876: -#line 2519 "third_party/libpg_query/grammar/statements/select.y" + case 888: +#line 2573 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("rtrim"), (yyvsp[(4) - (5)].list), (yylsp[(1) - (5)])); ;} break; - case 877: -#line 2523 "third_party/libpg_query/grammar/statements/select.y" + case 889: +#line 2577 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("trim"), (yyvsp[(3) - (4)].list), (yylsp[(1) - (4)])); ;} break; - case 878: -#line 2527 "third_party/libpg_query/grammar/statements/select.y" + case 890: +#line 2581 "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 879: -#line 2531 "third_party/libpg_query/grammar/statements/select.y" + case 891: +#line 2585 "third_party/libpg_query/grammar/statements/select.y" { PGCoalesceExpr *c = makeNode(PGCoalesceExpr); c->args = (yyvsp[(3) - (4)].list); @@ -236721,48 +252816,48 @@ YYLTYPE yylloc; ;} break; - case 880: -#line 2544 "third_party/libpg_query/grammar/statements/select.y" + case 892: +#line 2598 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(4) - (5)].list); ;} break; - case 881: -#line 2545 "third_party/libpg_query/grammar/statements/select.y" + case 893: +#line 2599 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 882: -#line 2549 "third_party/libpg_query/grammar/statements/select.y" + case 894: +#line 2603 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(4) - (5)].node); ;} break; - case 883: -#line 2550 "third_party/libpg_query/grammar/statements/select.y" + case 895: +#line 2604 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 884: -#line 2558 "third_party/libpg_query/grammar/statements/select.y" + case 896: +#line 2612 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(2) - (2)].list); ;} break; - case 885: -#line 2559 "third_party/libpg_query/grammar/statements/select.y" + case 897: +#line 2613 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 886: -#line 2563 "third_party/libpg_query/grammar/statements/select.y" + case 898: +#line 2617 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].windef)); ;} break; - case 887: -#line 2565 "third_party/libpg_query/grammar/statements/select.y" + case 899: +#line 2619 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].windef)); ;} break; - case 888: -#line 2570 "third_party/libpg_query/grammar/statements/select.y" + case 900: +#line 2624 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = (yyvsp[(3) - (3)].windef); n->name = (yyvsp[(1) - (3)].str); @@ -236770,13 +252865,13 @@ YYLTYPE yylloc; ;} break; - case 889: -#line 2578 "third_party/libpg_query/grammar/statements/select.y" + case 901: +#line 2632 "third_party/libpg_query/grammar/statements/select.y" { (yyval.windef) = (yyvsp[(2) - (2)].windef); ;} break; - case 890: -#line 2580 "third_party/libpg_query/grammar/statements/select.y" + case 902: +#line 2634 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = makeNode(PGWindowDef); n->name = (yyvsp[(2) - (2)].str); @@ -236791,13 +252886,13 @@ YYLTYPE yylloc; ;} break; - case 891: -#line 2593 "third_party/libpg_query/grammar/statements/select.y" + case 903: +#line 2647 "third_party/libpg_query/grammar/statements/select.y" { (yyval.windef) = NULL; ;} break; - case 892: -#line 2598 "third_party/libpg_query/grammar/statements/select.y" + case 904: +#line 2652 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = makeNode(PGWindowDef); n->name = NULL; @@ -236813,28 +252908,28 @@ YYLTYPE yylloc; ;} break; - case 893: -#line 2623 "third_party/libpg_query/grammar/statements/select.y" + case 905: +#line 2677 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 894: -#line 2624 "third_party/libpg_query/grammar/statements/select.y" + case 906: +#line 2678 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = NULL; ;} break; - case 895: -#line 2627 "third_party/libpg_query/grammar/statements/select.y" + case 907: +#line 2681 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (3)].list); ;} break; - case 896: -#line 2628 "third_party/libpg_query/grammar/statements/select.y" + case 908: +#line 2682 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 897: -#line 2640 "third_party/libpg_query/grammar/statements/select.y" + case 909: +#line 2694 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = (yyvsp[(2) - (2)].windef); n->frameOptions |= FRAMEOPTION_NONDEFAULT | FRAMEOPTION_RANGE; @@ -236842,8 +252937,8 @@ YYLTYPE yylloc; ;} break; - case 898: -#line 2646 "third_party/libpg_query/grammar/statements/select.y" + case 910: +#line 2700 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = (yyvsp[(2) - (2)].windef); n->frameOptions |= FRAMEOPTION_NONDEFAULT | FRAMEOPTION_ROWS; @@ -236851,8 +252946,8 @@ YYLTYPE yylloc; ;} break; - case 899: -#line 2652 "third_party/libpg_query/grammar/statements/select.y" + case 911: +#line 2706 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = makeNode(PGWindowDef); n->frameOptions = FRAMEOPTION_DEFAULTS; @@ -236862,8 +252957,8 @@ YYLTYPE yylloc; ;} break; - case 900: -#line 2662 "third_party/libpg_query/grammar/statements/select.y" + case 912: +#line 2716 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = (yyvsp[(1) - (1)].windef); /* reject invalid cases */ @@ -236882,8 +252977,8 @@ YYLTYPE yylloc; ;} break; - case 901: -#line 2679 "third_party/libpg_query/grammar/statements/select.y" + case 913: +#line 2733 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n1 = (yyvsp[(2) - (4)].windef); PGWindowDef *n2 = (yyvsp[(4) - (4)].windef); @@ -236922,8 +253017,8 @@ YYLTYPE yylloc; ;} break; - case 902: -#line 2724 "third_party/libpg_query/grammar/statements/select.y" + case 914: +#line 2778 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = makeNode(PGWindowDef); n->frameOptions = FRAMEOPTION_START_UNBOUNDED_PRECEDING; @@ -236933,8 +253028,8 @@ YYLTYPE yylloc; ;} break; - case 903: -#line 2732 "third_party/libpg_query/grammar/statements/select.y" + case 915: +#line 2786 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = makeNode(PGWindowDef); n->frameOptions = FRAMEOPTION_START_UNBOUNDED_FOLLOWING; @@ -236944,8 +253039,8 @@ YYLTYPE yylloc; ;} break; - case 904: -#line 2740 "third_party/libpg_query/grammar/statements/select.y" + case 916: +#line 2794 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = makeNode(PGWindowDef); n->frameOptions = FRAMEOPTION_START_CURRENT_ROW; @@ -236955,8 +253050,8 @@ YYLTYPE yylloc; ;} break; - case 905: -#line 2748 "third_party/libpg_query/grammar/statements/select.y" + case 917: +#line 2802 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = makeNode(PGWindowDef); n->frameOptions = FRAMEOPTION_START_VALUE_PRECEDING; @@ -236966,8 +253061,8 @@ YYLTYPE yylloc; ;} break; - case 906: -#line 2756 "third_party/libpg_query/grammar/statements/select.y" + case 918: +#line 2810 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = makeNode(PGWindowDef); n->frameOptions = FRAMEOPTION_START_VALUE_FOLLOWING; @@ -236977,28 +253072,28 @@ YYLTYPE yylloc; ;} break; - case 907: -#line 2776 "third_party/libpg_query/grammar/statements/select.y" + case 919: +#line 2830 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (4)].list); ;} break; - case 908: -#line 2777 "third_party/libpg_query/grammar/statements/select.y" + case 920: +#line 2831 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 909: -#line 2780 "third_party/libpg_query/grammar/statements/select.y" + case 921: +#line 2834 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list);;} break; - case 910: -#line 2781 "third_party/libpg_query/grammar/statements/select.y" + case 922: +#line 2835 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(2) - (5)].list), (yyvsp[(4) - (5)].node)); ;} break; - case 911: -#line 2785 "third_party/libpg_query/grammar/statements/select.y" + case 923: +#line 2839 "third_party/libpg_query/grammar/statements/select.y" { PGNamedArgExpr *na = makeNode(PGNamedArgExpr); na->name = (yyvsp[(1) - (3)].str); @@ -237009,222 +253104,222 @@ YYLTYPE yylloc; ;} break; - case 912: -#line 2795 "third_party/libpg_query/grammar/statements/select.y" + case 924: +#line 2849 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 913: -#line 2796 "third_party/libpg_query/grammar/statements/select.y" + case 925: +#line 2850 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;} break; - case 914: -#line 2798 "third_party/libpg_query/grammar/statements/select.y" + case 926: +#line 2852 "third_party/libpg_query/grammar/statements/select.y" { (yyval.subquerytype) = PG_ANY_SUBLINK; ;} break; - case 915: -#line 2799 "third_party/libpg_query/grammar/statements/select.y" + case 927: +#line 2853 "third_party/libpg_query/grammar/statements/select.y" { (yyval.subquerytype) = PG_ANY_SUBLINK; ;} break; - case 916: -#line 2800 "third_party/libpg_query/grammar/statements/select.y" + case 928: +#line 2854 "third_party/libpg_query/grammar/statements/select.y" { (yyval.subquerytype) = PG_ALL_SUBLINK; ;} break; - case 917: -#line 2803 "third_party/libpg_query/grammar/statements/select.y" + case 929: +#line 2857 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 918: -#line 2804 "third_party/libpg_query/grammar/statements/select.y" + case 930: +#line 2858 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) (yyvsp[(1) - (1)].conststr); ;} break; - case 919: -#line 2807 "third_party/libpg_query/grammar/statements/select.y" + case 931: +#line 2861 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "+"; ;} break; - case 920: -#line 2808 "third_party/libpg_query/grammar/statements/select.y" + case 932: +#line 2862 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "-"; ;} break; - case 921: -#line 2809 "third_party/libpg_query/grammar/statements/select.y" + case 933: +#line 2863 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "*"; ;} break; - case 922: -#line 2810 "third_party/libpg_query/grammar/statements/select.y" + case 934: +#line 2864 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "/"; ;} break; - case 923: -#line 2811 "third_party/libpg_query/grammar/statements/select.y" + case 935: +#line 2865 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "%"; ;} break; - case 924: -#line 2812 "third_party/libpg_query/grammar/statements/select.y" + case 936: +#line 2866 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "^"; ;} break; - case 925: -#line 2813 "third_party/libpg_query/grammar/statements/select.y" + case 937: +#line 2867 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "<"; ;} break; - case 926: -#line 2814 "third_party/libpg_query/grammar/statements/select.y" + case 938: +#line 2868 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = ">"; ;} break; - case 927: -#line 2815 "third_party/libpg_query/grammar/statements/select.y" + case 939: +#line 2869 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "="; ;} break; - case 928: -#line 2816 "third_party/libpg_query/grammar/statements/select.y" + case 940: +#line 2870 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "<="; ;} break; - case 929: -#line 2817 "third_party/libpg_query/grammar/statements/select.y" + case 941: +#line 2871 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = ">="; ;} break; - case 930: -#line 2818 "third_party/libpg_query/grammar/statements/select.y" + case 942: +#line 2872 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "<>"; ;} break; - case 931: -#line 2822 "third_party/libpg_query/grammar/statements/select.y" + case 943: +#line 2876 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;} break; - case 932: -#line 2824 "third_party/libpg_query/grammar/statements/select.y" + case 944: +#line 2878 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (4)].list); ;} break; - case 933: -#line 2829 "third_party/libpg_query/grammar/statements/select.y" + case 945: +#line 2883 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;} break; - case 934: -#line 2831 "third_party/libpg_query/grammar/statements/select.y" + case 946: +#line 2885 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (4)].list); ;} break; - case 935: -#line 2836 "third_party/libpg_query/grammar/statements/select.y" + case 947: +#line 2890 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;} break; - case 936: -#line 2838 "third_party/libpg_query/grammar/statements/select.y" + case 948: +#line 2892 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (4)].list); ;} break; - case 937: -#line 2840 "third_party/libpg_query/grammar/statements/select.y" + case 949: +#line 2894 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString("~~")); ;} break; - case 938: -#line 2842 "third_party/libpg_query/grammar/statements/select.y" + case 950: +#line 2896 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString("!~~")); ;} break; - case 939: -#line 2844 "third_party/libpg_query/grammar/statements/select.y" + case 951: +#line 2898 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString("~~~")); ;} break; - case 940: -#line 2846 "third_party/libpg_query/grammar/statements/select.y" + case 952: +#line 2900 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString("!~~~")); ;} break; - case 941: -#line 2848 "third_party/libpg_query/grammar/statements/select.y" + case 953: +#line 2902 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString("~~*")); ;} break; - case 942: -#line 2850 "third_party/libpg_query/grammar/statements/select.y" + case 954: +#line 2904 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString("!~~*")); ;} break; - case 943: -#line 2864 "third_party/libpg_query/grammar/statements/select.y" + case 955: +#line 2918 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;} break; - case 944: -#line 2866 "third_party/libpg_query/grammar/statements/select.y" + case 956: +#line 2920 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lcons(makeString((yyvsp[(1) - (3)].str)), (yyvsp[(3) - (3)].list)); ;} break; - case 945: -#line 2870 "third_party/libpg_query/grammar/statements/select.y" + case 957: +#line 2924 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 946: -#line 2874 "third_party/libpg_query/grammar/statements/select.y" + case 958: +#line 2928 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;} break; - case 947: -#line 2881 "third_party/libpg_query/grammar/statements/select.y" + case 959: +#line 2935 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 948: -#line 2885 "third_party/libpg_query/grammar/statements/select.y" + case 960: +#line 2939 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NULL; ;} break; - case 949: -#line 2893 "third_party/libpg_query/grammar/statements/select.y" + case 961: +#line 2947 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 950: -#line 2897 "third_party/libpg_query/grammar/statements/select.y" + case 962: +#line 2951 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;} break; - case 951: -#line 2903 "third_party/libpg_query/grammar/statements/select.y" + case 963: +#line 2957 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 952: -#line 2907 "third_party/libpg_query/grammar/statements/select.y" + case 964: +#line 2961 "third_party/libpg_query/grammar/statements/select.y" { PGNamedArgExpr *na = makeNode(PGNamedArgExpr); na->name = (yyvsp[(1) - (3)].str); @@ -237235,8 +253330,8 @@ YYLTYPE yylloc; ;} break; - case 953: -#line 2916 "third_party/libpg_query/grammar/statements/select.y" + case 965: +#line 2970 "third_party/libpg_query/grammar/statements/select.y" { PGNamedArgExpr *na = makeNode(PGNamedArgExpr); na->name = (yyvsp[(1) - (3)].str); @@ -237247,131 +253342,131 @@ YYLTYPE yylloc; ;} break; - case 954: -#line 2926 "third_party/libpg_query/grammar/statements/select.y" + case 966: +#line 2980 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].typnam)); ;} break; - case 955: -#line 2927 "third_party/libpg_query/grammar/statements/select.y" + case 967: +#line 2981 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].typnam)); ;} break; - case 956: -#line 2932 "third_party/libpg_query/grammar/statements/select.y" + case 968: +#line 2986 "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 957: -#line 2935 "third_party/libpg_query/grammar/statements/select.y" + case 969: +#line 2989 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 958: -#line 2942 "third_party/libpg_query/grammar/statements/select.y" + case 970: +#line 2996 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 959: -#line 2943 "third_party/libpg_query/grammar/statements/select.y" + case 971: +#line 2997 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "year"; ;} break; - case 960: -#line 2944 "third_party/libpg_query/grammar/statements/select.y" + case 972: +#line 2998 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "month"; ;} break; - case 961: -#line 2945 "third_party/libpg_query/grammar/statements/select.y" + case 973: +#line 2999 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "day"; ;} break; - case 962: -#line 2946 "third_party/libpg_query/grammar/statements/select.y" + case 974: +#line 3000 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "hour"; ;} break; - case 963: -#line 2947 "third_party/libpg_query/grammar/statements/select.y" + case 975: +#line 3001 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "minute"; ;} break; - case 964: -#line 2948 "third_party/libpg_query/grammar/statements/select.y" + case 976: +#line 3002 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "second"; ;} break; - case 965: -#line 2949 "third_party/libpg_query/grammar/statements/select.y" + case 977: +#line 3003 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "millisecond"; ;} break; - case 966: -#line 2950 "third_party/libpg_query/grammar/statements/select.y" + case 978: +#line 3004 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "microsecond"; ;} break; - case 967: -#line 2951 "third_party/libpg_query/grammar/statements/select.y" + case 979: +#line 3005 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 968: -#line 2962 "third_party/libpg_query/grammar/statements/select.y" + case 980: +#line 3016 "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 969: -#line 2966 "third_party/libpg_query/grammar/statements/select.y" + case 981: +#line 3020 "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 970: -#line 2973 "third_party/libpg_query/grammar/statements/select.y" + case 982: +#line 3027 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 971: -#line 2979 "third_party/libpg_query/grammar/statements/select.y" + case 983: +#line 3033 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2((yyvsp[(3) - (3)].node), (yyvsp[(1) - (3)].node)); ;} break; - case 972: -#line 2980 "third_party/libpg_query/grammar/statements/select.y" + case 984: +#line 3034 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 973: -#line 2997 "third_party/libpg_query/grammar/statements/select.y" + case 985: +#line 3051 "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 974: -#line 3001 "third_party/libpg_query/grammar/statements/select.y" + case 986: +#line 3055 "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 975: -#line 3006 "third_party/libpg_query/grammar/statements/select.y" + case 987: +#line 3060 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node)); ;} break; - case 976: -#line 3010 "third_party/libpg_query/grammar/statements/select.y" + case 988: +#line 3064 "third_party/libpg_query/grammar/statements/select.y" { /* * Since there are no cases where this syntax allows @@ -237388,45 +253483,45 @@ YYLTYPE yylloc; ;} break; - case 977: -#line 3025 "third_party/libpg_query/grammar/statements/select.y" + case 989: +#line 3079 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 978: -#line 3029 "third_party/libpg_query/grammar/statements/select.y" + case 990: +#line 3083 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 979: -#line 3033 "third_party/libpg_query/grammar/statements/select.y" + case 991: +#line 3087 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 980: -#line 3036 "third_party/libpg_query/grammar/statements/select.y" + case 992: +#line 3090 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 981: -#line 3039 "third_party/libpg_query/grammar/statements/select.y" + case 993: +#line 3093 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(3) - (3)].list), (yyvsp[(1) - (3)].node)); ;} break; - case 982: -#line 3040 "third_party/libpg_query/grammar/statements/select.y" + case 994: +#line 3094 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(2) - (2)].list); ;} break; - case 983: -#line 3041 "third_party/libpg_query/grammar/statements/select.y" + case 995: +#line 3095 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 984: -#line 3045 "third_party/libpg_query/grammar/statements/select.y" + case 996: +#line 3099 "third_party/libpg_query/grammar/statements/select.y" { PGSubLink *n = makeNode(PGSubLink); n->subselect = (yyvsp[(1) - (1)].node); @@ -237435,13 +253530,13 @@ YYLTYPE yylloc; ;} break; - case 985: -#line 3051 "third_party/libpg_query/grammar/statements/select.y" + case 997: +#line 3105 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *)(yyvsp[(2) - (3)].list); ;} break; - case 986: -#line 3062 "third_party/libpg_query/grammar/statements/select.y" + case 998: +#line 3116 "third_party/libpg_query/grammar/statements/select.y" { PGCaseExpr *c = makeNode(PGCaseExpr); c->casetype = InvalidOid; /* not analyzed yet */ @@ -237453,18 +253548,18 @@ YYLTYPE yylloc; ;} break; - case 987: -#line 3075 "third_party/libpg_query/grammar/statements/select.y" + case 999: +#line 3129 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 988: -#line 3076 "third_party/libpg_query/grammar/statements/select.y" + case 1000: +#line 3130 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node)); ;} break; - case 989: -#line 3081 "third_party/libpg_query/grammar/statements/select.y" + case 1001: +#line 3135 "third_party/libpg_query/grammar/statements/select.y" { PGCaseWhen *w = makeNode(PGCaseWhen); w->expr = (PGExpr *) (yyvsp[(2) - (4)].node); @@ -237474,49 +253569,49 @@ YYLTYPE yylloc; ;} break; - case 990: -#line 3091 "third_party/libpg_query/grammar/statements/select.y" + case 1002: +#line 3145 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 991: -#line 3092 "third_party/libpg_query/grammar/statements/select.y" + case 1003: +#line 3146 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 992: -#line 3095 "third_party/libpg_query/grammar/statements/select.y" + case 1004: +#line 3149 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 993: -#line 3096 "third_party/libpg_query/grammar/statements/select.y" + case 1005: +#line 3150 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 994: -#line 3100 "third_party/libpg_query/grammar/statements/select.y" + case 1006: +#line 3154 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeColumnRef((yyvsp[(1) - (1)].str), NIL, (yylsp[(1) - (1)]), yyscanner); ;} break; - case 995: -#line 3104 "third_party/libpg_query/grammar/statements/select.y" + case 1007: +#line 3158 "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 996: -#line 3111 "third_party/libpg_query/grammar/statements/select.y" + case 1008: +#line 3165 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeString((yyvsp[(2) - (2)].str)); ;} break; - case 997: -#line 3115 "third_party/libpg_query/grammar/statements/select.y" + case 1009: +#line 3169 "third_party/libpg_query/grammar/statements/select.y" { PGAIndices *ai = makeNode(PGAIndices); ai->is_slice = false; @@ -237526,8 +253621,8 @@ YYLTYPE yylloc; ;} break; - case 998: -#line 3123 "third_party/libpg_query/grammar/statements/select.y" + case 1010: +#line 3177 "third_party/libpg_query/grammar/statements/select.y" { PGAIndices *ai = makeNode(PGAIndices); ai->is_slice = true; @@ -237537,58 +253632,58 @@ YYLTYPE yylloc; ;} break; - case 999: -#line 3133 "third_party/libpg_query/grammar/statements/select.y" + case 1011: +#line 3187 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 1000: -#line 3134 "third_party/libpg_query/grammar/statements/select.y" + case 1012: +#line 3188 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 1001: -#line 3138 "third_party/libpg_query/grammar/statements/select.y" + case 1013: +#line 3192 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 1002: -#line 3139 "third_party/libpg_query/grammar/statements/select.y" + case 1014: +#line 3193 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node)); ;} break; - case 1003: -#line 3143 "third_party/libpg_query/grammar/statements/select.y" + case 1015: +#line 3197 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 1004: -#line 3144 "third_party/libpg_query/grammar/statements/select.y" + case 1016: +#line 3198 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node)); ;} break; - case 1007: -#line 3158 "third_party/libpg_query/grammar/statements/select.y" + case 1019: +#line 3212 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 1008: -#line 3159 "third_party/libpg_query/grammar/statements/select.y" + case 1020: +#line 3213 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 1009: -#line 3163 "third_party/libpg_query/grammar/statements/select.y" + case 1021: +#line 3217 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].target)); ;} break; - case 1010: -#line 3164 "third_party/libpg_query/grammar/statements/select.y" + case 1022: +#line 3218 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].target)); ;} break; - case 1011: -#line 3168 "third_party/libpg_query/grammar/statements/select.y" + case 1023: +#line 3222 "third_party/libpg_query/grammar/statements/select.y" { (yyval.target) = makeNode(PGResTarget); (yyval.target)->name = (yyvsp[(3) - (3)].str); @@ -237598,8 +253693,8 @@ YYLTYPE yylloc; ;} break; - case 1012: -#line 3184 "third_party/libpg_query/grammar/statements/select.y" + case 1024: +#line 3238 "third_party/libpg_query/grammar/statements/select.y" { (yyval.target) = makeNode(PGResTarget); (yyval.target)->name = (yyvsp[(2) - (2)].str); @@ -237609,8 +253704,8 @@ YYLTYPE yylloc; ;} break; - case 1013: -#line 3192 "third_party/libpg_query/grammar/statements/select.y" + case 1025: +#line 3246 "third_party/libpg_query/grammar/statements/select.y" { (yyval.target) = makeNode(PGResTarget); (yyval.target)->name = NULL; @@ -237620,8 +253715,8 @@ YYLTYPE yylloc; ;} break; - case 1014: -#line 3200 "third_party/libpg_query/grammar/statements/select.y" + case 1026: +#line 3254 "third_party/libpg_query/grammar/statements/select.y" { PGColumnRef *n = makeNode(PGColumnRef); PGAStar *star = makeNode(PGAStar); @@ -237638,8 +253733,8 @@ YYLTYPE yylloc; ;} break; - case 1015: -#line 3215 "third_party/libpg_query/grammar/statements/select.y" + case 1027: +#line 3269 "third_party/libpg_query/grammar/statements/select.y" { PGColumnRef *n = makeNode(PGColumnRef); PGAStar *star = makeNode(PGAStar); @@ -237657,75 +253752,75 @@ YYLTYPE yylloc; ;} break; - case 1016: -#line 3232 "third_party/libpg_query/grammar/statements/select.y" + case 1028: +#line 3286 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (4)].list); ;} break; - case 1017: -#line 3233 "third_party/libpg_query/grammar/statements/select.y" + case 1029: +#line 3287 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(2) - (2)].str))); ;} break; - case 1018: -#line 3236 "third_party/libpg_query/grammar/statements/select.y" + case 1030: +#line 3290 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 1019: -#line 3237 "third_party/libpg_query/grammar/statements/select.y" + case 1031: +#line 3291 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NULL; ;} break; - case 1020: -#line 3240 "third_party/libpg_query/grammar/statements/select.y" + case 1032: +#line 3294 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2((yyvsp[(1) - (3)].node), makeString((yyvsp[(3) - (3)].str))); ;} break; - case 1021: -#line 3244 "third_party/libpg_query/grammar/statements/select.y" + case 1033: +#line 3298 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].list)); ;} break; - case 1022: -#line 3245 "third_party/libpg_query/grammar/statements/select.y" + case 1034: +#line 3299 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); ;} break; - case 1023: -#line 3248 "third_party/libpg_query/grammar/statements/select.y" + case 1035: +#line 3302 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (4)].list); ;} break; - case 1024: -#line 3249 "third_party/libpg_query/grammar/statements/select.y" + case 1036: +#line 3303 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(2) - (2)].list)); ;} break; - case 1025: -#line 3250 "third_party/libpg_query/grammar/statements/select.y" + case 1037: +#line 3304 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NULL; ;} break; - case 1026: -#line 3260 "third_party/libpg_query/grammar/statements/select.y" + case 1038: +#line 3314 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].range)); ;} break; - case 1027: -#line 3261 "third_party/libpg_query/grammar/statements/select.y" + case 1039: +#line 3315 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].range)); ;} break; - case 1028: -#line 3273 "third_party/libpg_query/grammar/statements/select.y" + case 1040: +#line 3327 "third_party/libpg_query/grammar/statements/select.y" { (yyval.range) = makeRangeVar(NULL, (yyvsp[(1) - (1)].str), (yylsp[(1) - (1)])); ;} break; - case 1029: -#line 3277 "third_party/libpg_query/grammar/statements/select.y" + case 1041: +#line 3331 "third_party/libpg_query/grammar/statements/select.y" { check_qualified_name((yyvsp[(2) - (2)].list), yyscanner); (yyval.range) = makeRangeVar(NULL, NULL, (yylsp[(1) - (2)])); @@ -237752,55 +253847,55 @@ YYLTYPE yylloc; ;} break; - case 1030: -#line 3304 "third_party/libpg_query/grammar/statements/select.y" + case 1042: +#line 3358 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;} break; - case 1031: -#line 3306 "third_party/libpg_query/grammar/statements/select.y" + case 1043: +#line 3360 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), makeString((yyvsp[(3) - (3)].str))); ;} break; - case 1032: -#line 3310 "third_party/libpg_query/grammar/statements/select.y" + case 1044: +#line 3364 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1033: -#line 3312 "third_party/libpg_query/grammar/statements/select.y" + case 1045: +#line 3366 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1034: -#line 3323 "third_party/libpg_query/grammar/statements/select.y" + case 1046: +#line 3377 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;} break; - case 1035: -#line 3326 "third_party/libpg_query/grammar/statements/select.y" + case 1047: +#line 3380 "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 1036: -#line 3337 "third_party/libpg_query/grammar/statements/select.y" + case 1048: +#line 3391 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeIntConst((yyvsp[(1) - (1)].ival), (yylsp[(1) - (1)])); ;} break; - case 1037: -#line 3341 "third_party/libpg_query/grammar/statements/select.y" + case 1049: +#line 3395 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeFloatConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)])); ;} break; - case 1038: -#line 3345 "third_party/libpg_query/grammar/statements/select.y" + case 1050: +#line 3399 "third_party/libpg_query/grammar/statements/select.y" { if ((yyvsp[(2) - (2)].list)) { @@ -237814,15 +253909,15 @@ YYLTYPE yylloc; ;} break; - case 1039: -#line 3357 "third_party/libpg_query/grammar/statements/select.y" + case 1051: +#line 3411 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeBitStringConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)])); ;} break; - case 1040: -#line 3361 "third_party/libpg_query/grammar/statements/select.y" + case 1052: +#line 3415 "third_party/libpg_query/grammar/statements/select.y" { /* This is a bit constant per SQL99: * Without Feature F511, "BIT data type", @@ -237833,8 +253928,8 @@ YYLTYPE yylloc; ;} break; - case 1041: -#line 3370 "third_party/libpg_query/grammar/statements/select.y" + case 1053: +#line 3424 "third_party/libpg_query/grammar/statements/select.y" { /* generic type 'literal' syntax */ PGTypeName *t = makeTypeNameFromNameList((yyvsp[(1) - (2)].list)); @@ -237843,20 +253938,20 @@ YYLTYPE yylloc; ;} break; - case 1042: -#line 3377 "third_party/libpg_query/grammar/statements/select.y" + case 1054: +#line 3431 "third_party/libpg_query/grammar/statements/select.y" { /* generic syntax with a type modifier */ - PGTypeName *t = makeTypeNameFromNameList((yyvsp[(1) - (6)].list)); + PGTypeName *t = makeTypeNameFromNameList((yyvsp[(1) - (7)].list)); PGListCell *lc; /* * We must use func_arg_list and opt_sort_clause in the * production to avoid reduce/reduce conflicts, but we * don't actually wish to allow PGNamedArgExpr in this - * context, nor ORDER BY. + * context, ORDER BY, nor IGNORE NULLS. */ - foreach(lc, (yyvsp[(3) - (6)].list)) + foreach(lc, (yyvsp[(3) - (7)].list)) { PGNamedArgExpr *arg = (PGNamedArgExpr *) lfirst(lc); @@ -237866,208 +253961,214 @@ YYLTYPE yylloc; errmsg("type modifier cannot have parameter name"), parser_errposition(arg->location))); } - if ((yyvsp[(4) - (6)].list) != NIL) + if ((yyvsp[(4) - (7)].list) != NIL) ereport(ERROR, (errcode(PG_ERRCODE_SYNTAX_ERROR), errmsg("type modifier cannot have ORDER BY"), - parser_errposition((yylsp[(4) - (6)])))); + parser_errposition((yylsp[(4) - (7)])))); + if ((yyvsp[(5) - (7)].boolean) != false) + ereport(ERROR, + (errcode(PG_ERRCODE_SYNTAX_ERROR), + errmsg("type modifier cannot have IGNORE NULLS"), + parser_errposition((yylsp[(5) - (7)])))); + - t->typmods = (yyvsp[(3) - (6)].list); - t->location = (yylsp[(1) - (6)]); - (yyval.node) = makeStringConstCast((yyvsp[(6) - (6)].str), (yylsp[(6) - (6)]), t); + t->typmods = (yyvsp[(3) - (7)].list); + t->location = (yylsp[(1) - (7)]); + (yyval.node) = makeStringConstCast((yyvsp[(7) - (7)].str), (yylsp[(7) - (7)]), t); ;} break; - case 1043: -#line 3409 "third_party/libpg_query/grammar/statements/select.y" + case 1055: +#line 3469 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeStringConstCast((yyvsp[(2) - (2)].str), (yylsp[(2) - (2)]), (yyvsp[(1) - (2)].typnam)); ;} break; - case 1044: -#line 3413 "third_party/libpg_query/grammar/statements/select.y" + case 1056: +#line 3473 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeIntervalNode((yyvsp[(3) - (5)].node), (yylsp[(3) - (5)]), (yyvsp[(5) - (5)].list)); ;} break; - case 1045: -#line 3417 "third_party/libpg_query/grammar/statements/select.y" + case 1057: +#line 3477 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeIntervalNode((yyvsp[(2) - (3)].ival), (yylsp[(2) - (3)]), (yyvsp[(3) - (3)].list)); ;} break; - case 1046: -#line 3421 "third_party/libpg_query/grammar/statements/select.y" + case 1058: +#line 3481 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeIntervalNode((yyvsp[(2) - (3)].str), (yylsp[(2) - (3)]), (yyvsp[(3) - (3)].list)); ;} break; - case 1047: -#line 3425 "third_party/libpg_query/grammar/statements/select.y" + case 1059: +#line 3485 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeBoolAConst(true, (yylsp[(1) - (1)])); ;} break; - case 1048: -#line 3429 "third_party/libpg_query/grammar/statements/select.y" + case 1060: +#line 3489 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeBoolAConst(false, (yylsp[(1) - (1)])); ;} break; - case 1049: -#line 3433 "third_party/libpg_query/grammar/statements/select.y" + case 1061: +#line 3493 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeNullAConst((yylsp[(1) - (1)])); ;} break; - case 1050: -#line 3438 "third_party/libpg_query/grammar/statements/select.y" + case 1062: +#line 3498 "third_party/libpg_query/grammar/statements/select.y" { (yyval.ival) = (yyvsp[(1) - (1)].ival); ;} break; - case 1051: -#line 3439 "third_party/libpg_query/grammar/statements/select.y" + case 1063: +#line 3499 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1052: -#line 3455 "third_party/libpg_query/grammar/statements/select.y" + case 1064: +#line 3515 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1053: -#line 3456 "third_party/libpg_query/grammar/statements/select.y" + case 1065: +#line 3516 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1054: -#line 3457 "third_party/libpg_query/grammar/statements/select.y" + case 1066: +#line 3517 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1055: -#line 3460 "third_party/libpg_query/grammar/statements/select.y" + case 1067: +#line 3520 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1056: -#line 3461 "third_party/libpg_query/grammar/statements/select.y" + case 1068: +#line 3521 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1057: -#line 3467 "third_party/libpg_query/grammar/statements/select.y" + case 1069: +#line 3527 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1058: -#line 3468 "third_party/libpg_query/grammar/statements/select.y" + case 1070: +#line 3528 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1059: -#line 3469 "third_party/libpg_query/grammar/statements/select.y" + case 1071: +#line 3529 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1060: -#line 3472 "third_party/libpg_query/grammar/statements/select.y" + case 1072: +#line 3532 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1061: -#line 3473 "third_party/libpg_query/grammar/statements/select.y" + case 1073: +#line 3533 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1062: -#line 3474 "third_party/libpg_query/grammar/statements/select.y" + case 1074: +#line 3534 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1063: -#line 3477 "third_party/libpg_query/grammar/statements/select.y" + case 1075: +#line 3537 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1064: -#line 3478 "third_party/libpg_query/grammar/statements/select.y" + case 1076: +#line 3538 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1065: -#line 3479 "third_party/libpg_query/grammar/statements/select.y" + case 1077: +#line 3539 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1066: -#line 3482 "third_party/libpg_query/grammar/statements/select.y" + case 1078: +#line 3542 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;} break; - case 1067: -#line 3483 "third_party/libpg_query/grammar/statements/select.y" + case 1079: +#line 3543 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lcons(makeString((yyvsp[(1) - (2)].str)), (yyvsp[(2) - (2)].list)); ;} break; - case 1068: -#line 3487 "third_party/libpg_query/grammar/statements/select.y" + case 1080: +#line 3547 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(2) - (2)].str))); ;} break; - case 1069: -#line 3489 "third_party/libpg_query/grammar/statements/select.y" + case 1081: +#line 3549 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), makeString((yyvsp[(3) - (3)].str))); ;} break; - case 1070: -#line 3493 "third_party/libpg_query/grammar/statements/select.y" + case 1082: +#line 3553 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(2) - (3)].list); ;} break; - case 1071: -#line 3494 "third_party/libpg_query/grammar/statements/select.y" + case 1083: +#line 3554 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 1073: -#line 3505 "third_party/libpg_query/grammar/statements/select.y" + case 1085: +#line 3565 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1074: -#line 3506 "third_party/libpg_query/grammar/statements/select.y" + case 1086: +#line 3566 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1075: -#line 3507 "third_party/libpg_query/grammar/statements/select.y" + case 1087: +#line 3567 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1076: -#line 3508 "third_party/libpg_query/grammar/statements/select.y" + case 1088: +#line 3568 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1077: -#line 3511 "third_party/libpg_query/grammar/statements/select.y" + case 1089: +#line 3571 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1078: -#line 3512 "third_party/libpg_query/grammar/statements/select.y" + case 1090: +#line 3572 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1079: + case 1091: #line 8 "third_party/libpg_query/grammar/statements/prepare.y" { PGPrepareStmt *n = makeNode(PGPrepareStmt); @@ -238078,17 +254179,17 @@ YYLTYPE yylloc; ;} break; - case 1080: + case 1092: #line 18 "third_party/libpg_query/grammar/statements/prepare.y" { (yyval.list) = (yyvsp[(2) - (3)].list); ;} break; - case 1081: + case 1093: #line 19 "third_party/libpg_query/grammar/statements/prepare.y" { (yyval.list) = NIL; ;} break; - case 1086: + case 1098: #line 8 "third_party/libpg_query/grammar/statements/create_schema.y" { PGCreateSchemaStmt *n = makeNode(PGCreateSchemaStmt); @@ -238100,7 +254201,7 @@ YYLTYPE yylloc; ;} break; - case 1087: + case 1099: #line 17 "third_party/libpg_query/grammar/statements/create_schema.y" { PGCreateSchemaStmt *n = makeNode(PGCreateSchemaStmt); @@ -238117,7 +254218,7 @@ YYLTYPE yylloc; ;} break; - case 1088: + case 1100: #line 35 "third_party/libpg_query/grammar/statements/create_schema.y" { if ((yyloc) < 0) /* see comments for YYLLOC_DEFAULT */ @@ -238126,12 +254227,12 @@ YYLTYPE yylloc; ;} break; - case 1089: + case 1101: #line 41 "third_party/libpg_query/grammar/statements/create_schema.y" { (yyval.list) = NIL; ;} break; - case 1094: + case 1106: #line 11 "third_party/libpg_query/grammar/statements/index.y" { PGIndexStmt *n = makeNode(PGIndexStmt); @@ -238157,7 +254258,7 @@ YYLTYPE yylloc; ;} break; - case 1095: + case 1107: #line 36 "third_party/libpg_query/grammar/statements/index.y" { PGIndexStmt *n = makeNode(PGIndexStmt); @@ -238183,62 +254284,62 @@ YYLTYPE yylloc; ;} break; - case 1096: + case 1108: #line 62 "third_party/libpg_query/grammar/statements/index.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1097: + case 1109: #line 66 "third_party/libpg_query/grammar/statements/index.y" { (yyval.str) = (yyvsp[(2) - (2)].str); ;} break; - case 1098: + case 1110: #line 67 "third_party/libpg_query/grammar/statements/index.y" { (yyval.str) = (char*) DEFAULT_INDEX_TYPE; ;} break; - case 1099: + case 1111: #line 72 "third_party/libpg_query/grammar/statements/index.y" { (yyval.boolean) = true; ;} break; - case 1100: + case 1112: #line 73 "third_party/libpg_query/grammar/statements/index.y" { (yyval.boolean) = false; ;} break; - case 1101: + case 1113: #line 78 "third_party/libpg_query/grammar/statements/index.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1102: + case 1114: #line 79 "third_party/libpg_query/grammar/statements/index.y" { (yyval.str) = NULL; ;} break; - case 1103: + case 1115: #line 83 "third_party/libpg_query/grammar/statements/index.y" { (yyval.list) = (yyvsp[(2) - (2)].list); ;} break; - case 1104: + case 1116: #line 84 "third_party/libpg_query/grammar/statements/index.y" { (yyval.list) = NIL; ;} break; - case 1105: + case 1117: #line 89 "third_party/libpg_query/grammar/statements/index.y" { (yyval.boolean) = true; ;} break; - case 1106: + case 1118: #line 90 "third_party/libpg_query/grammar/statements/index.y" { (yyval.boolean) = false; ;} break; - case 1107: + case 1119: #line 8 "third_party/libpg_query/grammar/statements/alter_schema.y" { PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt); @@ -238250,7 +254351,7 @@ YYLTYPE yylloc; ;} break; - case 1108: + case 1120: #line 17 "third_party/libpg_query/grammar/statements/alter_schema.y" { PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt); @@ -238262,7 +254363,7 @@ YYLTYPE yylloc; ;} break; - case 1109: + case 1121: #line 26 "third_party/libpg_query/grammar/statements/alter_schema.y" { PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt); @@ -238274,7 +254375,7 @@ YYLTYPE yylloc; ;} break; - case 1110: + case 1122: #line 35 "third_party/libpg_query/grammar/statements/alter_schema.y" { PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt); @@ -238286,7 +254387,7 @@ YYLTYPE yylloc; ;} break; - case 1111: + case 1123: #line 44 "third_party/libpg_query/grammar/statements/alter_schema.y" { PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt); @@ -238298,7 +254399,7 @@ YYLTYPE yylloc; ;} break; - case 1112: + case 1124: #line 53 "third_party/libpg_query/grammar/statements/alter_schema.y" { PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt); @@ -238310,7 +254411,7 @@ YYLTYPE yylloc; ;} break; - case 1113: + case 1125: #line 6 "third_party/libpg_query/grammar/statements/checkpoint.y" { PGCheckPointStmt *n = makeNode(PGCheckPointStmt); @@ -238319,7 +254420,7 @@ YYLTYPE yylloc; ;} break; - case 1114: + case 1126: #line 12 "third_party/libpg_query/grammar/statements/checkpoint.y" { PGCheckPointStmt *n = makeNode(PGCheckPointStmt); @@ -238328,7 +254429,7 @@ YYLTYPE yylloc; ;} break; - case 1115: + case 1127: #line 8 "third_party/libpg_query/grammar/statements/export.y" { PGExportStmt *n = makeNode(PGExportStmt); @@ -238341,7 +254442,7 @@ YYLTYPE yylloc; ;} break; - case 1116: + case 1128: #line 21 "third_party/libpg_query/grammar/statements/export.y" { PGImportStmt *n = makeNode(PGImportStmt); @@ -238350,7 +254451,7 @@ YYLTYPE yylloc; ;} break; - case 1117: + case 1129: #line 10 "third_party/libpg_query/grammar/statements/explain.y" { PGExplainStmt *n = makeNode(PGExplainStmt); @@ -238360,7 +254461,7 @@ YYLTYPE yylloc; ;} break; - case 1118: + case 1130: #line 17 "third_party/libpg_query/grammar/statements/explain.y" { PGExplainStmt *n = makeNode(PGExplainStmt); @@ -238373,7 +254474,7 @@ YYLTYPE yylloc; ;} break; - case 1119: + case 1131: #line 27 "third_party/libpg_query/grammar/statements/explain.y" { PGExplainStmt *n = makeNode(PGExplainStmt); @@ -238383,7 +254484,7 @@ YYLTYPE yylloc; ;} break; - case 1120: + case 1132: #line 34 "third_party/libpg_query/grammar/statements/explain.y" { PGExplainStmt *n = makeNode(PGExplainStmt); @@ -238393,118 +254494,118 @@ YYLTYPE yylloc; ;} break; - case 1121: + case 1133: #line 44 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.boolean) = true; ;} break; - case 1122: + case 1134: #line 45 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.boolean) = false; ;} break; - case 1123: + case 1135: #line 50 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.node) = (PGNode *) makeString((yyvsp[(1) - (1)].str)); ;} break; - case 1124: + case 1136: #line 51 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.node) = (PGNode *) (yyvsp[(1) - (1)].value); ;} break; - case 1125: + case 1137: #line 52 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.node) = NULL; ;} break; - case 1131: + case 1143: #line 65 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1132: + case 1144: #line 66 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1133: + case 1145: #line 67 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1134: + case 1146: #line 72 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1135: + case 1147: #line 73 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1136: + case 1148: #line 79 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].defelt)); ;} break; - case 1137: + case 1149: #line 83 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].defelt)); ;} break; - case 1138: + case 1150: #line 90 "third_party/libpg_query/grammar/statements/explain.y" {;} break; - case 1139: + case 1151: #line 91 "third_party/libpg_query/grammar/statements/explain.y" {;} break; - case 1140: + case 1152: #line 96 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (char*) "true"; ;} break; - case 1141: + case 1153: #line 97 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (char*) "false"; ;} break; - case 1142: + case 1154: #line 98 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (char*) "on"; ;} break; - case 1143: + case 1155: #line 104 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1144: + case 1156: #line 110 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.defelt) = makeDefElem((yyvsp[(1) - (2)].str), (yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;} break; - case 1145: + case 1157: #line 117 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1146: + case 1158: #line 118 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (char*) "analyze"; ;} break; - case 1147: + case 1159: #line 11 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = (yyvsp[(2) - (2)].vsetstmt); @@ -238513,7 +254614,7 @@ YYLTYPE yylloc; ;} break; - case 1148: + case 1160: #line 17 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = (yyvsp[(3) - (3)].vsetstmt); @@ -238522,7 +254623,7 @@ YYLTYPE yylloc; ;} break; - case 1149: + case 1161: #line 23 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = (yyvsp[(3) - (3)].vsetstmt); @@ -238531,7 +254632,7 @@ YYLTYPE yylloc; ;} break; - case 1150: + case 1162: #line 29 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = (yyvsp[(3) - (3)].vsetstmt); @@ -238540,12 +254641,12 @@ YYLTYPE yylloc; ;} break; - case 1151: + case 1163: #line 38 "third_party/libpg_query/grammar/statements/variable_set.y" {(yyval.vsetstmt) = (yyvsp[(1) - (1)].vsetstmt);;} break; - case 1152: + case 1164: #line 40 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -238555,7 +254656,7 @@ YYLTYPE yylloc; ;} break; - case 1153: + case 1165: #line 48 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -238569,7 +254670,7 @@ YYLTYPE yylloc; ;} break; - case 1154: + case 1166: #line 59 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -238580,7 +254681,7 @@ YYLTYPE yylloc; ;} break; - case 1155: + case 1167: #line 71 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -238591,7 +254692,7 @@ YYLTYPE yylloc; ;} break; - case 1156: + case 1168: #line 79 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -238602,7 +254703,7 @@ YYLTYPE yylloc; ;} break; - case 1157: + case 1169: #line 87 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -238612,7 +254713,7 @@ YYLTYPE yylloc; ;} break; - case 1158: + case 1170: #line 94 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -238622,31 +254723,31 @@ YYLTYPE yylloc; ;} break; - case 1159: + case 1171: #line 104 "third_party/libpg_query/grammar/statements/variable_set.y" { (yyval.node) = makeStringConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)])); ;} break; - case 1160: + case 1172: #line 106 "third_party/libpg_query/grammar/statements/variable_set.y" { (yyval.node) = makeAConst((yyvsp[(1) - (1)].value), (yylsp[(1) - (1)])); ;} break; - case 1161: + case 1173: #line 112 "third_party/libpg_query/grammar/statements/variable_set.y" { (yyval.node) = makeStringConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)])); ;} break; - case 1162: + case 1174: #line 116 "third_party/libpg_query/grammar/statements/variable_set.y" { (yyval.node) = makeStringConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)])); ;} break; - case 1163: + case 1175: #line 120 "third_party/libpg_query/grammar/statements/variable_set.y" { PGTypeName *t = (yyvsp[(1) - (3)].typnam); @@ -238664,7 +254765,7 @@ YYLTYPE yylloc; ;} break; - case 1164: + case 1176: #line 135 "third_party/libpg_query/grammar/statements/variable_set.y" { PGTypeName *t = (yyvsp[(1) - (5)].typnam); @@ -238674,46 +254775,72 @@ YYLTYPE yylloc; ;} break; - case 1165: + case 1177: #line 141 "third_party/libpg_query/grammar/statements/variable_set.y" { (yyval.node) = makeAConst((yyvsp[(1) - (1)].value), (yylsp[(1) - (1)])); ;} break; - case 1166: + case 1178: #line 142 "third_party/libpg_query/grammar/statements/variable_set.y" { (yyval.node) = NULL; ;} break; - case 1167: + case 1179: #line 143 "third_party/libpg_query/grammar/statements/variable_set.y" { (yyval.node) = NULL; ;} break; - case 1168: + case 1180: #line 147 "third_party/libpg_query/grammar/statements/variable_set.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 1169: + case 1181: #line 148 "third_party/libpg_query/grammar/statements/variable_set.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;} break; - case 1170: + case 1182: #line 8 "third_party/libpg_query/grammar/statements/load.y" { PGLoadStmt *n = makeNode(PGLoadStmt); n->filename = (yyvsp[(2) - (2)].str); + n->load_type = PG_LOAD_TYPE_LOAD; (yyval.node) = (PGNode *)n; ;} break; - case 1171: -#line 16 "third_party/libpg_query/grammar/statements/load.y" + case 1183: +#line 14 "third_party/libpg_query/grammar/statements/load.y" + { + PGLoadStmt *n = makeNode(PGLoadStmt); + n->filename = (yyvsp[(2) - (2)].str); + n->load_type = PG_LOAD_TYPE_INSTALL; + (yyval.node) = (PGNode *)n; + ;} + break; + + case 1184: +#line 20 "third_party/libpg_query/grammar/statements/load.y" + { + PGLoadStmt *n = makeNode(PGLoadStmt); + n->filename = (yyvsp[(3) - (3)].str); + n->load_type = PG_LOAD_TYPE_FORCE_INSTALL; + (yyval.node) = (PGNode *)n; + ;} + break; + + case 1185: +#line 28 "third_party/libpg_query/grammar/statements/load.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1172: + case 1186: +#line 29 "third_party/libpg_query/grammar/statements/load.y" + { (yyval.str) = (yyvsp[(1) - (1)].str); ;} + break; + + case 1187: #line 9 "third_party/libpg_query/grammar/statements/vacuum.y" { PGVacuumStmt *n = makeNode(PGVacuumStmt); @@ -238730,7 +254857,7 @@ YYLTYPE yylloc; ;} break; - case 1173: + case 1188: #line 23 "third_party/libpg_query/grammar/statements/vacuum.y" { PGVacuumStmt *n = makeNode(PGVacuumStmt); @@ -238747,7 +254874,7 @@ YYLTYPE yylloc; ;} break; - case 1174: + case 1189: #line 37 "third_party/libpg_query/grammar/statements/vacuum.y" { PGVacuumStmt *n = (PGVacuumStmt *) (yyvsp[(5) - (5)].node); @@ -238762,7 +254889,7 @@ YYLTYPE yylloc; ;} break; - case 1175: + case 1190: #line 49 "third_party/libpg_query/grammar/statements/vacuum.y" { PGVacuumStmt *n = makeNode(PGVacuumStmt); @@ -238773,7 +254900,7 @@ YYLTYPE yylloc; ;} break; - case 1176: + case 1191: #line 57 "third_party/libpg_query/grammar/statements/vacuum.y" { PGVacuumStmt *n = makeNode(PGVacuumStmt); @@ -238786,27 +254913,27 @@ YYLTYPE yylloc; ;} break; - case 1177: + case 1192: #line 70 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.ival) = PG_VACOPT_ANALYZE; ;} break; - case 1178: + case 1193: #line 71 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.ival) = PG_VACOPT_VERBOSE; ;} break; - case 1179: + case 1194: #line 72 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.ival) = PG_VACOPT_FREEZE; ;} break; - case 1180: + case 1195: #line 73 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.ival) = PG_VACOPT_FULL; ;} break; - case 1181: + case 1196: #line 75 "third_party/libpg_query/grammar/statements/vacuum.y" { if (strcmp((yyvsp[(1) - (1)].str), "disable_page_skipping") == 0) @@ -238819,37 +254946,37 @@ YYLTYPE yylloc; ;} break; - case 1182: + case 1197: #line 87 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.boolean) = true; ;} break; - case 1183: + case 1198: #line 88 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.boolean) = false; ;} break; - case 1184: + case 1199: #line 93 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.ival) = (yyvsp[(1) - (1)].ival); ;} break; - case 1185: + case 1200: #line 94 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.ival) = (yyvsp[(1) - (3)].ival) | (yyvsp[(3) - (3)].ival); ;} break; - case 1186: + case 1201: #line 98 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.boolean) = true; ;} break; - case 1187: + case 1202: #line 99 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.boolean) = false; ;} break; - case 1188: + case 1203: #line 9 "third_party/libpg_query/grammar/statements/delete.y" { PGDeleteStmt *n = makeNode(PGDeleteStmt); @@ -238862,14 +254989,14 @@ YYLTYPE yylloc; ;} break; - case 1189: + case 1204: #line 22 "third_party/libpg_query/grammar/statements/delete.y" { (yyval.range) = (yyvsp[(1) - (1)].range); ;} break; - case 1190: + case 1205: #line 26 "third_party/libpg_query/grammar/statements/delete.y" { PGAlias *alias = makeNode(PGAlias); @@ -238879,7 +255006,7 @@ YYLTYPE yylloc; ;} break; - case 1191: + case 1206: #line 33 "third_party/libpg_query/grammar/statements/delete.y" { PGAlias *alias = makeNode(PGAlias); @@ -238889,27 +255016,27 @@ YYLTYPE yylloc; ;} break; - case 1192: + case 1207: #line 43 "third_party/libpg_query/grammar/statements/delete.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 1193: + case 1208: #line 44 "third_party/libpg_query/grammar/statements/delete.y" { (yyval.node) = NULL; ;} break; - case 1194: + case 1209: #line 50 "third_party/libpg_query/grammar/statements/delete.y" { (yyval.list) = (yyvsp[(2) - (2)].list); ;} break; - case 1195: + case 1210: #line 51 "third_party/libpg_query/grammar/statements/delete.y" { (yyval.list) = NIL; ;} break; - case 1196: + case 1211: #line 10 "third_party/libpg_query/grammar/statements/analyze.y" { PGVacuumStmt *n = makeNode(PGVacuumStmt); @@ -238922,7 +255049,7 @@ YYLTYPE yylloc; ;} break; - case 1197: + case 1212: #line 20 "third_party/libpg_query/grammar/statements/analyze.y" { PGVacuumStmt *n = makeNode(PGVacuumStmt); @@ -238935,12 +255062,12 @@ YYLTYPE yylloc; ;} break; - case 1198: + case 1213: #line 2 "third_party/libpg_query/grammar/statements/variable_reset.y" { (yyval.node) = (PGNode *) (yyvsp[(2) - (2)].vsetstmt); ;} break; - case 1199: + case 1214: #line 8 "third_party/libpg_query/grammar/statements/variable_reset.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -238950,7 +255077,7 @@ YYLTYPE yylloc; ;} break; - case 1200: + case 1215: #line 15 "third_party/libpg_query/grammar/statements/variable_reset.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -238959,12 +255086,12 @@ YYLTYPE yylloc; ;} break; - case 1201: + case 1216: #line 24 "third_party/libpg_query/grammar/statements/variable_reset.y" { (yyval.vsetstmt) = (yyvsp[(1) - (1)].vsetstmt); ;} break; - case 1202: + case 1217: #line 26 "third_party/libpg_query/grammar/statements/variable_reset.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -238974,7 +255101,7 @@ YYLTYPE yylloc; ;} break; - case 1203: + case 1218: #line 33 "third_party/libpg_query/grammar/statements/variable_reset.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -238984,7 +255111,7 @@ YYLTYPE yylloc; ;} break; - case 1204: + case 1219: #line 3 "third_party/libpg_query/grammar/statements/variable_show.y" { PGVariableShowSelectStmt *n = makeNode(PGVariableShowSelectStmt); @@ -238995,7 +255122,7 @@ YYLTYPE yylloc; ;} break; - case 1205: + case 1220: #line 10 "third_party/libpg_query/grammar/statements/variable_show.y" { PGVariableShowSelectStmt *n = makeNode(PGVariableShowSelectStmt); @@ -239006,7 +255133,7 @@ YYLTYPE yylloc; ;} break; - case 1206: + case 1221: #line 18 "third_party/libpg_query/grammar/statements/variable_show.y" { PGVariableShowStmt *n = makeNode(PGVariableShowStmt); @@ -239016,7 +255143,7 @@ YYLTYPE yylloc; ;} break; - case 1207: + case 1222: #line 25 "third_party/libpg_query/grammar/statements/variable_show.y" { PGVariableShowStmt *n = makeNode(PGVariableShowStmt); @@ -239026,7 +255153,7 @@ YYLTYPE yylloc; ;} break; - case 1208: + case 1223: #line 32 "third_party/libpg_query/grammar/statements/variable_show.y" { PGVariableShowStmt *n = makeNode(PGVariableShowStmt); @@ -239036,7 +255163,7 @@ YYLTYPE yylloc; ;} break; - case 1209: + case 1224: #line 39 "third_party/libpg_query/grammar/statements/variable_show.y" { PGVariableShowStmt *n = makeNode(PGVariableShowStmt); @@ -239046,7 +255173,7 @@ YYLTYPE yylloc; ;} break; - case 1210: + case 1225: #line 46 "third_party/libpg_query/grammar/statements/variable_show.y" { PGVariableShowStmt *n = makeNode(PGVariableShowStmt); @@ -239056,17 +255183,17 @@ YYLTYPE yylloc; ;} break; - case 1213: + case 1228: #line 57 "third_party/libpg_query/grammar/statements/variable_show.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1214: + case 1229: #line 59 "third_party/libpg_query/grammar/statements/variable_show.y" { (yyval.str) = psprintf("%s.%s", (yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].str)); ;} break; - case 1215: + case 1230: #line 7 "third_party/libpg_query/grammar/statements/call.y" { PGCallStmt *n = makeNode(PGCallStmt); @@ -239075,7 +255202,7 @@ YYLTYPE yylloc; ;} break; - case 1216: + case 1231: #line 10 "third_party/libpg_query/grammar/statements/view.y" { PGViewStmt *n = makeNode(PGViewStmt); @@ -239090,7 +255217,7 @@ YYLTYPE yylloc; ;} break; - case 1217: + case 1232: #line 23 "third_party/libpg_query/grammar/statements/view.y" { PGViewStmt *n = makeNode(PGViewStmt); @@ -239105,7 +255232,7 @@ YYLTYPE yylloc; ;} break; - case 1218: + case 1233: #line 36 "third_party/libpg_query/grammar/statements/view.y" { PGViewStmt *n = makeNode(PGViewStmt); @@ -239125,7 +255252,7 @@ YYLTYPE yylloc; ;} break; - case 1219: + case 1234: #line 54 "third_party/libpg_query/grammar/statements/view.y" { PGViewStmt *n = makeNode(PGViewStmt); @@ -239145,27 +255272,27 @@ YYLTYPE yylloc; ;} break; - case 1220: + case 1235: #line 74 "third_party/libpg_query/grammar/statements/view.y" { (yyval.viewcheckoption) = CASCADED_CHECK_OPTION; ;} break; - case 1221: + case 1236: #line 75 "third_party/libpg_query/grammar/statements/view.y" { (yyval.viewcheckoption) = CASCADED_CHECK_OPTION; ;} break; - case 1222: + case 1237: #line 76 "third_party/libpg_query/grammar/statements/view.y" { (yyval.viewcheckoption) = PG_LOCAL_CHECK_OPTION; ;} break; - case 1223: + case 1238: #line 77 "third_party/libpg_query/grammar/statements/view.y" { (yyval.viewcheckoption) = PG_NO_CHECK_OPTION; ;} break; - case 1224: + case 1239: #line 12 "third_party/libpg_query/grammar/statements/create_as.y" { PGCreateTableAsStmt *ctas = makeNode(PGCreateTableAsStmt); @@ -239181,7 +255308,7 @@ YYLTYPE yylloc; ;} break; - case 1225: + case 1240: #line 25 "third_party/libpg_query/grammar/statements/create_as.y" { PGCreateTableAsStmt *ctas = makeNode(PGCreateTableAsStmt); @@ -239197,22 +255324,22 @@ YYLTYPE yylloc; ;} break; - case 1226: + case 1241: #line 41 "third_party/libpg_query/grammar/statements/create_as.y" { (yyval.boolean) = true; ;} break; - case 1227: + case 1242: #line 42 "third_party/libpg_query/grammar/statements/create_as.y" { (yyval.boolean) = false; ;} break; - case 1228: + case 1243: #line 43 "third_party/libpg_query/grammar/statements/create_as.y" { (yyval.boolean) = true; ;} break; - case 1229: + case 1244: #line 49 "third_party/libpg_query/grammar/statements/create_as.y" { (yyval.into) = makeNode(PGIntoClause); @@ -239227,7 +255354,7 @@ YYLTYPE yylloc; /* Line 1267 of yacc.c. */ -#line 24115 "third_party/libpg_query/grammar/grammar_out.cpp" +#line 24860 "third_party/libpg_query/grammar/grammar_out.cpp" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -239631,6 +255758,18 @@ makeSampleOptions(PGNode *sample_size, char *method, int seed, int location) { return (PGNode *)n; } +/* makeLimitPercent() + * Make limit percent node + */ +static PGNode * +makeLimitPercent(PGNode *limit_percent) { + PGLimitPercent *n = makeNode(PGLimitPercent); + + n->limit_percent = limit_percent; + + return (PGNode *)n; +} + static PGNode * makeIntConst(int val, int location) { @@ -240187,11 +256326,12 @@ parser_init(base_yy_extra_type *yyext) } // namespace duckdb_libpgquery + // LICENSE_CHANGE_END // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /*-------------------------------------------------------------------- @@ -240230,7 +256370,7 @@ parser_init(base_yy_extra_type *yyext) // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list @@ -240407,6 +256547,7 @@ PG_KEYWORD("hour", HOUR_P, UNRESERVED_KEYWORD) PG_KEYWORD("hours", HOURS_P, UNRESERVED_KEYWORD) PG_KEYWORD("identity", IDENTITY_P, UNRESERVED_KEYWORD) PG_KEYWORD("if", IF_P, UNRESERVED_KEYWORD) +PG_KEYWORD("ignore", IGNORE_P, UNRESERVED_KEYWORD) PG_KEYWORD("ilike", ILIKE, TYPE_FUNC_NAME_KEYWORD) PG_KEYWORD("immediate", IMMEDIATE, UNRESERVED_KEYWORD) PG_KEYWORD("immutable", IMMUTABLE, UNRESERVED_KEYWORD) @@ -240426,6 +256567,7 @@ PG_KEYWORD("inout", INOUT, COL_NAME_KEYWORD) PG_KEYWORD("input", INPUT_P, UNRESERVED_KEYWORD) PG_KEYWORD("insensitive", INSENSITIVE, UNRESERVED_KEYWORD) PG_KEYWORD("insert", INSERT, UNRESERVED_KEYWORD) +PG_KEYWORD("install", INSTALL, UNRESERVED_KEYWORD) PG_KEYWORD("instead", INSTEAD, UNRESERVED_KEYWORD) PG_KEYWORD("int", INT_P, COL_NAME_KEYWORD) PG_KEYWORD("integer", INTEGER, COL_NAME_KEYWORD) @@ -240540,6 +256682,7 @@ PG_KEYWORD("procedural", PROCEDURAL, UNRESERVED_KEYWORD) PG_KEYWORD("procedure", PROCEDURE, UNRESERVED_KEYWORD) PG_KEYWORD("program", PROGRAM, UNRESERVED_KEYWORD) PG_KEYWORD("publication", PUBLICATION, UNRESERVED_KEYWORD) +PG_KEYWORD("qualify", QUALIFY, RESERVED_KEYWORD) PG_KEYWORD("quote", QUOTE, UNRESERVED_KEYWORD) PG_KEYWORD("range", RANGE, UNRESERVED_KEYWORD) PG_KEYWORD("read", READ_P, UNRESERVED_KEYWORD) @@ -240559,6 +256702,7 @@ PG_KEYWORD("repeatable", REPEATABLE, UNRESERVED_KEYWORD) PG_KEYWORD("replace", REPLACE, UNRESERVED_KEYWORD) PG_KEYWORD("replica", REPLICA, UNRESERVED_KEYWORD) PG_KEYWORD("reset", RESET, UNRESERVED_KEYWORD) +PG_KEYWORD("respect", RESPECT_P, UNRESERVED_KEYWORD) PG_KEYWORD("restart", RESTART, UNRESERVED_KEYWORD) PG_KEYWORD("restrict", RESTRICT, UNRESERVED_KEYWORD) PG_KEYWORD("returning", RETURNING, RESERVED_KEYWORD) @@ -240741,6 +256885,30 @@ bool is_keyword(const char *text) { return ScanKeywordLookup(text, ScanKeywords, NumScanKeywords) != NULL; } +std::vector keyword_list() { + std::vector result; + for(size_t i = 0; i < NumScanKeywords; i++) { + PGKeyword keyword; + keyword.text = ScanKeywords[i].name; + switch(ScanKeywords[i].category) { + case UNRESERVED_KEYWORD: + keyword.category = PGKeywordCategory::PG_KEYWORD_UNRESERVED; + break; + case RESERVED_KEYWORD: + keyword.category = PGKeywordCategory::PG_KEYWORD_RESERVED; + break; + case TYPE_FUNC_NAME_KEYWORD: + keyword.category = PGKeywordCategory::PG_KEYWORD_TYPE_FUNC; + break; + case COL_NAME_KEYWORD: + keyword.category = PGKeywordCategory::PG_KEYWORD_COL_NAME; + break; + } + result.push_back(keyword); + } + return result; +} + std::vector tokenize(const char *str) { core_yyscan_t yyscanner; base_yy_extra_type yyextra; @@ -240933,7 +257101,7 @@ int base_yylex(YYSTYPE *lvalp, YYLTYPE *llocp, core_yyscan_t yyscanner) { // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list #line 2 "third_party/libpg_query/src_backend_parser_scan.cpp" @@ -240976,44 +257144,9 @@ int base_yylex(YYSTYPE *lvalp, YYLTYPE *llocp, core_yyscan_t yyscanner) { /* only needed for GUC variables */ -// LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 -// See the end of this file for a list - -/*------------------------------------------------------------------------- - * - * scansup.h - * scanner support routines. used by both the bootstrap lexer - * as well as the normal lexer - * - * Portions Copyright (c) 1996-2017, PostgreSQL Global Development PGGroup - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/parser/scansup.h - * - *------------------------------------------------------------------------- - */ - - - -namespace duckdb_libpgquery { - -char *scanstr(const char *s); - -char *downcase_truncate_identifier(const char *ident, int len, bool warn); - -char *downcase_identifier(const char *ident, int len, bool warn, bool truncate); - -bool scanner_isspace(char ch); - -} - -// LICENSE_CHANGE_END - - // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /*------------------------------------------------------------------------- @@ -241101,7 +257234,6 @@ typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; -typedef uint64_t flex_uint64_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; @@ -241225,11 +257357,6 @@ typedef void* yyscan_t; typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 @@ -241252,6 +257379,11 @@ typedef size_t yy_size_t; #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state @@ -241269,7 +257401,7 @@ struct yy_buffer_state /* Number of characters read into yy_ch_buf, not including EOB * characters. */ - yy_size_t yy_n_chars; + int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to @@ -241348,7 +257480,7 @@ static void core_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanne YY_BUFFER_STATE core_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); YY_BUFFER_STATE core_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); -YY_BUFFER_STATE core_yy_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner ); +YY_BUFFER_STATE core_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); void *core_yyalloc (yy_size_t ,yyscan_t yyscanner ); void *core_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner ); @@ -241399,7 +257531,7 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); */ #define YY_DO_BEFORE_ACTION \ yyg->yytext_ptr = yy_bp; \ - yyleng = (yy_size_t) (yy_cp - yy_bp); \ + yyleng = (size_t) (yy_cp - yy_bp); \ yyg->yy_hold_char = *yy_cp; \ *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; @@ -242100,7 +258232,7 @@ extern void core_yyset_column(int column_no, yyscan_t yyscanner); * Note that xcstart must appear before operator, as explained above! * Also whitespace (comment) must appear before operator. */ -#line 1094 "third_party/libpg_query/src_backend_parser_scan.cpp" +#line 1093 "third_party/libpg_query/src_backend_parser_scan.cpp" #define INITIAL 0 #define xb 1 @@ -242133,8 +258265,8 @@ struct yyguts_t size_t yy_buffer_stack_max; /**< capacity of stack. */ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ char yy_hold_char; - yy_size_t yy_n_chars; - yy_size_t yyleng_r; + int yy_n_chars; + int yyleng_r; char *yy_c_buf_p; int yy_init; int yy_start; @@ -242191,7 +258323,7 @@ FILE *core_yyget_out (yyscan_t yyscanner ); void core_yyset_out (FILE * out_str ,yyscan_t yyscanner ); -yy_size_t core_yyget_leng (yyscan_t yyscanner ); +int core_yyget_leng (yyscan_t yyscanner ); char *core_yyget_text (yyscan_t yyscanner ); @@ -242258,7 +258390,7 @@ static int input (yyscan_t yyscanner ); if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ - yy_size_t n; \ + int n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ @@ -242346,7 +258478,7 @@ YY_DECL #line 401 "third_party/libpg_query/scan.l" -#line 1340 "third_party/libpg_query/src_backend_parser_scan.cpp" +#line 1339 "third_party/libpg_query/src_backend_parser_scan.cpp" yylval = yylval_param; @@ -243420,7 +259552,7 @@ YY_RULE_SETUP #line 1075 "third_party/libpg_query/scan.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 2421 "third_party/libpg_query/src_backend_parser_scan.cpp" +#line 2420 "third_party/libpg_query/src_backend_parser_scan.cpp" case YY_END_OF_BUFFER: { @@ -243606,7 +259738,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) else { - yy_size_t num_to_read = + int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) @@ -243620,7 +259752,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) if ( b->yy_is_our_buffer ) { - yy_size_t new_size = b->yy_buf_size * 2; + int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; @@ -243651,7 +259783,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - yyg->yy_n_chars, num_to_read ); + yyg->yy_n_chars, (size_t) num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } @@ -243776,7 +259908,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) else { /* need more input */ - yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr; + int offset = yyg->yy_c_buf_p - yyg->yytext_ptr; ++yyg->yy_c_buf_p; switch ( yy_get_next_buffer( yyscanner ) ) @@ -243800,7 +259932,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) case EOB_ACT_END_OF_FILE: { if ( core_yywrap(yyscanner ) ) - return 0; + return EOF; if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; @@ -244056,7 +260188,7 @@ void core_yypop_buffer_state (yyscan_t yyscanner) */ static void core_yyensure_buffer_stack (yyscan_t yyscanner) { - yy_size_t num_to_alloc; + int num_to_alloc; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!yyg->yy_buffer_stack) { @@ -244154,11 +260286,12 @@ YY_BUFFER_STATE core_yy_scan_string (yyconst char * yystr , yyscan_t yyscanner) * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ -YY_BUFFER_STATE core_yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len , yyscan_t yyscanner) +YY_BUFFER_STATE core_yy_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner) { YY_BUFFER_STATE b; char *buf; - yy_size_t n, i; + yy_size_t n; + int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; @@ -244268,7 +260401,7 @@ FILE *core_yyget_out (yyscan_t yyscanner) /** Get the length of the current token. * @param yyscanner The scanner object. */ -yy_size_t core_yyget_leng (yyscan_t yyscanner) +int core_yyget_leng (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyleng; @@ -245105,7 +261238,7 @@ core_yyfree(void *ptr, core_yyscan_t yyscanner) // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /*-------------------------------------------------------------------- @@ -245170,6 +261303,16 @@ char *downcase_truncate_identifier(const char *ident, int len, bool warn) { return downcase_identifier(ident, len, warn, true); } +static __thread bool pg_preserve_identifier_case = false; + +void set_preserve_identifier_case(bool preserve) { + pg_preserve_identifier_case = preserve; +} + +bool get_preserve_identifier_case() { + return pg_preserve_identifier_case; +} + /* * a workhorse for downcase_truncate_identifier */ @@ -245193,10 +261336,12 @@ char *downcase_identifier(const char *ident, int len, bool warn, bool truncate) for (i = 0; i < len; i++) { unsigned char ch = (unsigned char)ident[i]; - if (ch >= 'A' && ch <= 'Z') - ch += 'a' - 'A'; - else if (enc_is_single_byte && IS_HIGHBIT_SET(ch) && isupper(ch)) - ch = tolower(ch); + if (!get_preserve_identifier_case()) { + if (ch >= 'A' && ch <= 'Z') + ch += 'a' - 'A'; + else if (enc_is_single_byte && IS_HIGHBIT_SET(ch) && isupper(ch)) + ch = tolower(ch); + } result[i] = (char)ch; } result[i] = '\0'; @@ -245225,7 +261370,7 @@ bool scanner_isspace(char ch) { // LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #8 +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #9 // See the end of this file for a list /*-------------------------------------------------------------------- @@ -245749,6 +261894,33 @@ SOFTWARE. ### THIRD PARTY LICENSE #7 ### +The MIT License (MIT) + +Copyright (c) 2017 yhirose + +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: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + + + +### THIRD PARTY LICENSE #8 ### + This license file applies to everything in this repository except that which is explicitly annotated as being written by other authors, i.e. the Boost queue (included in the benchmarks for comparison), Intel's TBB library (ditto), @@ -245813,7 +261985,7 @@ DEALINGS IN THE SOFTWARE. -### THIRD PARTY LICENSE #8 ### +### THIRD PARTY LICENSE #9 ### Copyright (c) 2015, Lukas Fittl All rights reserved. @@ -245844,4 +262016,199 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +### THIRD PARTY LICENSE #10 ### + +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ diff --git a/libduckdb-sys/duckdb/duckdb.h b/libduckdb-sys/duckdb/duckdb.h index 4c134157..e07095a3 100644 --- a/libduckdb-sys/duckdb/duckdb.h +++ b/libduckdb-sys/duckdb/duckdb.h @@ -9,8 +9,10 @@ #pragma once +// duplicate of duckdb/main/winapi.hpp +#ifndef DUCKDB_API #ifdef _WIN32 -#ifdef DUCKDB_BUILD_LIBRARY +#if defined(DUCKDB_BUILD_LIBRARY) && !defined(DUCKDB_BUILD_LOADABLE_EXTENSION) #define DUCKDB_API __declspec(dllexport) #else #define DUCKDB_API __declspec(dllimport) @@ -18,6 +20,22 @@ #else #define DUCKDB_API #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 @@ -128,19 +146,43 @@ typedef struct { } 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; diff --git a/libduckdb-sys/duckdb/duckdb.hpp b/libduckdb-sys/duckdb/duckdb.hpp index 054688dc..51dd5a32 100644 --- a/libduckdb-sys/duckdb/duckdb.hpp +++ b/libduckdb-sys/duckdb/duckdb.hpp @@ -1,5 +1,5 @@ /* -Copyright 2018 DuckDB Contributors (see https://github.com/duckdb/duckdb/graphs/contributors) +Copyright 2018-2022 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 "88aa81c6b" -#define DUCKDB_VERSION "0.3.1" +#define DUCKDB_SOURCE_ID "5aebf7dac" +#define DUCKDB_VERSION "v0.3.2" //===----------------------------------------------------------------------===// // DuckDB // @@ -71,9 +71,62 @@ namespace duckdb { using std::string; } +//===----------------------------------------------------------------------===// +// DuckDB +// +// 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 + +#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 +#endif +#endif + namespace duckdb { +// API versions +// if no explicit API version is defined, the latest API version is used +// Note that using older API versions (i.e. not using DUCKDB_API_LATEST) is deprecated. +// These will not be supported long-term, and will be removed in future versions. + +#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 + //! inline std directives that we use frequently using std::move; using std::shared_ptr; @@ -96,9 +149,6 @@ typedef int64_t row_t; //! The type used for hashes typedef uint64_t hash_t; -//! The value used to signify an invalid index entry -extern const idx_t INVALID_INDEX; - //! data pointers typedef uint8_t data_t; typedef data_t *data_ptr_t; @@ -124,6 +174,11 @@ extern const transaction_t NOT_DELETED_ID; extern const double PI; +struct DConstants { + //! The value used to signify an invalid index entry + static constexpr const idx_t INVALID_INDEX = idx_t(-1); +}; + struct Storage { //! The size of a hard disk sector, only really needed for Direct IO constexpr static int SECTOR_SIZE = 4096; @@ -198,6 +253,12 @@ enum class ProfilerPrintFormat : uint8_t { NONE, QUERY_TREE, JSON, QUERY_TREE_OP #define suint64_t int64_t #endif +#if defined(_WIN32) || defined(_WIN64) +#define DUCKDB_WINDOWS +#elif defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)) +#define DUCKDB_POSIX +#endif + namespace duckdb { #if !defined(_MSC_VER) && (__cplusplus < 201402L) template @@ -309,13 +370,15 @@ void AssignSharedPointer(shared_ptr &target, const shared_ptr &source) { + + #if (defined(DUCKDB_USE_STANDARD_ASSERT) || !defined(DEBUG)) && !defined(DUCKDB_FORCE_ASSERT) #include #define D_ASSERT assert #else namespace duckdb { -void DuckDBAssertInternal(bool condition, const char *condition_name, const char *file, int linenr); +DUCKDB_API void DuckDBAssertInternal(bool condition, const char *condition_name, const char *file, int linenr); } #define D_ASSERT(condition) duckdb::DuckDBAssertInternal(bool(condition), #condition, __FILE__, __LINE__) @@ -546,34 +609,13 @@ using std::vector; -#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 - -#ifdef DUCKDB_BUILD_LOADABLE_EXTENSION -#ifdef _WIN32 -#define DUCKDB_EXTENSION_API __declspec(dllexport) -#else -#define DUCKDB_EXTENSION_API -#endif -#endif - - - namespace duckdb { class Serializer; class Deserializer; class Value; class TypeCatalogEntry; +class Vector; //! Type used to represent dates (days since 1970-01-01) struct date_t { int32_t days; @@ -904,6 +946,8 @@ enum class LogicalTypeId : uint8_t { USMALLINT = 29, UINTEGER = 30, UBIGINT = 31, + TIMESTAMP_TZ = 32, + TIME_TZ = 34, HUGEINT = 50, @@ -925,42 +969,38 @@ struct LogicalType { DUCKDB_API LogicalType(); DUCKDB_API LogicalType(LogicalTypeId id); // NOLINT: Allow implicit conversion from `LogicalTypeId` DUCKDB_API LogicalType(LogicalTypeId id, shared_ptr type_info); - - DUCKDB_API LogicalType(const LogicalType &other) : - id_(other.id_), physical_type_(other.physical_type_), type_info_(other.type_info_) {} - - DUCKDB_API LogicalType(LogicalType &&other) : - id_(other.id_), physical_type_(other.physical_type_), type_info_(move(other.type_info_)) {} + DUCKDB_API LogicalType(const LogicalType &other); + DUCKDB_API LogicalType(LogicalType &&other) noexcept; DUCKDB_API ~LogicalType(); - LogicalTypeId id() const { + inline LogicalTypeId id() const { return id_; } - PhysicalType InternalType() const { + inline PhysicalType InternalType() const { return physical_type_; } - const ExtraTypeInfo *AuxInfo() const { + inline const ExtraTypeInfo *AuxInfo() const { return type_info_.get(); } // copy assignment - LogicalType& operator=(const LogicalType &other) { + inline LogicalType& operator=(const LogicalType &other) { id_ = other.id_; physical_type_ = other.physical_type_; type_info_ = other.type_info_; return *this; } // move assignment - LogicalType& operator=(LogicalType&& other) { + inline LogicalType& operator=(LogicalType&& other) noexcept { id_ = other.id_; physical_type_ = other.physical_type_; type_info_ = move(other.type_info_); return *this; } - bool operator==(const LogicalType &rhs) const; - bool operator!=(const LogicalType &rhs) const { + DUCKDB_API bool operator==(const LogicalType &rhs) const; + inline bool operator!=(const LogicalType &rhs) const { return !(*this == rhs); } @@ -990,34 +1030,38 @@ struct LogicalType { PhysicalType GetInternalType(); public: - DUCKDB_API static const LogicalType SQLNULL; - DUCKDB_API static const LogicalType BOOLEAN; - DUCKDB_API static const LogicalType TINYINT; - DUCKDB_API static const LogicalType UTINYINT; - DUCKDB_API static const LogicalType SMALLINT; - DUCKDB_API static const LogicalType USMALLINT; - DUCKDB_API static const LogicalType INTEGER; - DUCKDB_API static const LogicalType UINTEGER; - DUCKDB_API static const LogicalType BIGINT; - DUCKDB_API static const LogicalType UBIGINT; - DUCKDB_API static const LogicalType FLOAT; - DUCKDB_API static const LogicalType DOUBLE; - DUCKDB_API static const LogicalType DATE; - DUCKDB_API static const LogicalType TIMESTAMP; - DUCKDB_API static const LogicalType TIMESTAMP_S; - DUCKDB_API static const LogicalType TIMESTAMP_MS; - DUCKDB_API static const LogicalType TIMESTAMP_NS; - DUCKDB_API static const LogicalType TIME; - DUCKDB_API static const LogicalType VARCHAR; - DUCKDB_API static const LogicalType ANY; - DUCKDB_API static const LogicalType BLOB; - DUCKDB_API static const LogicalType INTERVAL; - DUCKDB_API static const LogicalType HUGEINT; - DUCKDB_API static const LogicalType UUID; - DUCKDB_API static const LogicalType HASH; - DUCKDB_API static const LogicalType POINTER; - DUCKDB_API static const LogicalType TABLE; - DUCKDB_API static const LogicalType INVALID; + static constexpr const LogicalTypeId SQLNULL = LogicalTypeId::SQLNULL; + static constexpr const LogicalTypeId BOOLEAN = LogicalTypeId::BOOLEAN; + static constexpr const LogicalTypeId TINYINT = LogicalTypeId::TINYINT; + static constexpr const LogicalTypeId UTINYINT = LogicalTypeId::UTINYINT; + static constexpr const LogicalTypeId SMALLINT = LogicalTypeId::SMALLINT; + static constexpr const LogicalTypeId USMALLINT = LogicalTypeId::USMALLINT; + static constexpr const LogicalTypeId INTEGER = LogicalTypeId::INTEGER; + static constexpr const LogicalTypeId UINTEGER = LogicalTypeId::UINTEGER; + static constexpr const LogicalTypeId BIGINT = LogicalTypeId::BIGINT; + static constexpr const LogicalTypeId UBIGINT = LogicalTypeId::UBIGINT; + static constexpr const LogicalTypeId FLOAT = LogicalTypeId::FLOAT; + static constexpr const LogicalTypeId DOUBLE = LogicalTypeId::DOUBLE; + static constexpr const LogicalTypeId DATE = LogicalTypeId::DATE; + static constexpr const LogicalTypeId TIMESTAMP = LogicalTypeId::TIMESTAMP; + static constexpr const LogicalTypeId TIMESTAMP_S = LogicalTypeId::TIMESTAMP_SEC; + static constexpr const LogicalTypeId TIMESTAMP_MS = LogicalTypeId::TIMESTAMP_MS; + static constexpr const LogicalTypeId TIMESTAMP_NS = LogicalTypeId::TIMESTAMP_NS; + static constexpr const LogicalTypeId TIME = LogicalTypeId::TIME; + static constexpr const LogicalTypeId TIMESTAMP_TZ = LogicalTypeId::TIMESTAMP_TZ; + static constexpr const LogicalTypeId TIME_TZ = LogicalTypeId::TIME_TZ; + 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 HUGEINT = LogicalTypeId::HUGEINT; + static constexpr const LogicalTypeId UUID = LogicalTypeId::UUID; + static constexpr const LogicalTypeId HASH = LogicalTypeId::HASH; + static constexpr const LogicalTypeId POINTER = LogicalTypeId::POINTER; + static constexpr const LogicalTypeId TABLE = LogicalTypeId::TABLE; + static constexpr const LogicalTypeId INVALID = LogicalTypeId::INVALID; + + static constexpr const LogicalTypeId ROW_TYPE = LogicalTypeId::BIGINT; // explicitly allowing these functions to be capitalized to be in-line with the remaining functions DUCKDB_API static LogicalType DECIMAL(int width, int scale); // NOLINT @@ -1025,14 +1069,15 @@ struct LogicalType { DUCKDB_API static LogicalType LIST( LogicalType child); // NOLINT DUCKDB_API static LogicalType STRUCT( child_list_t children); // NOLINT DUCKDB_API static LogicalType MAP( child_list_t children); // NOLINT - DUCKDB_API static LogicalType ENUM(const string &enum_name, const vector &ordered_data); // NOLINT + DUCKDB_API static LogicalType MAP(LogicalType key, LogicalType value); // NOLINT + DUCKDB_API static LogicalType ENUM(const string &enum_name, Vector &ordered_data, idx_t size); // 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; + DUCKDB_API static const vector Numeric(); //! A list of all INTEGRAL types - DUCKDB_API static const vector INTEGRAL; + DUCKDB_API static const vector Integral(); //! A list of ALL SQL types - DUCKDB_API static const vector ALL_TYPES; + DUCKDB_API static const vector AllTypes(); }; struct DecimalType { @@ -1055,9 +1100,9 @@ struct UserType{ struct EnumType{ DUCKDB_API static const string &GetTypeName(const LogicalType &type); DUCKDB_API static int64_t GetPos(const LogicalType &type, const string& key); - DUCKDB_API static const vector &GetValuesInsertOrder(const LogicalType &type); + DUCKDB_API static Vector &GetValuesInsertOrder(const LogicalType &type); DUCKDB_API static idx_t GetSize(const LogicalType &type); - DUCKDB_API static const string& GetValue(const Value &val); + DUCKDB_API static const string GetValue(const Value &val); DUCKDB_API static void SetCatalog(LogicalType &type, TypeCatalogEntry* catalog_entry); DUCKDB_API static TypeCatalogEntry* GetCatalog(const LogicalType &type); DUCKDB_API static PhysicalType GetPhysicalType(idx_t size); @@ -1070,6 +1115,11 @@ struct StructType { DUCKDB_API static idx_t GetChildCount(const LogicalType &type); }; +struct MapType { + DUCKDB_API static const LogicalType &KeyType(const LogicalType &type); + DUCKDB_API static const LogicalType &ValueType(const LogicalType &type); +}; + string LogicalTypeIdToString(LogicalTypeId type); @@ -1128,10 +1178,9 @@ bool IsValidType() { } //! The PhysicalType used by the row identifiers column -extern const LogicalType LOGICAL_ROW_TYPE; extern const PhysicalType ROW_TYPE; -string TypeIdToString(PhysicalType type); +DUCKDB_API string TypeIdToString(PhysicalType type); idx_t GetTypeIdSize(PhysicalType type); bool TypeIsConstantSize(PhysicalType type); bool TypeIsIntegral(PhysicalType type); @@ -1158,15 +1207,9 @@ enum class ExceptionFormatValueType : uint8_t { }; struct ExceptionFormatValue { - ExceptionFormatValue(double dbl_val) // NOLINT - : type(ExceptionFormatValueType::FORMAT_VALUE_TYPE_DOUBLE), dbl_val(dbl_val) { - } - ExceptionFormatValue(int64_t int_val) // NOLINT - : type(ExceptionFormatValueType::FORMAT_VALUE_TYPE_INTEGER), int_val(int_val) { - } - ExceptionFormatValue(string str_val) // NOLINT - : type(ExceptionFormatValueType::FORMAT_VALUE_TYPE_STRING), str_val(move(str_val)) { - } + DUCKDB_API ExceptionFormatValue(double dbl_val); // NOLINT + DUCKDB_API ExceptionFormatValue(int64_t int_val); // NOLINT + DUCKDB_API ExceptionFormatValue(string str_val); // NOLINT ExceptionFormatValueType type; @@ -1183,19 +1226,19 @@ struct ExceptionFormatValue { }; template <> -ExceptionFormatValue ExceptionFormatValue::CreateFormatValue(PhysicalType value); +DUCKDB_API ExceptionFormatValue ExceptionFormatValue::CreateFormatValue(PhysicalType value); template <> -ExceptionFormatValue ExceptionFormatValue::CreateFormatValue(LogicalType value); +DUCKDB_API ExceptionFormatValue ExceptionFormatValue::CreateFormatValue(LogicalType value); template <> -ExceptionFormatValue ExceptionFormatValue::CreateFormatValue(float value); +DUCKDB_API ExceptionFormatValue ExceptionFormatValue::CreateFormatValue(float value); template <> -ExceptionFormatValue ExceptionFormatValue::CreateFormatValue(double value); +DUCKDB_API ExceptionFormatValue ExceptionFormatValue::CreateFormatValue(double value); template <> -ExceptionFormatValue ExceptionFormatValue::CreateFormatValue(string value); +DUCKDB_API ExceptionFormatValue ExceptionFormatValue::CreateFormatValue(string value); template <> -ExceptionFormatValue ExceptionFormatValue::CreateFormatValue(const char *value); +DUCKDB_API ExceptionFormatValue ExceptionFormatValue::CreateFormatValue(const char *value); template <> -ExceptionFormatValue ExceptionFormatValue::CreateFormatValue(char *value); +DUCKDB_API ExceptionFormatValue ExceptionFormatValue::CreateFormatValue(char *value); } // namespace duckdb @@ -1261,20 +1304,21 @@ enum class ExceptionType { INTERNAL = 31, // Internal exception: exception that indicates something went wrong internally (i.e. bug in the code base) INVALID_INPUT = 32, // Input or arguments error - OUT_OF_MEMORY = 33 // out of memory + OUT_OF_MEMORY = 33, // out of memory + PERMISSION = 34 // insufficient permissions }; class Exception : public std::exception { public: - explicit Exception(const string &msg); - Exception(ExceptionType exception_type, const string &message); + DUCKDB_API explicit Exception(const string &msg); + DUCKDB_API Exception(ExceptionType exception_type, const string &message); ExceptionType type; public: - const char *what() const noexcept override; + DUCKDB_API const char *what() const noexcept override; - string ExceptionTypeToString(ExceptionType type); + DUCKDB_API string ExceptionTypeToString(ExceptionType type); template static string ConstructMessage(const string &msg, Args... params) { @@ -1282,7 +1326,7 @@ class Exception : public std::exception { return ConstructMessageRecursive(msg, values, params...); } - static string ConstructMessageRecursive(const string &msg, vector &values); + DUCKDB_API static string ConstructMessageRecursive(const string &msg, vector &values); template static string ConstructMessageRecursive(const string &msg, vector &values, T param, @@ -1291,6 +1335,8 @@ class Exception : public std::exception { return ConstructMessageRecursive(msg, values, params...); } + DUCKDB_API static bool UncaughtException(); + private: string exception_message_; }; @@ -1302,13 +1348,12 @@ class Exception : public std::exception { //! Exceptions that are StandardExceptions do NOT invalidate the current transaction when thrown class StandardException : public Exception { public: - StandardException(ExceptionType exception_type, string message) : Exception(exception_type, message) { - } + DUCKDB_API StandardException(ExceptionType exception_type, const string &message); }; class CatalogException : public StandardException { public: - explicit CatalogException(const string &msg); + DUCKDB_API explicit CatalogException(const string &msg); template explicit CatalogException(const string &msg, Args... params) : CatalogException(ConstructMessage(msg, params...)) { @@ -1317,16 +1362,26 @@ class CatalogException : public StandardException { class ParserException : public StandardException { public: - explicit ParserException(const string &msg); + DUCKDB_API explicit ParserException(const string &msg); template explicit ParserException(const string &msg, Args... params) : ParserException(ConstructMessage(msg, params...)) { } }; +class PermissionException : public StandardException { +public: + DUCKDB_API explicit PermissionException(const string &msg); + + template + explicit PermissionException(const string &msg, Args... params) + : PermissionException(ConstructMessage(msg, params...)) { + } +}; + class BinderException : public StandardException { public: - explicit BinderException(const string &msg); + DUCKDB_API explicit BinderException(const string &msg); template explicit BinderException(const string &msg, Args... params) : BinderException(ConstructMessage(msg, params...)) { @@ -1335,7 +1390,7 @@ class BinderException : public StandardException { class ConversionException : public Exception { public: - explicit ConversionException(const string &msg); + DUCKDB_API explicit ConversionException(const string &msg); template explicit ConversionException(const string &msg, Args... params) @@ -1345,7 +1400,7 @@ class ConversionException : public Exception { class TransactionException : public Exception { public: - explicit TransactionException(const string &msg); + DUCKDB_API explicit TransactionException(const string &msg); template explicit TransactionException(const string &msg, Args... params) @@ -1355,7 +1410,7 @@ class TransactionException : public Exception { class NotImplementedException : public Exception { public: - explicit NotImplementedException(const string &msg); + DUCKDB_API explicit NotImplementedException(const string &msg); template explicit NotImplementedException(const string &msg, Args... params) @@ -1365,7 +1420,7 @@ class NotImplementedException : public Exception { class OutOfRangeException : public Exception { public: - explicit OutOfRangeException(const string &msg); + DUCKDB_API explicit OutOfRangeException(const string &msg); template explicit OutOfRangeException(const string &msg, Args... params) @@ -1375,7 +1430,7 @@ class OutOfRangeException : public Exception { class OutOfMemoryException : public Exception { public: - explicit OutOfMemoryException(const string &msg); + DUCKDB_API explicit OutOfMemoryException(const string &msg); template explicit OutOfMemoryException(const string &msg, Args... params) @@ -1385,7 +1440,7 @@ class OutOfMemoryException : public Exception { class SyntaxException : public Exception { public: - explicit SyntaxException(const string &msg); + DUCKDB_API explicit SyntaxException(const string &msg); template explicit SyntaxException(const string &msg, Args... params) : SyntaxException(ConstructMessage(msg, params...)) { @@ -1394,7 +1449,7 @@ class SyntaxException : public Exception { class ConstraintException : public Exception { public: - explicit ConstraintException(const string &msg); + DUCKDB_API explicit ConstraintException(const string &msg); template explicit ConstraintException(const string &msg, Args... params) @@ -1404,7 +1459,7 @@ class ConstraintException : public Exception { class IOException : public Exception { public: - explicit IOException(const string &msg); + DUCKDB_API explicit IOException(const string &msg); template explicit IOException(const string &msg, Args... params) : IOException(ConstructMessage(msg, params...)) { @@ -1413,7 +1468,7 @@ class IOException : public Exception { class SerializationException : public Exception { public: - explicit SerializationException(const string &msg); + DUCKDB_API explicit SerializationException(const string &msg); template explicit SerializationException(const string &msg, Args... params) @@ -1423,7 +1478,7 @@ class SerializationException : public Exception { class SequenceException : public Exception { public: - explicit SequenceException(const string &msg); + DUCKDB_API explicit SequenceException(const string &msg); template explicit SequenceException(const string &msg, Args... params) @@ -1433,12 +1488,12 @@ class SequenceException : public Exception { class InterruptException : public Exception { public: - InterruptException(); + DUCKDB_API InterruptException(); }; class FatalException : public Exception { public: - explicit FatalException(const string &msg); + DUCKDB_API explicit FatalException(const string &msg); template explicit FatalException(const string &msg, Args... params) : FatalException(ConstructMessage(msg, params...)) { @@ -1447,7 +1502,7 @@ class FatalException : public Exception { class InternalException : public Exception { public: - explicit InternalException(const string &msg); + DUCKDB_API explicit InternalException(const string &msg); template explicit InternalException(const string &msg, Args... params) @@ -1457,7 +1512,7 @@ class InternalException : public Exception { class InvalidInputException : public Exception { public: - explicit InvalidInputException(const string &msg); + DUCKDB_API explicit InvalidInputException(const string &msg); template explicit InvalidInputException(const string &msg, Args... params) @@ -1467,33 +1522,34 @@ class InvalidInputException : public Exception { class CastException : public Exception { public: - CastException(const PhysicalType origType, const PhysicalType newType); - CastException(const LogicalType &origType, const LogicalType &newType); + DUCKDB_API CastException(const PhysicalType origType, const PhysicalType newType); + DUCKDB_API CastException(const LogicalType &origType, const LogicalType &newType); }; class InvalidTypeException : public Exception { public: - InvalidTypeException(PhysicalType type, const string &msg); - InvalidTypeException(const LogicalType &type, const string &msg); + DUCKDB_API InvalidTypeException(PhysicalType type, const string &msg); + DUCKDB_API InvalidTypeException(const LogicalType &type, const string &msg); }; class TypeMismatchException : public Exception { public: - TypeMismatchException(const PhysicalType type_1, const PhysicalType type_2, const string &msg); - TypeMismatchException(const LogicalType &type_1, const LogicalType &type_2, const string &msg); + DUCKDB_API TypeMismatchException(const PhysicalType type_1, const PhysicalType type_2, const string &msg); + DUCKDB_API TypeMismatchException(const LogicalType &type_1, const LogicalType &type_2, const string &msg); }; class ValueOutOfRangeException : public Exception { public: - ValueOutOfRangeException(const int64_t value, const PhysicalType origType, const PhysicalType newType); - ValueOutOfRangeException(const hugeint_t value, const PhysicalType origType, const PhysicalType newType); - ValueOutOfRangeException(const double value, const PhysicalType origType, const PhysicalType newType); - ValueOutOfRangeException(const PhysicalType varType, const idx_t length); + DUCKDB_API ValueOutOfRangeException(const int64_t value, const PhysicalType origType, const PhysicalType newType); + DUCKDB_API ValueOutOfRangeException(const hugeint_t value, const PhysicalType origType, const PhysicalType newType); + DUCKDB_API ValueOutOfRangeException(const double value, const PhysicalType origType, const PhysicalType newType); + DUCKDB_API ValueOutOfRangeException(const PhysicalType varType, const idx_t length); }; } // namespace duckdb +#include namespace duckdb { @@ -1507,19 +1563,18 @@ class Serializer { template void Write(T element) { + static_assert(std::is_trivially_destructible(), "Write element must be trivially destructible"); + WriteData((const_data_ptr_t)&element, sizeof(T)); } - //! Write data from a string buffer directly (wihtout length prefix) + //! Write data from a string buffer directly (without length prefix) void WriteBufferData(const string &str) { WriteData((const_data_ptr_t)str.c_str(), str.size()); } //! Write a string with a length prefix void WriteString(const string &val) { - Write((uint32_t)val.size()); - if (!val.empty()) { - WriteData((const_data_ptr_t)val.c_str(), val.size()); - } + WriteStringLen((const_data_ptr_t)val.c_str(), val.size()); } void WriteStringLen(const_data_ptr_t val, idx_t len) { Write((uint32_t)len); @@ -1529,7 +1584,7 @@ class Serializer { } template - void WriteList(vector> &list) { + void WriteList(const vector> &list) { Write((uint32_t)list.size()); for (auto &child : list) { child->Serialize(*this); @@ -1718,7 +1773,9 @@ using std::unordered_map; namespace duckdb { -enum class FileCompressionType : uint8_t { AUTO_DETECT = 0, UNCOMPRESSED = 1, GZIP = 2 }; +enum class FileCompressionType : uint8_t { AUTO_DETECT = 0, UNCOMPRESSED = 1, GZIP = 2, ZSTD = 3 }; + +FileCompressionType FileCompressionTypeFromString(const string &input); } // namespace duckdb @@ -1756,30 +1813,28 @@ enum class FileType { struct FileHandle { public: - FileHandle(FileSystem &file_system, string path) : file_system(file_system), path(path) { - } + DUCKDB_API FileHandle(FileSystem &file_system, string path); FileHandle(const FileHandle &) = delete; - virtual ~FileHandle() { - } + DUCKDB_API virtual ~FileHandle(); - int64_t Read(void *buffer, idx_t nr_bytes); - int64_t Write(void *buffer, idx_t nr_bytes); - void Read(void *buffer, idx_t nr_bytes, idx_t location); - void Write(void *buffer, idx_t nr_bytes, idx_t location); - void Seek(idx_t location); - void Reset(); - idx_t SeekPosition(); - void Sync(); - void Truncate(int64_t new_size); - string ReadLine(); + DUCKDB_API int64_t Read(void *buffer, idx_t nr_bytes); + DUCKDB_API int64_t Write(void *buffer, idx_t nr_bytes); + DUCKDB_API void Read(void *buffer, idx_t nr_bytes, idx_t location); + DUCKDB_API void Write(void *buffer, idx_t nr_bytes, idx_t location); + DUCKDB_API void Seek(idx_t location); + DUCKDB_API void Reset(); + DUCKDB_API idx_t SeekPosition(); + DUCKDB_API void Sync(); + DUCKDB_API void Truncate(int64_t new_size); + DUCKDB_API string ReadLine(); - bool CanSeek(); - bool OnDiskFile(); - idx_t GetFileSize(); - FileType GetType(); + DUCKDB_API bool CanSeek(); + DUCKDB_API bool OnDiskFile(); + DUCKDB_API idx_t GetFileSize(); + DUCKDB_API FileType GetType(); -protected: - virtual void Close() = 0; + //! Closes the file handle. + DUCKDB_API virtual void Close() = 0; public: FileSystem &file_system; @@ -1806,104 +1861,107 @@ class FileFlags { class FileSystem { public: - virtual ~FileSystem() { - } + DUCKDB_API virtual ~FileSystem(); public: - static constexpr FileLockType DEFAULT_LOCK = FileLockType::NO_LOCK; - static constexpr FileCompressionType DEFAULT_COMPRESSION = FileCompressionType::UNCOMPRESSED; - static FileSystem &GetFileSystem(ClientContext &context); - static FileSystem &GetFileSystem(DatabaseInstance &db); - static FileOpener *GetFileOpener(ClientContext &context); + DUCKDB_API static constexpr FileLockType DEFAULT_LOCK = FileLockType::NO_LOCK; + 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 FileOpener *GetFileOpener(ClientContext &context); - virtual unique_ptr OpenFile(const string &path, uint8_t flags, FileLockType lock = DEFAULT_LOCK, - FileCompressionType compression = DEFAULT_COMPRESSION, - FileOpener *opener = nullptr); + DUCKDB_API virtual unique_ptr OpenFile(const string &path, uint8_t flags, + FileLockType lock = DEFAULT_LOCK, + FileCompressionType compression = DEFAULT_COMPRESSION, + FileOpener *opener = nullptr); //! Read exactly nr_bytes from the specified location in the file. Fails if nr_bytes could not be read. This is //! equivalent to calling SetFilePointer(location) followed by calling Read(). - virtual void Read(FileHandle &handle, void *buffer, int64_t nr_bytes, idx_t location); + DUCKDB_API virtual void Read(FileHandle &handle, void *buffer, int64_t nr_bytes, idx_t location); //! Write exactly nr_bytes to the specified location in the file. Fails if nr_bytes could not be read. This is //! equivalent to calling SetFilePointer(location) followed by calling Write(). - virtual void Write(FileHandle &handle, void *buffer, int64_t nr_bytes, idx_t location); + DUCKDB_API virtual void Write(FileHandle &handle, void *buffer, int64_t nr_bytes, idx_t location); //! Read nr_bytes from the specified file into the buffer, moving the file pointer forward by nr_bytes. Returns the //! amount of bytes read. - virtual int64_t Read(FileHandle &handle, void *buffer, int64_t nr_bytes); + DUCKDB_API virtual int64_t Read(FileHandle &handle, void *buffer, int64_t nr_bytes); //! Write nr_bytes from the buffer into the file, moving the file pointer forward by nr_bytes. - virtual int64_t Write(FileHandle &handle, void *buffer, int64_t nr_bytes); + DUCKDB_API virtual int64_t Write(FileHandle &handle, void *buffer, int64_t nr_bytes); //! Returns the file size of a file handle, returns -1 on error - virtual int64_t GetFileSize(FileHandle &handle); + 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 - virtual time_t GetLastModifiedTime(FileHandle &handle); + DUCKDB_API virtual time_t GetLastModifiedTime(FileHandle &handle); //! Returns the file last modified time of a file handle, returns timespec with zero on all attributes on error - virtual FileType GetFileType(FileHandle &handle); + DUCKDB_API virtual FileType GetFileType(FileHandle &handle); //! Truncate a file to a maximum size of new_size, new_size should be smaller than or equal to the current size of //! the file - virtual void Truncate(FileHandle &handle, int64_t new_size); + DUCKDB_API virtual void Truncate(FileHandle &handle, int64_t new_size); //! Check if a directory exists - virtual bool DirectoryExists(const string &directory); + DUCKDB_API virtual bool DirectoryExists(const string &directory); //! Create a directory if it does not exist - virtual void CreateDirectory(const string &directory); + DUCKDB_API virtual void CreateDirectory(const string &directory); //! Recursively remove a directory and all files in it - virtual void RemoveDirectory(const string &directory); + DUCKDB_API virtual void RemoveDirectory(const string &directory); //! List files in a directory, invoking the callback method for each one with (filename, is_dir) - virtual bool ListFiles(const string &directory, const std::function &callback); + DUCKDB_API virtual bool ListFiles(const string &directory, const std::function &callback); //! Move a file from source path to the target, StorageManager relies on this being an atomic action for ACID //! properties - virtual void MoveFile(const string &source, const string &target); + DUCKDB_API virtual void MoveFile(const string &source, const string &target); //! Check if a file exists - virtual bool FileExists(const string &filename); + DUCKDB_API virtual bool FileExists(const string &filename); //! Remove a file from disk - virtual void RemoveFile(const string &filename); + DUCKDB_API virtual void RemoveFile(const string &filename); //! Sync a file handle to disk - virtual void FileSync(FileHandle &handle); + DUCKDB_API virtual void FileSync(FileHandle &handle); //! Sets the working directory - static void SetWorkingDirectory(const string &path); + DUCKDB_API static void SetWorkingDirectory(const string &path); //! Gets the working directory - static string GetWorkingDirectory(); + DUCKDB_API static string GetWorkingDirectory(); //! Gets the users home directory - static string GetHomeDirectory(); + DUCKDB_API static string GetHomeDirectory(); //! Returns the system-available memory in bytes - static idx_t GetAvailableMemory(); + DUCKDB_API static idx_t GetAvailableMemory(); //! Path separator for the current file system - static string PathSeparator(); + DUCKDB_API static string PathSeparator(); //! Join two paths together - static string JoinPath(const string &a, const string &path); + 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) - static string ConvertSeparators(const string &path); + 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) - static string ExtractBaseName(const string &path); + DUCKDB_API static string ExtractBaseName(const string &path); //! Runs a glob on the file system, returning a list of matching files - virtual vector Glob(const string &path); + DUCKDB_API virtual vector Glob(const string &path); //! registers a sub-file system to handle certain file name prefixes, e.g. http:// etc. - virtual void RegisterSubSystem(unique_ptr sub_fs); + DUCKDB_API virtual void RegisterSubSystem(unique_ptr sub_fs); + DUCKDB_API virtual void RegisterSubSystem(FileCompressionType compression_type, unique_ptr fs); //! Whether or not a sub-system can handle a specific file path - virtual bool CanHandleFile(const string &fpath); + DUCKDB_API virtual bool CanHandleFile(const string &fpath); //! Set the file pointer of a file handle to a specified location. Reads and writes will happen from this location - virtual void Seek(FileHandle &handle, idx_t location); + DUCKDB_API virtual void Seek(FileHandle &handle, idx_t location); //! Reset a file to the beginning (equivalent to Seek(handle, 0) for simple files) - virtual void Reset(FileHandle &handle); - virtual idx_t SeekPosition(FileHandle &handle); + DUCKDB_API virtual void Reset(FileHandle &handle); + DUCKDB_API virtual idx_t SeekPosition(FileHandle &handle); //! Whether or not we can seek into the file - virtual bool CanSeek(); + DUCKDB_API virtual bool CanSeek(); //! Whether or not the FS handles plain files on disk. This is relevant for certain optimizations, as random reads //! in a file on-disk are much cheaper than e.g. random reads in a file over the network - virtual bool OnDiskFile(FileHandle &handle); + DUCKDB_API virtual bool OnDiskFile(FileHandle &handle); + + DUCKDB_API virtual unique_ptr OpenCompressedFile(unique_ptr handle, bool write); //! Create a LocalFileSystem. - static unique_ptr CreateLocal(); + DUCKDB_API static unique_ptr CreateLocal(); protected: //! Return the name of the filesytem. Used for forming diagnosis messages. - virtual std::string GetName() const = 0; + DUCKDB_API virtual std::string GetName() const = 0; }; } // namespace duckdb @@ -1923,6 +1981,7 @@ class BufferedFileWriter : public Serializer { FileOpener *opener = nullptr); FileSystem &fs; + string path; unique_ptr data; idx_t offset; idx_t total_written; @@ -2224,14 +2283,14 @@ struct TemplatedValidityData { static constexpr const V MAX_ENTRY = ~V(0); public: - explicit TemplatedValidityData(idx_t count) { + inline explicit TemplatedValidityData(idx_t count) { auto entry_count = EntryCount(count); owned_data = unique_ptr(new V[entry_count]); for (idx_t entry_idx = 0; entry_idx < entry_count; entry_idx++) { owned_data[entry_idx] = MAX_ENTRY; } } - TemplatedValidityData(const V *validity_mask, idx_t count) { + inline TemplatedValidityData(const V *validity_mask, idx_t count) { D_ASSERT(validity_mask); auto entry_count = EntryCount(count); owned_data = unique_ptr(new V[entry_count]); @@ -2267,14 +2326,14 @@ struct TemplatedValidityMask { static constexpr const int STANDARD_MASK_SIZE = STANDARD_ENTRY_COUNT * sizeof(validity_t); public: - TemplatedValidityMask() : validity_mask(nullptr) { + inline TemplatedValidityMask() : validity_mask(nullptr) { } - explicit TemplatedValidityMask(idx_t max_count) { + inline explicit TemplatedValidityMask(idx_t max_count) { Initialize(max_count); } - explicit TemplatedValidityMask(V *ptr) : validity_mask(ptr) { + inline explicit TemplatedValidityMask(V *ptr) : validity_mask(ptr) { } - TemplatedValidityMask(const TemplatedValidityMask &original, idx_t count) { + inline TemplatedValidityMask(const TemplatedValidityMask &original, idx_t count) { Copy(original, count); } @@ -2284,7 +2343,7 @@ struct TemplatedValidityMask { inline bool AllValid() const { return !validity_mask; } - bool CheckAllValid(idx_t count) const { + inline bool CheckAllValid(idx_t count) const { if (AllValid()) { return true; } @@ -2296,7 +2355,7 @@ struct TemplatedValidityMask { return valid_count == entry_count; } - bool CheckAllValid(idx_t to, idx_t from) const { + inline bool CheckAllValid(idx_t to, idx_t from) const { if (AllValid()) { return true; } @@ -2308,10 +2367,45 @@ struct TemplatedValidityMask { return true; } + idx_t CountValid(const idx_t count) const { + if (AllValid() || count == 0) { + return count; + } + + idx_t valid = 0; + const auto entry_count = EntryCount(count); + for (idx_t entry_idx = 0; entry_idx < entry_count;) { + auto entry = GetValidityEntry(entry_idx++); + // Handle ragged end + if (entry_idx == entry_count) { + idx_t idx_in_entry; + GetEntryIndex(count, entry_idx, idx_in_entry); + for (idx_t i = 0; i < idx_in_entry; ++i) { + valid += idx_t(RowIsValid(entry, i)); + } + break; + } + + // Handle all set + if (AllValid(entry)) { + valid += BITS_PER_VALUE; + continue; + } + + // Count partial entry (Kernighan's algorithm) + while (entry) { + entry &= (entry - 1); + ++valid; + } + } + + return valid; + } + inline V *GetData() const { return validity_mask; } - void Reset() { + inline void Reset() { validity_mask = nullptr; validity_data.reset(); } @@ -2437,19 +2531,19 @@ struct TemplatedValidityMask { } public: - void Initialize(validity_t *validity) { + inline void Initialize(validity_t *validity) { validity_data.reset(); validity_mask = validity; } - void Initialize(const TemplatedValidityMask &other) { + inline void Initialize(const TemplatedValidityMask &other) { validity_mask = other.validity_mask; validity_data = other.validity_data; } - void Initialize(idx_t count = STANDARD_VECTOR_SIZE) { + inline void Initialize(idx_t count = STANDARD_VECTOR_SIZE) { validity_data = make_buffer(count); validity_mask = validity_data->owned_data.get(); } - void Copy(const TemplatedValidityMask &other, idx_t count) { + inline void Copy(const TemplatedValidityMask &other, idx_t count) { if (other.AllValid()) { validity_data = nullptr; validity_mask = nullptr; @@ -2466,21 +2560,21 @@ struct TemplatedValidityMask { struct ValidityMask : public TemplatedValidityMask { public: - ValidityMask() : TemplatedValidityMask(nullptr) { + inline ValidityMask() : TemplatedValidityMask(nullptr) { } - explicit ValidityMask(idx_t max_count) : TemplatedValidityMask(max_count) { + inline explicit ValidityMask(idx_t max_count) : TemplatedValidityMask(max_count) { } - explicit ValidityMask(validity_t *ptr) : TemplatedValidityMask(ptr) { + inline explicit ValidityMask(validity_t *ptr) : TemplatedValidityMask(ptr) { } - ValidityMask(const ValidityMask &original, idx_t count) : TemplatedValidityMask(original, count) { + inline ValidityMask(const ValidityMask &original, idx_t count) : TemplatedValidityMask(original, count) { } public: - void Resize(idx_t old_size, idx_t new_size); + DUCKDB_API void Resize(idx_t old_size, idx_t new_size); - void Slice(const ValidityMask &other, idx_t offset); - void Combine(const ValidityMask &other, idx_t count); - string ToString(idx_t count) const; + DUCKDB_API void Slice(const ValidityMask &other, idx_t offset); + DUCKDB_API void Combine(const ValidityMask &other, idx_t count); + DUCKDB_API string ToString(idx_t count) const; }; } // namespace duckdb @@ -2508,31 +2602,47 @@ class Serializer; //! The Value object holds a single arbitrary value of any type that can be //! stored in the database. class Value { - friend class Vector; + friend struct StringValue; + friend struct StructValue; + friend struct ListValue; public: //! Create an empty NULL value of the specified type - explicit Value(LogicalType type = LogicalType::SQLNULL); + DUCKDB_API explicit Value(LogicalType type = LogicalType::SQLNULL); //! Create an INTEGER value - Value(int32_t val); // NOLINT: Allow implicit conversion from `int32_t` + DUCKDB_API Value(int32_t val); // NOLINT: Allow implicit conversion from `int32_t` //! Create a BIGINT value - Value(int64_t val); // NOLINT: Allow implicit conversion from `int64_t` + DUCKDB_API Value(int64_t val); // NOLINT: Allow implicit conversion from `int64_t` //! Create a FLOAT value - Value(float val); // NOLINT: Allow implicit conversion from `float` + DUCKDB_API Value(float val); // NOLINT: Allow implicit conversion from `float` //! Create a DOUBLE value - Value(double val); // NOLINT: Allow implicit conversion from `double` + DUCKDB_API Value(double val); // NOLINT: Allow implicit conversion from `double` //! Create a VARCHAR value - Value(const char *val); // NOLINT: Allow implicit conversion from `const char *` + DUCKDB_API Value(const char *val); // NOLINT: Allow implicit conversion from `const char *` //! Create a NULL value - Value(std::nullptr_t val); // NOLINT: Allow implicit conversion from `nullptr_t` + DUCKDB_API Value(std::nullptr_t val); // NOLINT: Allow implicit conversion from `nullptr_t` //! Create a VARCHAR value - Value(string_t val); // NOLINT: Allow implicit conversion from `string_t` + DUCKDB_API Value(string_t val); // NOLINT: Allow implicit conversion from `string_t` //! Create a VARCHAR value - Value(string val); // NOLINT: Allow implicit conversion from `string` + DUCKDB_API Value(string val); // NOLINT: Allow implicit conversion from `string` + //! Copy constructor + DUCKDB_API Value(const Value &other); + //! Move constructor + DUCKDB_API Value(Value &&other) noexcept; + //! Destructor + DUCKDB_API ~Value(); - const LogicalType &type() const { + // copy assignment + DUCKDB_API Value &operator=(const Value &other); + // move assignment + DUCKDB_API Value &operator=(Value &&other) noexcept; + + inline const LogicalType &type() const { return type_; } + inline bool IsNull() const { + return is_null; + } //! Create the lowest possible value of a given type (numeric only) DUCKDB_API static Value MinimumValue(const LogicalType &type); @@ -2576,15 +2686,17 @@ class Value { DUCKDB_API static Value DATE(int32_t year, int32_t month, int32_t day); //! Create a time Value from a specified time DUCKDB_API static Value TIME(dtime_t time); + DUCKDB_API static Value TIMETZ(dtime_t time); //! Create a time Value from a specified time DUCKDB_API static Value TIME(int32_t hour, int32_t min, int32_t sec, int32_t micros); //! Create a timestamp Value from a specified date/time combination DUCKDB_API static Value TIMESTAMP(date_t date, dtime_t time); //! Create a timestamp Value from a specified timestamp DUCKDB_API static Value TIMESTAMP(timestamp_t timestamp); - DUCKDB_API static Value TimestampNs(timestamp_t timestamp); - DUCKDB_API static Value TimestampMs(timestamp_t timestamp); - DUCKDB_API static Value TimestampSec(timestamp_t timestamp); + DUCKDB_API static Value TIMESTAMPNS(timestamp_t timestamp); + DUCKDB_API static Value TIMESTAMPMS(timestamp_t timestamp); + DUCKDB_API static Value TIMESTAMPSEC(timestamp_t timestamp); + DUCKDB_API static Value TIMESTAMPTZ(timestamp_t timestamp); //! Create a timestamp Value from a specified timestamp in separate values DUCKDB_API static Value TIMESTAMP(int32_t year, int32_t month, int32_t day, int32_t hour, int32_t min, int32_t sec, int32_t micros); @@ -2605,9 +2717,12 @@ class Value { DUCKDB_API static Value DOUBLE(double value); //! Create a struct value with given list of entries DUCKDB_API static Value STRUCT(child_list_t values); - //! Create a list value with the given entries + //! Create a list value with the given entries, list type is inferred from children + //! Cannot be called with an empty list, use either EMPTYLIST or LIST with a type instead DUCKDB_API static Value LIST(vector values); - //! Create an empty list with the specified type + //! Create a list value with the given entries + 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); //! Creat a map value from a (key, value) pair DUCKDB_API static Value MAP(Value key, Value value); @@ -2622,17 +2737,22 @@ class Value { template T GetValue() const { - throw NotImplementedException("Unimplemented template type for Value::GetValue"); + throw InternalException("Unimplemented template type for Value::GetValue"); } template static Value CreateValue(T value) { - throw NotImplementedException("Unimplemented template type for Value::CreateValue"); + throw InternalException("Unimplemented template type for Value::CreateValue"); } // Returns the internal value. Unlike GetValue(), this method does not perform casting, and assumes T matches the // type of the value. Only use this if you know what you are doing. template - T &GetValueUnsafe() { - throw NotImplementedException("Unimplemented template type for Value::GetValueUnsafe"); + T GetValueUnsafe() const { + throw InternalException("Unimplemented template type for Value::GetValueUnsafe"); + } + //! Returns a reference to the internal value. This can only be used for primitive types. + template + T &GetReferenceUnsafe() { + throw InternalException("Unimplemented template type for Value::GetReferenceUnsafe"); } //! Return a copy of this value @@ -2640,6 +2760,8 @@ class Value { return Value(*this); } + //! Hashes the Value + DUCKDB_API hash_t Hash() const; //! Convert this value to a string DUCKDB_API string ToString() const; @@ -2654,39 +2776,30 @@ class Value { DUCKDB_API bool TryCastAs(const LogicalType &target_type, bool strict = false); //! Serializes a Value to a stand-alone binary blob - DUCKDB_API void Serialize(Serializer &serializer); + DUCKDB_API void Serialize(Serializer &serializer) const; //! Deserializes a Value from a blob DUCKDB_API static Value Deserialize(Deserializer &source); - //===--------------------------------------------------------------------===// - // Numeric Operators - //===--------------------------------------------------------------------===// - Value operator+(const Value &rhs) const; - Value operator-(const Value &rhs) const; - Value operator*(const Value &rhs) const; - Value operator/(const Value &rhs) const; - Value operator%(const Value &rhs) const; - //===--------------------------------------------------------------------===// // Comparison Operators //===--------------------------------------------------------------------===// - bool operator==(const Value &rhs) const; - bool operator!=(const Value &rhs) const; - bool operator<(const Value &rhs) const; - bool operator>(const Value &rhs) const; - bool operator<=(const Value &rhs) const; - bool operator>=(const Value &rhs) const; - - bool operator==(const int64_t &rhs) const; - bool operator!=(const int64_t &rhs) const; - bool operator<(const int64_t &rhs) const; - bool operator>(const int64_t &rhs) const; - bool operator<=(const int64_t &rhs) const; - bool operator>=(const int64_t &rhs) const; - - static bool FloatIsValid(float value); - static bool DoubleIsValid(double value); - static bool StringIsValid(const char *str, idx_t length); + DUCKDB_API bool operator==(const Value &rhs) const; + DUCKDB_API bool operator!=(const Value &rhs) const; + DUCKDB_API bool operator<(const Value &rhs) const; + DUCKDB_API bool operator>(const Value &rhs) const; + DUCKDB_API bool operator<=(const Value &rhs) const; + DUCKDB_API bool operator>=(const Value &rhs) const; + + DUCKDB_API bool operator==(const int64_t &rhs) const; + DUCKDB_API bool operator!=(const int64_t &rhs) const; + DUCKDB_API bool operator<(const int64_t &rhs) const; + DUCKDB_API bool operator>(const int64_t &rhs) const; + DUCKDB_API bool operator<=(const int64_t &rhs) const; + DUCKDB_API bool operator>=(const int64_t &rhs) const; + + DUCKDB_API static bool FloatIsValid(float value); + DUCKDB_API static bool DoubleIsValid(double value); + DUCKDB_API static bool StringIsValid(const char *str, idx_t length); static bool StringIsValid(const string &str) { return StringIsValid(str.c_str(), str.size()); } @@ -2698,19 +2811,21 @@ class Value { //! Returns true if the values are (approximately) equivalent. Note this is NOT the SQL equivalence. For this //! function, NULL values are equivalent and floating point values that are close are equivalent. - static bool ValuesAreEqual(const Value &result_value, const Value &value); + DUCKDB_API static bool ValuesAreEqual(const Value &result_value, const Value &value); friend std::ostream &operator<<(std::ostream &out, const Value &val) { out << val.ToString(); return out; } - void Print() const; + DUCKDB_API void Print() const; private: //! The logical of the value LogicalType type_; +#if DUCKDB_API_VERSION < DUCKDB_API_0_3_2 public: +#endif //! Whether or not the value is NULL bool is_null; @@ -2745,17 +2860,93 @@ class Value { private: template T GetValueInternal() const; - //! Templated helper function for casting - template - static DST _cast(const Value &v); +}; - //! Templated helper function for binary operations - template - static void _templated_binary_operation(const Value &left, const Value &right, Value &result, bool ignore_null); +//===--------------------------------------------------------------------===// +// Type-specific getters +//===--------------------------------------------------------------------===// +// Note that these are equivalent to calling GetValueUnsafe, meaning no cast will be performed +// instead, an assertion will be triggered if the value is not of the correct type +struct BooleanValue { + DUCKDB_API static bool Get(const Value &value); +}; - //! Templated helper function for boolean operations - template - static bool _templated_boolean_operation(const Value &left, const Value &right); +struct TinyIntValue { + DUCKDB_API static int8_t Get(const Value &value); +}; + +struct SmallIntValue { + DUCKDB_API static int16_t Get(const Value &value); +}; + +struct IntegerValue { + DUCKDB_API static int32_t Get(const Value &value); +}; + +struct BigIntValue { + DUCKDB_API static int64_t Get(const Value &value); +}; + +struct HugeIntValue { + DUCKDB_API static hugeint_t Get(const Value &value); +}; + +struct UTinyIntValue { + DUCKDB_API static uint8_t Get(const Value &value); +}; + +struct USmallIntValue { + DUCKDB_API static uint16_t Get(const Value &value); +}; + +struct UIntegerValue { + DUCKDB_API static uint32_t Get(const Value &value); +}; + +struct UBigIntValue { + DUCKDB_API static uint64_t Get(const Value &value); +}; + +struct FloatValue { + DUCKDB_API static float Get(const Value &value); +}; + +struct DoubleValue { + DUCKDB_API static double Get(const Value &value); +}; + +struct StringValue { + DUCKDB_API static const string &Get(const Value &value); +}; + +struct DateValue { + DUCKDB_API static date_t Get(const Value &value); +}; + +struct TimeValue { + DUCKDB_API static dtime_t Get(const Value &value); +}; + +struct TimestampValue { + DUCKDB_API static timestamp_t Get(const Value &value); +}; + +struct IntervalValue { + DUCKDB_API static interval_t Get(const Value &value); +}; + +struct StructValue { + DUCKDB_API static const vector &GetChildren(const Value &value); +}; + +struct ListValue { + DUCKDB_API static const vector &GetChildren(const Value &value); +}; + +//! Return the internal integral value for any type that is stored as an integral value internally +//! This can be used on values of type integer, uinteger, but also date, timestamp, decimal, etc +struct IntegralValue { + static hugeint_t Get(const Value &value); }; template <> @@ -2835,37 +3026,72 @@ template <> DUCKDB_API interval_t Value::GetValue() const; template <> -DUCKDB_API int8_t &Value::GetValueUnsafe(); +DUCKDB_API bool Value::GetValueUnsafe() const; +template <> +DUCKDB_API int8_t Value::GetValueUnsafe() const; +template <> +DUCKDB_API int16_t Value::GetValueUnsafe() const; +template <> +DUCKDB_API int32_t Value::GetValueUnsafe() const; +template <> +DUCKDB_API int64_t Value::GetValueUnsafe() const; +template <> +DUCKDB_API hugeint_t Value::GetValueUnsafe() const; +template <> +DUCKDB_API uint8_t Value::GetValueUnsafe() const; template <> -DUCKDB_API int16_t &Value::GetValueUnsafe(); +DUCKDB_API uint16_t Value::GetValueUnsafe() const; template <> -DUCKDB_API int32_t &Value::GetValueUnsafe(); +DUCKDB_API uint32_t Value::GetValueUnsafe() const; template <> -DUCKDB_API int64_t &Value::GetValueUnsafe(); +DUCKDB_API uint64_t Value::GetValueUnsafe() const; template <> -DUCKDB_API hugeint_t &Value::GetValueUnsafe(); +DUCKDB_API string Value::GetValueUnsafe() const; template <> -DUCKDB_API uint8_t &Value::GetValueUnsafe(); +DUCKDB_API string_t Value::GetValueUnsafe() const; template <> -DUCKDB_API uint16_t &Value::GetValueUnsafe(); +DUCKDB_API float Value::GetValueUnsafe() const; template <> -DUCKDB_API uint32_t &Value::GetValueUnsafe(); +DUCKDB_API double Value::GetValueUnsafe() const; template <> -DUCKDB_API uint64_t &Value::GetValueUnsafe(); +DUCKDB_API date_t Value::GetValueUnsafe() const; template <> -DUCKDB_API string &Value::GetValueUnsafe(); +DUCKDB_API dtime_t Value::GetValueUnsafe() const; template <> -DUCKDB_API float &Value::GetValueUnsafe(); +DUCKDB_API timestamp_t Value::GetValueUnsafe() const; template <> -DUCKDB_API double &Value::GetValueUnsafe(); +DUCKDB_API interval_t Value::GetValueUnsafe() const; + +template <> +DUCKDB_API int8_t &Value::GetReferenceUnsafe(); +template <> +DUCKDB_API int16_t &Value::GetReferenceUnsafe(); +template <> +DUCKDB_API int32_t &Value::GetReferenceUnsafe(); +template <> +DUCKDB_API int64_t &Value::GetReferenceUnsafe(); +template <> +DUCKDB_API hugeint_t &Value::GetReferenceUnsafe(); +template <> +DUCKDB_API uint8_t &Value::GetReferenceUnsafe(); +template <> +DUCKDB_API uint16_t &Value::GetReferenceUnsafe(); template <> -DUCKDB_API date_t &Value::GetValueUnsafe(); +DUCKDB_API uint32_t &Value::GetReferenceUnsafe(); template <> -DUCKDB_API dtime_t &Value::GetValueUnsafe(); +DUCKDB_API uint64_t &Value::GetReferenceUnsafe(); template <> -DUCKDB_API timestamp_t &Value::GetValueUnsafe(); +DUCKDB_API float &Value::GetReferenceUnsafe(); template <> -DUCKDB_API interval_t &Value::GetValueUnsafe(); +DUCKDB_API double &Value::GetReferenceUnsafe(); +template <> +DUCKDB_API date_t &Value::GetReferenceUnsafe(); +template <> +DUCKDB_API dtime_t &Value::GetReferenceUnsafe(); +template <> +DUCKDB_API timestamp_t &Value::GetReferenceUnsafe(); +template <> +DUCKDB_API interval_t &Value::GetReferenceUnsafe(); template <> DUCKDB_API bool Value::IsValid(float value); @@ -3096,6 +3322,21 @@ enum class VectorBufferType : uint8_t { OPAQUE_BUFFER // opaque buffer, can be created for example by the parquet reader }; +enum class VectorAuxiliaryDataType : uint8_t { + ARROW_AUXILIARY // Holds Arrow Chunks that this vector depends on +}; + +struct VectorAuxiliaryData { + explicit VectorAuxiliaryData(VectorAuxiliaryDataType type_p) + : type(type_p) { + + }; + VectorAuxiliaryDataType type; + + virtual ~VectorAuxiliaryData() { + } +}; + //! The VectorBuffer is a class used by the vector to hold its data class VectorBuffer { public: @@ -3118,10 +3359,19 @@ class VectorBuffer { data_ptr_t GetData() { return data.get(); } + void SetData(unique_ptr new_data) { data = move(new_data); } + VectorAuxiliaryData *GetAuxiliaryData() { + return aux_data.get(); + } + + void SetAuxiliaryData(unique_ptr aux_data_p, VectorAuxiliaryDataType aux_type_p) { + aux_data = move(aux_data_p); + } + static buffer_ptr CreateStandardVector(PhysicalType type, idx_t capacity = STANDARD_VECTOR_SIZE); static buffer_ptr CreateConstantVector(PhysicalType type); static buffer_ptr CreateConstantVector(const LogicalType &logical_type); @@ -3132,8 +3382,13 @@ class VectorBuffer { return buffer_type; } + inline VectorAuxiliaryDataType GetAuxiliaryDataType() const { + return aux_data->type; + } + protected: VectorBufferType buffer_type; + unique_ptr aux_data; unique_ptr data; }; @@ -3228,7 +3483,7 @@ class VectorListBuffer : public VectorBuffer { void Append(const Vector &to_append, idx_t to_append_size, idx_t source_offset = 0); void Append(const Vector &to_append, const SelectionVector &sel, idx_t to_append_size, idx_t source_offset = 0); - void PushBack(Value &insert); + void PushBack(const Value &insert); idx_t capacity = 0; idx_t size = 0; @@ -3283,69 +3538,69 @@ class Vector { public: //! Create a vector that references the other vector - explicit Vector(Vector &other); + DUCKDB_API explicit Vector(Vector &other); //! Create a vector that slices another vector - explicit Vector(Vector &other, const SelectionVector &sel, idx_t count); + DUCKDB_API explicit Vector(Vector &other, const SelectionVector &sel, idx_t count); //! Create a vector that slices another vector starting from a specific offset - explicit Vector(Vector &other, idx_t offset); + DUCKDB_API explicit Vector(Vector &other, idx_t offset); //! Create a vector of size one holding the passed on value - explicit Vector(const Value &value); + DUCKDB_API explicit Vector(const Value &value); //! Create a vector of size tuple_count (non-standard) - explicit Vector(LogicalType type, idx_t capacity = STANDARD_VECTOR_SIZE); + DUCKDB_API explicit Vector(LogicalType type, idx_t capacity = STANDARD_VECTOR_SIZE); //! Create an empty standard vector with a type, equivalent to calling Vector(type, true, false) - explicit Vector(const VectorCache &cache); + DUCKDB_API explicit Vector(const VectorCache &cache); //! Create a non-owning vector that references the specified data - Vector(LogicalType type, data_ptr_t dataptr); + DUCKDB_API Vector(LogicalType type, data_ptr_t dataptr); //! Create an owning vector that holds at most STANDARD_VECTOR_SIZE entries. /*! Create a new vector If create_data is true, the vector will be an owning empty vector. If zero_data is true, the allocated data will be zero-initialized. */ - Vector(LogicalType type, bool create_data, bool zero_data, idx_t capacity = STANDARD_VECTOR_SIZE); + DUCKDB_API Vector(LogicalType type, bool create_data, bool zero_data, idx_t capacity = STANDARD_VECTOR_SIZE); // implicit copying of Vectors is not allowed Vector(const Vector &) = delete; // but moving of vectors is allowed - Vector(Vector &&other) noexcept; + DUCKDB_API Vector(Vector &&other) noexcept; public: //! Create a vector that references the specified value. - void Reference(const Value &value); + DUCKDB_API void Reference(const Value &value); //! Causes this vector to reference the data held by the other vector. //! The type of the "other" vector should match the type of this vector - void Reference(Vector &other); + DUCKDB_API void Reference(Vector &other); //! Reinterpret the data of the other vector as the type of this vector //! Note that this takes the data of the other vector as-is and places it in this vector //! Without changing the type of this vector - void Reinterpret(Vector &other); + DUCKDB_API void Reinterpret(Vector &other); //! Causes this vector to reference the data held by the other vector, changes the type if required. - void ReferenceAndSetType(Vector &other); + DUCKDB_API void ReferenceAndSetType(Vector &other); //! Resets a vector from a vector cache. //! This turns the vector back into an empty FlatVector with STANDARD_VECTOR_SIZE entries. //! The VectorCache is used so this can be done without requiring any allocations. - void ResetFromCache(const VectorCache &cache); + DUCKDB_API void ResetFromCache(const VectorCache &cache); //! Creates a reference to a slice of the other vector - void Slice(Vector &other, idx_t offset); + DUCKDB_API void Slice(Vector &other, idx_t offset); //! Creates a reference to a slice of the other vector - void Slice(Vector &other, const SelectionVector &sel, idx_t count); + DUCKDB_API void Slice(Vector &other, const SelectionVector &sel, idx_t count); //! Turns the vector into a dictionary vector with the specified dictionary - void Slice(const SelectionVector &sel, idx_t count); + DUCKDB_API void Slice(const SelectionVector &sel, idx_t count); //! Slice the vector, keeping the result around in a cache or potentially using the cache instead of slicing - void Slice(const SelectionVector &sel, idx_t count, SelCache &cache); + DUCKDB_API void Slice(const SelectionVector &sel, idx_t count, SelCache &cache); //! Creates the data of this vector with the specified type. Any data that //! is currently in the vector is destroyed. - void Initialize(bool zero_data = false, idx_t capacity = STANDARD_VECTOR_SIZE); + DUCKDB_API void Initialize(bool zero_data = false, idx_t capacity = STANDARD_VECTOR_SIZE); //! Converts this Vector to a printable string representation - string ToString(idx_t count) const; - void Print(idx_t count); + DUCKDB_API string ToString(idx_t count) const; + DUCKDB_API void Print(idx_t count); - string ToString() const; - void Print(); + DUCKDB_API string ToString() const; + DUCKDB_API void Print(); //! Flatten the vector, removing any compression and turning it into a FLAT_VECTOR DUCKDB_API void Normalify(idx_t count); @@ -3354,31 +3609,31 @@ class Vector { DUCKDB_API void Orrify(idx_t count, VectorData &data); //! Turn the vector into a sequence vector - void Sequence(int64_t start, int64_t increment); + DUCKDB_API void Sequence(int64_t start, int64_t increment); //! Verify that the Vector is in a consistent, not corrupt state. DEBUG //! FUNCTION ONLY! - void Verify(idx_t count); - void Verify(const SelectionVector &sel, idx_t count); - void UTFVerify(idx_t count); - void UTFVerify(const SelectionVector &sel, idx_t count); + DUCKDB_API void Verify(idx_t count); + DUCKDB_API void Verify(const SelectionVector &sel, idx_t count); + DUCKDB_API void UTFVerify(idx_t count); + DUCKDB_API void UTFVerify(const SelectionVector &sel, idx_t count); //! Returns the [index] element of the Vector as a Value. - Value GetValue(idx_t index) const; + DUCKDB_API Value GetValue(idx_t index) const; //! Sets the [index] element of the Vector to the specified Value. - void SetValue(idx_t index, const Value &val); + DUCKDB_API void SetValue(idx_t index, const Value &val); - void SetAuxiliary(buffer_ptr new_buffer) { + inline void SetAuxiliary(buffer_ptr new_buffer) { auxiliary = std::move(new_buffer); }; //! This functions resizes the vector - void Resize(idx_t cur_size, idx_t new_size); + DUCKDB_API void Resize(idx_t cur_size, idx_t new_size); //! Serializes a Vector to a stand-alone binary blob - void Serialize(idx_t count, Serializer &serializer); + DUCKDB_API void Serialize(idx_t count, Serializer &serializer); //! Deserializes a blob back into a Vector - void Deserialize(idx_t count, Deserializer &source); + DUCKDB_API void Deserialize(idx_t count, Deserializer &source); // Getters inline VectorType GetVectorType() const { @@ -3391,11 +3646,11 @@ class Vector { return data; } - buffer_ptr GetAuxiliary() { + inline buffer_ptr GetAuxiliary() { return auxiliary; } - buffer_ptr GetBuffer() { + inline buffer_ptr GetBuffer() { return buffer; } @@ -3458,11 +3713,11 @@ struct ConstantVector { return vector.validity; } DUCKDB_API static const SelectionVector *ZeroSelectionVector(idx_t count, SelectionVector &owned_sel); + DUCKDB_API static const SelectionVector *ZeroSelectionVector(); //! Turns "vector" into a constant vector by referencing a value within the source vector DUCKDB_API static void Reference(Vector &vector, Vector &source, idx_t position, idx_t count); static const sel_t ZERO_VECTOR[STANDARD_VECTOR_SIZE]; - static const SelectionVector ZERO_SELECTION_VECTOR; }; struct DictionaryVector { @@ -3522,9 +3777,8 @@ struct FlatVector { D_ASSERT(vector.GetVectorType() == VectorType::FLAT_VECTOR); return !vector.validity.RowIsValid(idx); } - - static const sel_t INCREMENTAL_VECTOR[STANDARD_VECTOR_SIZE]; - static const SelectionVector INCREMENTAL_SELECTION_VECTOR; + DUCKDB_API static const SelectionVector *IncrementalSelectionVector(idx_t count, SelectionVector &owned_sel); + DUCKDB_API static const SelectionVector *IncrementalSelectionVector(); }; struct ListVector { @@ -3547,8 +3801,8 @@ struct ListVector { DUCKDB_API static void Append(Vector &target, const Vector &source, idx_t source_size, idx_t source_offset = 0); 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, Value &insert); - DUCKDB_API static vector Search(Vector &list, Value &key, idx_t row); + 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); //! Share the entry of the other list vector DUCKDB_API static void ReferenceEntry(Vector &vector, Vector &other); @@ -3620,53 +3874,188 @@ struct SequenceVector { -struct ArrowArray; +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/arrow_wrapper.hpp +// +// +//===----------------------------------------------------------------------===// -namespace duckdb { -class VectorCache; -//! A Data Chunk represents a set of vectors. -/*! - The data chunk class is the intermediate representation used by the - execution engine of DuckDB. It effectively represents a subset of a relation. - It holds a set of vectors that all have the same length. +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/arrow.hpp +// +// +//===----------------------------------------------------------------------===// - DataChunk is initialized using the DataChunk::Initialize function by - providing it with a vector of TypeIds for the Vector members. By default, - this function will also allocate a chunk of memory in the DataChunk for the - vectors and all the vectors will be referencing vectors to the data owned by - the chunk. The reason for this behavior is that the underlying vectors can - become referencing vectors to other chunks as well (i.e. in the case an - operator does not alter the data, such as a Filter operator which only adds a - selection vector). +#ifndef ARROW_FLAG_DICTIONARY_ORDERED - In addition to holding the data of the vectors, the DataChunk also owns the - selection vector that underlying vectors can point to. -*/ -class DataChunk { -public: - //! Creates an empty DataChunk - DataChunk(); - ~DataChunk(); +#include - //! The vectors owned by the DataChunk. - vector data; +#ifdef __cplusplus +extern "C" { +#endif -public: - DUCKDB_API idx_t size() const { - return count; - } - DUCKDB_API idx_t ColumnCount() const { - return data.size(); - } - void SetCardinality(idx_t count_p) { - D_ASSERT(count_p <= capacity); +#define ARROW_FLAG_DICTIONARY_ORDERED 1 +#define ARROW_FLAG_NULLABLE 2 +#define ARROW_FLAG_MAP_KEYS_SORTED 4 + +struct ArrowSchema { + // Array type description + const char *format; + const char *name; + const char *metadata; + int64_t flags; + int64_t n_children; + struct ArrowSchema **children; + struct ArrowSchema *dictionary; + + // Release callback + void (*release)(struct ArrowSchema *); + // Opaque producer-specific data + void *private_data; +}; + +struct ArrowArray { + // Array data description + int64_t length; + int64_t null_count; + int64_t offset; + int64_t n_buffers; + int64_t n_children; + const void **buffers; + struct ArrowArray **children; + struct ArrowArray *dictionary; + + // Release callback + void (*release)(struct ArrowArray *); + // Opaque producer-specific data + void *private_data; +}; + +// EXPERIMENTAL +struct ArrowArrayStream { + // Callback to get the stream type + // (will be the same for all arrays in the stream). + // Return value: 0 if successful, an `errno`-compatible error code otherwise. + int (*get_schema)(struct ArrowArrayStream *, struct ArrowSchema *out); + // Callback to get the next array + // (if no error and the array is released, the stream has ended) + // Return value: 0 if successful, an `errno`-compatible error code otherwise. + int (*get_next)(struct ArrowArrayStream *, struct ArrowArray *out); + + // Callback to get optional detailed error information. + // This must only be called if the last stream operation failed + // with a non-0 return code. The returned pointer is only valid until + // the next operation on this stream (including release). + // If unavailable, NULL is returned. + const char *(*get_last_error)(struct ArrowArrayStream *); + + // Release callback: release the stream's own resources. + // Note that arrays returned by `get_next` must be individually released. + void (*release)(struct ArrowArrayStream *); + // Opaque producer-specific data + void *private_data; +}; + +#ifdef __cplusplus +} +#endif + +#endif + + + +//! Here we have the internal duckdb classes that interact with Arrow's Internal Header (i.e., duckdb/commons/arrow.hpp) +namespace duckdb { +class ArrowSchemaWrapper { +public: + ArrowSchema arrow_schema; + + ArrowSchemaWrapper() { + arrow_schema.release = nullptr; + } + + ~ArrowSchemaWrapper(); +}; +class ArrowArrayWrapper { +public: + ArrowArray arrow_array; + ArrowArrayWrapper() { + arrow_array.length = 0; + arrow_array.release = nullptr; + } + ~ArrowArrayWrapper(); +}; + +class ArrowArrayStreamWrapper { +public: + ArrowArrayStream arrow_array_stream; + int64_t number_of_rows; + void GetSchema(ArrowSchemaWrapper &schema); + + shared_ptr GetNextChunk(); + + const char *GetError(); + + ~ArrowArrayStreamWrapper(); + ArrowArrayStreamWrapper() { + arrow_array_stream.release = nullptr; + } +}; +} // namespace duckdb + + +struct ArrowArray; + +namespace duckdb { +class VectorCache; + +//! A Data Chunk represents a set of vectors. +/*! + The data chunk class is the intermediate representation used by the + execution engine of DuckDB. It effectively represents a subset of a relation. + It holds a set of vectors that all have the same length. + + DataChunk is initialized using the DataChunk::Initialize function by + providing it with a vector of TypeIds for the Vector members. By default, + this function will also allocate a chunk of memory in the DataChunk for the + vectors and all the vectors will be referencing vectors to the data owned by + the chunk. The reason for this behavior is that the underlying vectors can + become referencing vectors to other chunks as well (i.e. in the case an + operator does not alter the data, such as a Filter operator which only adds a + selection vector). + + In addition to holding the data of the vectors, the DataChunk also owns the + selection vector that underlying vectors can point to. +*/ +class DataChunk { +public: + //! Creates an empty DataChunk + DUCKDB_API DataChunk(); + DUCKDB_API ~DataChunk(); + + //! The vectors owned by the DataChunk. + vector data; + +public: + inline idx_t size() const { // NOLINT + return count; + } + inline idx_t ColumnCount() const { + return data.size(); + } + inline void SetCardinality(idx_t count_p) { + D_ASSERT(count_p <= capacity); this->count = count_p; } - void SetCardinality(const DataChunk &other) { + inline void SetCardinality(const DataChunk &other) { this->count = other.size(); } - void SetCapacity(const DataChunk &other) { + inline void SetCapacity(const DataChunk &other) { this->capacity = other.capacity; } @@ -3682,9 +4071,9 @@ class DataChunk { //! This will create one vector of the specified type for each LogicalType in the //! types list. The vector will be referencing vector to the data owned by //! the DataChunk. - void Initialize(const vector &types); + DUCKDB_API void Initialize(const vector &types); //! Initializes an empty DataChunk with the given types. The vectors will *not* have any data allocated for them. - void InitializeEmpty(const vector &types); + DUCKDB_API void InitializeEmpty(const vector &types); //! Append the other DataChunk to this one. The column count and types of //! the two DataChunks have to match exactly. Throws an exception if there //! is not enough space in the chunk and resize is not allowed. @@ -4381,8 +4770,9 @@ struct BinaryExecutor { template static idx_t Select(Vector &left, Vector &right, const SelectionVector *sel, idx_t count, SelectionVector *true_sel, SelectionVector *false_sel) { + SelectionVector owned_sel; if (!sel) { - sel = &FlatVector::INCREMENTAL_SELECTION_VECTOR; + sel = FlatVector::IncrementalSelectionVector(count, owned_sel); } if (left.GetVectorType() == VectorType::CONSTANT_VECTOR && right.GetVectorType() == VectorType::CONSTANT_VECTOR) { @@ -4551,8 +4941,9 @@ struct TernaryExecutor { template static idx_t Select(Vector &a, Vector &b, Vector &c, const SelectionVector *sel, idx_t count, SelectionVector *true_sel, SelectionVector *false_sel) { + SelectionVector owned_sel; if (!sel) { - sel = &FlatVector::INCREMENTAL_SELECTION_VECTOR; + sel = FlatVector::IncrementalSelectionVector(count, owned_sel); } VectorData adata, bdata, cdata; a.Orrify(count, adata); @@ -5065,27 +5456,20 @@ class CycleCounter { - //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/unordered_set.hpp +// duckdb/common/named_parameter_map.hpp // // //===----------------------------------------------------------------------===// -#include - -namespace duckdb { -using std::unordered_set; -} - //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/parser/column_definition.hpp +// duckdb/common/case_insensitive_map.hpp // // //===----------------------------------------------------------------------===// @@ -5093,32 +5477,27 @@ using std::unordered_set; - //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/parser/parsed_expression.hpp +// duckdb/common/unordered_set.hpp // // //===----------------------------------------------------------------------===// -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/base_expression.hpp -// -// -//===----------------------------------------------------------------------===// - +#include +namespace duckdb { +using std::unordered_set; +} //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/enums/expression_type.hpp +// duckdb/common/string_util.hpp // // //===----------------------------------------------------------------------===// @@ -5127,93 +5506,290 @@ using std::unordered_set; -namespace duckdb { -//===--------------------------------------------------------------------===// -// Predicate Expression Operation Types -//===--------------------------------------------------------------------===// -enum class ExpressionType : uint8_t { - INVALID = 0, - // explicitly cast left as right (right is integer in ValueType enum) - OPERATOR_CAST = 12, - // logical not operator - OPERATOR_NOT = 13, - // is null operator - OPERATOR_IS_NULL = 14, - // is not null operator - OPERATOR_IS_NOT_NULL = 15, +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 char CharacterToLower(char c) { + if (c >= 'A' && c <= 'Z') { + return c - ('A' - 'a'); + } + return c; + } - // ----------------------------- - // Comparison Operators - // ----------------------------- - // equal operator between left and right - COMPARE_EQUAL = 25, - // compare initial boundary - COMPARE_BOUNDARY_START = COMPARE_EQUAL, - // inequal operator between left and right - COMPARE_NOTEQUAL = 26, - // less than operator between left and right - COMPARE_LESSTHAN = 27, - // greater than operator between left and right - COMPARE_GREATERTHAN = 28, - // less than equal operator between left and right - COMPARE_LESSTHANOREQUALTO = 29, - // greater than equal operator between left and right - COMPARE_GREATERTHANOREQUALTO = 30, - // IN operator [left IN (right1, right2, ...)] - COMPARE_IN = 35, - // NOT IN operator [left NOT IN (right1, right2, ...)] - COMPARE_NOT_IN = 36, - // IS DISTINCT FROM operator - COMPARE_DISTINCT_FROM = 37, + //! Returns true if the needle string exists in the haystack + DUCKDB_API static bool Contains(const string &haystack, const string &needle); - COMPARE_BETWEEN = 38, - COMPARE_NOT_BETWEEN = 39, - // IS NOT DISTINCT FROM operator - COMPARE_NOT_DISTINCT_FROM = 40, - // compare final boundary - COMPARE_BOUNDARY_END = COMPARE_NOT_DISTINCT_FROM, + //! Returns true if the target string starts with the given prefix + DUCKDB_API static bool StartsWith(string str, string prefix); - // ----------------------------- - // Conjunction Operators - // ----------------------------- - CONJUNCTION_AND = 50, - CONJUNCTION_OR = 51, + //! Returns true if the target string ends with the given suffix. + DUCKDB_API static bool EndsWith(const string &str, const string &suffix); - // ----------------------------- - // Values - // ----------------------------- - VALUE_CONSTANT = 75, - VALUE_PARAMETER = 76, - VALUE_TUPLE = 77, - VALUE_TUPLE_ADDRESS = 78, - VALUE_NULL = 79, - VALUE_VECTOR = 80, - VALUE_SCALAR = 81, - VALUE_DEFAULT = 82, + //! Repeat a string multiple times + DUCKDB_API static string Repeat(const string &str, const idx_t n); - // ----------------------------- - // Aggregates - // ----------------------------- - AGGREGATE = 100, - BOUND_AGGREGATE = 101, - GROUPING_FUNCTION = 102, + //! Split the input string based on newline char + DUCKDB_API static vector Split(const string &str, char delimiter); - // ----------------------------- - // Window Functions - // ----------------------------- - WINDOW_AGGREGATE = 110, + //! 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 = '"'); - WINDOW_RANK = 120, - WINDOW_RANK_DENSE = 121, - WINDOW_NTILE = 122, - WINDOW_PERCENT_RANK = 123, - WINDOW_CUME_DIST = 124, - WINDOW_ROW_NUMBER = 125, + //! Join multiple strings into one string. Components are concatenated by the given separator + DUCKDB_API static string Join(const vector &input, const string &separator); - WINDOW_FIRST_VALUE = 130, - WINDOW_LAST_VALUE = 131, + //! 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/parser/column_definition.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/parsed_expression.hpp +// +// +//===----------------------------------------------------------------------===// + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/base_expression.hpp +// +// +//===----------------------------------------------------------------------===// + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/expression_type.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +//===--------------------------------------------------------------------===// +// Predicate Expression Operation Types +//===--------------------------------------------------------------------===// +enum class ExpressionType : uint8_t { + INVALID = 0, + + // explicitly cast left as right (right is integer in ValueType enum) + OPERATOR_CAST = 12, + // logical not operator + OPERATOR_NOT = 13, + // is null operator + OPERATOR_IS_NULL = 14, + // is not null operator + OPERATOR_IS_NOT_NULL = 15, + + // ----------------------------- + // Comparison Operators + // ----------------------------- + // equal operator between left and right + COMPARE_EQUAL = 25, + // compare initial boundary + COMPARE_BOUNDARY_START = COMPARE_EQUAL, + // inequal operator between left and right + COMPARE_NOTEQUAL = 26, + // less than operator between left and right + COMPARE_LESSTHAN = 27, + // greater than operator between left and right + COMPARE_GREATERTHAN = 28, + // less than equal operator between left and right + COMPARE_LESSTHANOREQUALTO = 29, + // greater than equal operator between left and right + COMPARE_GREATERTHANOREQUALTO = 30, + // IN operator [left IN (right1, right2, ...)] + COMPARE_IN = 35, + // NOT IN operator [left NOT IN (right1, right2, ...)] + COMPARE_NOT_IN = 36, + // IS DISTINCT FROM operator + COMPARE_DISTINCT_FROM = 37, + + COMPARE_BETWEEN = 38, + COMPARE_NOT_BETWEEN = 39, + // IS NOT DISTINCT FROM operator + COMPARE_NOT_DISTINCT_FROM = 40, + // compare final boundary + COMPARE_BOUNDARY_END = COMPARE_NOT_DISTINCT_FROM, + + // ----------------------------- + // Conjunction Operators + // ----------------------------- + CONJUNCTION_AND = 50, + CONJUNCTION_OR = 51, + + // ----------------------------- + // Values + // ----------------------------- + VALUE_CONSTANT = 75, + VALUE_PARAMETER = 76, + VALUE_TUPLE = 77, + VALUE_TUPLE_ADDRESS = 78, + VALUE_NULL = 79, + VALUE_VECTOR = 80, + VALUE_SCALAR = 81, + VALUE_DEFAULT = 82, + + // ----------------------------- + // Aggregates + // ----------------------------- + AGGREGATE = 100, + BOUND_AGGREGATE = 101, + GROUPING_FUNCTION = 102, + + // ----------------------------- + // Window Functions + // ----------------------------- + WINDOW_AGGREGATE = 110, + + WINDOW_RANK = 120, + WINDOW_RANK_DENSE = 121, + WINDOW_NTILE = 122, + WINDOW_PERCENT_RANK = 123, + WINDOW_CUME_DIST = 124, + WINDOW_ROW_NUMBER = 125, + + WINDOW_FIRST_VALUE = 130, + WINDOW_LAST_VALUE = 131, WINDOW_LEAD = 132, WINDOW_LAG = 133, WINDOW_NTH_VALUE = 134, @@ -5338,11 +5914,11 @@ class BaseExpression { } //! Returns the type of the expression - ExpressionType GetExpressionType() { + ExpressionType GetExpressionType() const { return type; } //! Returns the class of the expression - ExpressionClass GetExpressionClass() { + ExpressionClass GetExpressionClass() const { return expression_class; } @@ -5405,6 +5981,8 @@ class BaseExpression { namespace duckdb { class Serializer; class Deserializer; +class FieldWriter; +class FieldReader; //! The ParsedExpression class is a base class that can represent any expression //! part of a SQL statement. @@ -5422,7 +6000,7 @@ class ParsedExpression : public BaseExpression { } //! The location in the query (if any) - idx_t query_location = INVALID_INDEX; + idx_t query_location = DConstants::INVALID_INDEX; public: bool IsAggregate() const override; @@ -5438,7 +6016,10 @@ class ParsedExpression : public BaseExpression { virtual unique_ptr Copy() const = 0; //! Serializes an Expression to a stand-alone binary blob - virtual void Serialize(Serializer &serializer); + 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); @@ -5491,11 +6072,8 @@ namespace duckdb { //! A column of a table. class ColumnDefinition { public: - ColumnDefinition(string name, LogicalType type) : name(name), type(type) { - } - ColumnDefinition(string name, LogicalType type, unique_ptr default_value) - : name(name), type(type), default_value(move(default_value)) { - } + DUCKDB_API ColumnDefinition(string name, LogicalType type); + DUCKDB_API ColumnDefinition(string name, LogicalType type, unique_ptr default_value); //! The name of the entry string name; @@ -5509,10 +6087,10 @@ class ColumnDefinition { CompressionType compression_type = CompressionType::COMPRESSION_AUTO; public: - ColumnDefinition Copy() const; + DUCKDB_API ColumnDefinition Copy() const; - void Serialize(Serializer &serializer) const; - static ColumnDefinition Deserialize(Deserializer &source); + DUCKDB_API void Serialize(Serializer &serializer) const; + DUCKDB_API static ColumnDefinition Deserialize(Deserializer &source); }; } // namespace duckdb @@ -5538,24 +6116,11 @@ class TableFunction; struct PragmaInfo; struct FunctionData { - virtual ~FunctionData() { - } + DUCKDB_API virtual ~FunctionData(); - virtual unique_ptr Copy() { - throw InternalException("Unimplemented copy for FunctionData"); - }; - virtual bool Equals(FunctionData &other) { - return true; - } - static bool Equals(FunctionData *left, FunctionData *right) { - if (left == right) { - return true; - } - if (!left || !right) { - return false; - } - return left->Equals(*right); - } + DUCKDB_API virtual unique_ptr Copy(); + DUCKDB_API virtual bool Equals(FunctionData &other); + DUCKDB_API static bool Equals(FunctionData *left, FunctionData *right); }; struct TableFunctionData : public FunctionData { @@ -5565,16 +6130,14 @@ struct TableFunctionData : public FunctionData { struct FunctionParameters { vector values; - unordered_map named_parameters; + named_parameter_map_t named_parameters; }; //! Function is the base class used for any type of function (scalar, aggregate or simple function) class Function { public: - explicit Function(string name) : name(name) { - } - virtual ~Function() { - } + DUCKDB_API explicit Function(string name); + DUCKDB_API virtual ~Function(); //! The name of the function string name; @@ -5587,38 +6150,36 @@ class Function { const LogicalType &return_type); //! Returns the formatted string name(arg1, arg2.., np1=a, np2=b, ...) DUCKDB_API static string CallToString(const string &name, const vector &arguments, - const unordered_map &named_parameters); + const named_parameter_type_map_t &named_parameters); //! Bind a scalar function from the set of functions and input arguments. Returns the index of the chosen function, - //! returns INVALID_INDEX and sets error if none could be found - static idx_t BindFunction(const string &name, vector &functions, vector &arguments, - string &error); - static idx_t BindFunction(const string &name, vector &functions, - vector> &arguments, string &error); + //! returns DConstants::INVALID_INDEX and sets error if none could be found + DUCKDB_API static idx_t BindFunction(const string &name, vector &functions, + vector &arguments, string &error); + DUCKDB_API static idx_t BindFunction(const string &name, vector &functions, + vector> &arguments, string &error); //! Bind an aggregate function from the set of functions and input arguments. Returns the index of the chosen - //! function, returns INVALID_INDEX and sets error if none could be found - static idx_t BindFunction(const string &name, vector &functions, vector &arguments, - string &error); - static idx_t BindFunction(const string &name, vector &functions, - vector> &arguments, string &error); + //! function, returns DConstants::INVALID_INDEX and sets error if none could be found + DUCKDB_API static idx_t BindFunction(const string &name, vector &functions, + vector &arguments, string &error); + DUCKDB_API static idx_t BindFunction(const string &name, vector &functions, + vector> &arguments, string &error); //! Bind a table function from the set of functions and input arguments. Returns the index of the chosen - //! function, returns INVALID_INDEX and sets error if none could be found - static idx_t BindFunction(const string &name, vector &functions, vector &arguments, - string &error); - static idx_t BindFunction(const string &name, vector &functions, - vector> &arguments, string &error); + //! function, returns DConstants::INVALID_INDEX and sets error if none could be found + DUCKDB_API static idx_t BindFunction(const string &name, vector &functions, + vector &arguments, string &error); + DUCKDB_API static idx_t BindFunction(const string &name, vector &functions, + vector> &arguments, string &error); //! Bind a pragma function from the set of functions and input arguments - static idx_t BindFunction(const string &name, vector &functions, PragmaInfo &info, string &error); + DUCKDB_API static idx_t BindFunction(const string &name, vector &functions, PragmaInfo &info, + string &error); }; class SimpleFunction : public Function { public: - SimpleFunction(string name, vector arguments, - LogicalType varargs = LogicalType(LogicalTypeId::INVALID)) - : Function(name), arguments(move(arguments)), varargs(varargs) { - } - ~SimpleFunction() override { - } + DUCKDB_API SimpleFunction(string name, vector arguments, + LogicalType varargs = LogicalType(LogicalTypeId::INVALID)); + DUCKDB_API ~SimpleFunction() override; //! The set of arguments of the function vector arguments; @@ -5627,50 +6188,34 @@ class SimpleFunction : public Function { LogicalType varargs; public: - virtual string ToString() { - return Function::CallToString(name, arguments); - } + DUCKDB_API virtual string ToString(); - bool HasVarArgs() const { - return varargs.id() != LogicalTypeId::INVALID; - } + DUCKDB_API bool HasVarArgs() const; }; class SimpleNamedParameterFunction : public SimpleFunction { public: - SimpleNamedParameterFunction(string name, vector arguments, - LogicalType varargs = LogicalType(LogicalTypeId::INVALID)) - : SimpleFunction(name, move(arguments), varargs) { - } - ~SimpleNamedParameterFunction() override { - } + DUCKDB_API SimpleNamedParameterFunction(string name, vector arguments, + LogicalType varargs = LogicalType(LogicalTypeId::INVALID)); + DUCKDB_API ~SimpleNamedParameterFunction() override; //! The named parameters of the function - unordered_map named_parameters; + named_parameter_type_map_t named_parameters; public: - string ToString() override { - return Function::CallToString(name, arguments, named_parameters); - } - - bool HasNamedParameters() { - return named_parameters.size() != 0; - } + DUCKDB_API string ToString() override; + DUCKDB_API bool HasNamedParameters(); - void EvaluateInputParameters(vector &arguments, vector ¶meters, - unordered_map &named_parameters, - vector> &children); + DUCKDB_API void EvaluateInputParameters(vector &arguments, vector ¶meters, + named_parameter_map_t &named_parameters, + vector> &children); }; class BaseScalarFunction : public SimpleFunction { public: - BaseScalarFunction(string name, vector arguments, LogicalType return_type, bool has_side_effects, - LogicalType varargs = LogicalType(LogicalTypeId::INVALID)) - : SimpleFunction(move(name), move(arguments), move(varargs)), return_type(return_type), - has_side_effects(has_side_effects) { - } - ~BaseScalarFunction() override { - } + DUCKDB_API BaseScalarFunction(string name, vector arguments, LogicalType return_type, + bool has_side_effects, LogicalType varargs = LogicalType(LogicalTypeId::INVALID)); + DUCKDB_API ~BaseScalarFunction() override; //! Return type of the function LogicalType return_type; @@ -5679,14 +6224,12 @@ class BaseScalarFunction : public SimpleFunction { bool has_side_effects; public: - hash_t Hash() const; + DUCKDB_API hash_t Hash() const; //! Cast a set of expressions to the arguments of this function - void CastToFunctionArguments(vector> &children); + DUCKDB_API void CastToFunctionArguments(vector> &children); - string ToString() override { - return Function::CallToString(name, arguments, return_type); - } + DUCKDB_API string ToString() override; }; class BuiltinFunctions { @@ -5736,6 +6279,7 @@ class BuiltinFunctions { // scalar functions void RegisterDateFunctions(); + void RegisterEnumFunctions(); void RegisterGenericFunctions(); void RegisterMathFunctions(); void RegisterOperators(); @@ -6014,8 +6558,9 @@ class Interval { static constexpr const int32_t MONTHS_PER_YEAR = 12; static constexpr const int32_t MONTHS_PER_QUARTER = 3; static constexpr const int32_t DAYS_PER_WEEK = 7; - static constexpr const int64_t DAYS_PER_MONTH = - 30; // only used for interval comparison/ordering purposes, in which case a month counts as 30 days + //! only used for interval comparison/ordering purposes, in which case a month counts as 30 days + static constexpr const int64_t DAYS_PER_MONTH = 30; + static constexpr const int64_t DAYS_PER_YEAR = 365; static constexpr const int64_t MSECS_PER_SEC = 1000; static constexpr const int32_t SECS_PER_MINUTE = 60; static constexpr const int32_t MINS_PER_HOUR = 60; @@ -6049,7 +6594,7 @@ class Interval { static string ToString(const interval_t &val); //! Convert milliseconds to a normalised interval - static interval_t FromMicro(int64_t micros); + DUCKDB_API static interval_t FromMicro(int64_t micros); //! Get Interval in milliseconds static int64_t GetMilli(const interval_t &val); @@ -6066,6 +6611,14 @@ class Interval { //! Returns the exact difference between two timestamps (days and seconds) static interval_t GetDifference(timestamp_t timestamp_1, timestamp_t timestamp_2); + //! Add an interval to a date + static date_t Add(date_t left, interval_t right); + //! Add an interval to a timestamp + static timestamp_t Add(timestamp_t left, interval_t right); + //! Add an interval to a time. In case the time overflows or underflows, modify the date by the overflow. + //! For example if we go from 23:00 to 02:00, we add a day to the date + static dtime_t Add(dtime_t left, interval_t right, date_t &date); + //! Comparison operators static bool Equals(interval_t left, interval_t right); static bool GreaterThan(interval_t left, interval_t right); @@ -6346,6 +6899,8 @@ struct SelectionVector; class Serializer; class Deserializer; +class FieldWriter; +class FieldReader; class Vector; class ValidityStatistics; @@ -6360,24 +6915,27 @@ class BaseStatistics { unique_ptr validity_stats; public: - bool CanHaveNull(); - bool CanHaveNoNull(); + bool CanHaveNull() const; + bool CanHaveNoNull() const; - virtual bool IsConstant() { + virtual bool IsConstant() const { return false; } static unique_ptr CreateEmpty(LogicalType type); virtual void Merge(const BaseStatistics &other); - virtual unique_ptr Copy(); - virtual void Serialize(Serializer &serializer); - static unique_ptr Deserialize(Deserializer &source, LogicalType type); - //! Verify that a vector does not violate the statistics - virtual void Verify(Vector &vector, const SelectionVector &sel, idx_t count); - void Verify(Vector &vector, idx_t count); - virtual string ToString(); + virtual unique_ptr Copy() const; + void Serialize(Serializer &serializer) const; + virtual void Serialize(FieldWriter &writer) const; + static unique_ptr Deserialize(Deserializer &source, LogicalType type); + + //! Verify that a vector does not violate the statistics + virtual void Verify(Vector &vector, const SelectionVector &sel, idx_t count) const; + void Verify(Vector &vector, idx_t count) const; + + virtual string ToString() const; }; } // namespace duckdb @@ -6401,23 +6959,17 @@ typedef void (*dependency_function_t)(BoundFunctionExpression &expr, unordered_s class ScalarFunction : public BaseScalarFunction { public: - ScalarFunction(string name, vector arguments, LogicalType return_type, scalar_function_t function, - bool has_side_effects = false, bind_scalar_function_t bind = nullptr, - dependency_function_t dependency = nullptr, function_statistics_t statistics = nullptr, - init_local_state_t init_local_state = nullptr, - LogicalType varargs = LogicalType(LogicalTypeId::INVALID)) - : BaseScalarFunction(name, arguments, return_type, has_side_effects, varargs), function(function), bind(bind), - init_local_state(init_local_state), dependency(dependency), statistics(statistics) { - } - - ScalarFunction(vector arguments, LogicalType return_type, scalar_function_t function, - bool has_side_effects = false, bind_scalar_function_t bind = nullptr, - dependency_function_t dependency = nullptr, function_statistics_t statistics = nullptr, - init_local_state_t init_local_state = nullptr, - LogicalType varargs = LogicalType(LogicalTypeId::INVALID)) - : ScalarFunction(string(), arguments, return_type, function, has_side_effects, bind, dependency, statistics, - init_local_state, varargs) { - } + DUCKDB_API ScalarFunction(string name, vector arguments, LogicalType return_type, + scalar_function_t function, bool has_side_effects = false, + bind_scalar_function_t bind = nullptr, dependency_function_t dependency = nullptr, + function_statistics_t statistics = nullptr, init_local_state_t init_local_state = nullptr, + LogicalType varargs = LogicalType(LogicalTypeId::INVALID)); + + DUCKDB_API ScalarFunction(vector arguments, LogicalType return_type, scalar_function_t function, + bool has_side_effects = false, bind_scalar_function_t bind = nullptr, + dependency_function_t dependency = nullptr, function_statistics_t statistics = nullptr, + init_local_state_t init_local_state = nullptr, + LogicalType varargs = LogicalType(LogicalTypeId::INVALID)); //! The main scalar function to execute scalar_function_t function; @@ -6425,78 +6977,35 @@ class ScalarFunction : public BaseScalarFunction { bind_scalar_function_t bind; //! Init thread local state for the function (if any) init_local_state_t init_local_state; - // The dependency function (if any) + //! The dependency function (if any) dependency_function_t dependency; //! The statistics propagation function (if any) function_statistics_t statistics; - static unique_ptr BindScalarFunction(ClientContext &context, const string &schema, - const string &name, - vector> children, - string &error, bool is_operator = false); - static unique_ptr BindScalarFunction(ClientContext &context, - ScalarFunctionCatalogEntry &function, - vector> children, - string &error, bool is_operator = false); - - static unique_ptr BindScalarFunction(ClientContext &context, ScalarFunction bound_function, - vector> children, - bool is_operator = false); + DUCKDB_API static unique_ptr BindScalarFunction(ClientContext &context, + const string &schema, const string &name, + vector> children, + string &error, bool is_operator = false); + DUCKDB_API static unique_ptr BindScalarFunction(ClientContext &context, + ScalarFunctionCatalogEntry &function, + vector> children, + string &error, bool is_operator = false); - bool operator==(const ScalarFunction &rhs) const { - return CompareScalarFunctionT(rhs.function) && bind == rhs.bind && dependency == rhs.dependency && - statistics == rhs.statistics; - } - bool operator!=(const ScalarFunction &rhs) const { - return !(*this == rhs); - } + DUCKDB_API static unique_ptr BindScalarFunction(ClientContext &context, + ScalarFunction bound_function, + vector> children, + bool is_operator = false); - bool Equal(const ScalarFunction &rhs) const { - // number of types - if (this->arguments.size() != rhs.arguments.size()) { - return false; - } - // argument types - for (idx_t i = 0; i < this->arguments.size(); ++i) { - if (this->arguments[i] != rhs.arguments[i]) { - return false; - } - } - // return type - if (this->return_type != rhs.return_type) { - return false; - } - // varargs - if (this->varargs != rhs.varargs) { - return false; - } + DUCKDB_API bool operator==(const ScalarFunction &rhs) const; + DUCKDB_API bool operator!=(const ScalarFunction &rhs) const; - return true; // they are equal - } + DUCKDB_API bool Equal(const ScalarFunction &rhs) const; private: - bool CompareScalarFunctionT(const scalar_function_t other) const { - typedef void(scalar_function_ptr_t)(DataChunk &, ExpressionState &, Vector &); - - auto func_ptr = (scalar_function_ptr_t **)function.template target(); - auto other_ptr = (scalar_function_ptr_t **)other.template target(); - - // Case the functions were created from lambdas the target will return a nullptr - if (!func_ptr && !other_ptr) { - return true; - } - if (func_ptr == nullptr || other_ptr == nullptr) { - // scalar_function_t (std::functions) from lambdas cannot be compared - return false; - } - return ((size_t)*func_ptr == (size_t)*other_ptr); - } + bool CompareScalarFunctionT(const scalar_function_t &other) const; public: - static void NopFunction(DataChunk &input, ExpressionState &state, Vector &result) { - D_ASSERT(input.ColumnCount() >= 1); - result.Reference(input.data[0]); - } + DUCKDB_API static void NopFunction(DataChunk &input, ExpressionState &state, Vector &result); template static void UnaryFunction(DataChunk &input, ExpressionState &state, Vector &result) { @@ -6947,12 +7456,12 @@ class AggregateExecutor { template static void UnaryWindow(Vector &input, FunctionData *bind_data, data_ptr_t state, const FrameBounds &frame, - const FrameBounds &prev, Vector &result, idx_t rid) { + const FrameBounds &prev, Vector &result, idx_t rid, idx_t bias) { - auto idata = FlatVector::GetData(input) - MinValue(frame.first, prev.first); + auto idata = FlatVector::GetData(input) - bias; const auto &ivalid = FlatVector::Validity(input); OP::template Window(idata, ivalid, bind_data, (STATE *)state, frame, prev, - result, rid); + result, rid, bias); } template @@ -7051,8 +7560,15 @@ enum class OrderByNullType : uint8_t { INVALID = 0, ORDER_DEFAULT = 1, NULLS_FIR namespace duckdb { +class FieldWriter; +class FieldReader; -enum ResultModifierType : uint8_t { LIMIT_MODIFIER = 1, ORDER_MODIFIER = 2, DISTINCT_MODIFIER = 3 }; +enum ResultModifierType : uint8_t { + LIMIT_MODIFIER = 1, + ORDER_MODIFIER = 2, + DISTINCT_MODIFIER = 3, + LIMIT_PERCENT_MODIFIER = 4 +}; //! A ResultModifier class ResultModifier { @@ -7069,9 +7585,11 @@ class ResultModifier { virtual bool Equals(const ResultModifier *other) const; //! Create a copy of this ResultModifier - virtual unique_ptr Copy() = 0; + virtual unique_ptr Copy() const = 0; //! Serializes a ResultModifier to a stand-alone binary blob - virtual void Serialize(Serializer &serializer); + void Serialize(Serializer &serializer) const; + //! Serializes a ResultModifier to a stand-alone binary blob + virtual void Serialize(FieldWriter &writer) const = 0; //! Deserializes a blob back into a ResultModifier static unique_ptr Deserialize(Deserializer &source); }; @@ -7090,7 +7608,7 @@ struct OrderByNode { unique_ptr expression; public: - void Serialize(Serializer &serializer); + void Serialize(Serializer &serializer) const; string ToString() const; static OrderByNode Deserialize(Deserializer &source); }; @@ -7107,9 +7625,9 @@ class LimitModifier : public ResultModifier { public: bool Equals(const ResultModifier *other) const override; - unique_ptr Copy() override; - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(Deserializer &source); + unique_ptr Copy() const override; + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(FieldReader &reader); }; class OrderModifier : public ResultModifier { @@ -7122,9 +7640,9 @@ class OrderModifier : public ResultModifier { public: bool Equals(const ResultModifier *other) const override; - unique_ptr Copy() override; - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(Deserializer &source); + unique_ptr Copy() const override; + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(FieldReader &reader); }; class DistinctModifier : public ResultModifier { @@ -7137,9 +7655,26 @@ class DistinctModifier : public ResultModifier { public: bool Equals(const ResultModifier *other) const override; - unique_ptr Copy() override; - void Serialize(Serializer &serializer) override; - static unique_ptr Deserialize(Deserializer &source); + unique_ptr Copy() const override; + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(FieldReader &reader); +}; + +class LimitPercentModifier : public ResultModifier { +public: + LimitPercentModifier() : ResultModifier(ResultModifierType::LIMIT_PERCENT_MODIFIER) { + } + + //! LIMIT % + unique_ptr limit; + //! OFFSET + unique_ptr offset; + +public: + bool Equals(const ResultModifier *other) const override; + unique_ptr Copy() const override; + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(FieldReader &reader); }; } // namespace duckdb @@ -7282,7 +7817,7 @@ class CatalogEntry { atomic timestamp; //! Child entry unique_ptr child; - //! Parent entry (the node that owns this node) + //! Parent entry (the node that dependents_map this node) CatalogEntry *parent; public: @@ -7336,7 +7871,7 @@ class SQLStatement; class QueryErrorContext { public: - explicit QueryErrorContext(SQLStatement *statement_ = nullptr, idx_t query_location_ = INVALID_INDEX) + explicit QueryErrorContext(SQLStatement *statement_ = nullptr, idx_t query_location_ = DConstants::INVALID_INDEX) : statement(statement_), query_location(query_location_) { } @@ -7381,6 +7916,7 @@ struct CreateViewInfo; struct CreateSequenceInfo; struct CreateCollationInfo; struct CreateTypeInfo; +struct CreateTableInfo; class ClientContext; class Transaction; @@ -7403,7 +7939,7 @@ struct CatalogEntryLookup { SchemaCatalogEntry *schema; CatalogEntry *entry; - bool Found() const { + DUCKDB_API bool Found() const { return entry; } }; @@ -7417,11 +7953,11 @@ struct SimilarCatalogEntry { //! The schema of the entry. SchemaCatalogEntry *schema; - bool Found() const { + DUCKDB_API bool Found() const { return !name.empty(); } - string GetQualifiedName() const; + DUCKDB_API string GetQualifiedName() const; }; //! The Catalog object represents the catalog of the database. @@ -7441,79 +7977,96 @@ class Catalog { public: //! Get the ClientContext from the Catalog - static Catalog &GetCatalog(ClientContext &context); - static Catalog &GetCatalog(DatabaseInstance &db); + DUCKDB_API static Catalog &GetCatalog(ClientContext &context); + DUCKDB_API static Catalog &GetCatalog(DatabaseInstance &db); - DependencyManager &GetDependencyManager() { + DUCKDB_API DependencyManager &GetDependencyManager() { return *dependency_manager; } //! Returns the current version of the catalog (incremented whenever anything changes, not stored between restarts) - idx_t GetCatalogVersion(); + DUCKDB_API idx_t GetCatalogVersion(); //! Trigger a modification in the catalog, increasing the catalog version and returning the previous version - idx_t ModifyCatalog(); + DUCKDB_API idx_t ModifyCatalog(); //! Creates a schema in the catalog. - CatalogEntry *CreateSchema(ClientContext &context, CreateSchemaInfo *info); + DUCKDB_API CatalogEntry *CreateSchema(ClientContext &context, CreateSchemaInfo *info); //! Creates a table in the catalog. - CatalogEntry *CreateTable(ClientContext &context, 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 - CatalogEntry *CreateTableFunction(ClientContext &context, CreateTableFunctionInfo *info); + DUCKDB_API CatalogEntry *CreateTableFunction(ClientContext &context, CreateTableFunctionInfo *info); //! Create a copy function in the catalog - CatalogEntry *CreateCopyFunction(ClientContext &context, CreateCopyFunctionInfo *info); + DUCKDB_API CatalogEntry *CreateCopyFunction(ClientContext &context, CreateCopyFunctionInfo *info); //! Create a pragma function in the catalog - CatalogEntry *CreatePragmaFunction(ClientContext &context, CreatePragmaFunctionInfo *info); + DUCKDB_API CatalogEntry *CreatePragmaFunction(ClientContext &context, CreatePragmaFunctionInfo *info); //! Create a scalar or aggregate function in the catalog - CatalogEntry *CreateFunction(ClientContext &context, CreateFunctionInfo *info); - //! Creates a table in the catalog. - CatalogEntry *CreateView(ClientContext &context, CreateViewInfo *info); + DUCKDB_API CatalogEntry *CreateFunction(ClientContext &context, CreateFunctionInfo *info); //! Creates a table in the catalog. - CatalogEntry *CreateSequence(ClientContext &context, CreateSequenceInfo *info); + 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. - CatalogEntry *CreateType(ClientContext &context, CreateTypeInfo *info); + DUCKDB_API CatalogEntry *CreateType(ClientContext &context, CreateTypeInfo *info); //! Creates a collation in the catalog - CatalogEntry *CreateCollation(ClientContext &context, CreateCollationInfo *info); + DUCKDB_API CatalogEntry *CreateCollation(ClientContext &context, CreateCollationInfo *info); //! Creates a table in the catalog. - CatalogEntry *CreateTable(ClientContext &context, SchemaCatalogEntry *schema, BoundCreateTableInfo *info); + DUCKDB_API CatalogEntry *CreateTable(ClientContext &context, SchemaCatalogEntry *schema, + BoundCreateTableInfo *info); //! Create a table function in the catalog - CatalogEntry *CreateTableFunction(ClientContext &context, SchemaCatalogEntry *schema, - CreateTableFunctionInfo *info); + DUCKDB_API CatalogEntry *CreateTableFunction(ClientContext &context, SchemaCatalogEntry *schema, + CreateTableFunctionInfo *info); //! Create a copy function in the catalog - CatalogEntry *CreateCopyFunction(ClientContext &context, SchemaCatalogEntry *schema, CreateCopyFunctionInfo *info); + DUCKDB_API CatalogEntry *CreateCopyFunction(ClientContext &context, SchemaCatalogEntry *schema, + CreateCopyFunctionInfo *info); //! Create a pragma function in the catalog - CatalogEntry *CreatePragmaFunction(ClientContext &context, SchemaCatalogEntry *schema, - CreatePragmaFunctionInfo *info); + DUCKDB_API CatalogEntry *CreatePragmaFunction(ClientContext &context, SchemaCatalogEntry *schema, + CreatePragmaFunctionInfo *info); //! Create a scalar or aggregate function in the catalog - CatalogEntry *CreateFunction(ClientContext &context, SchemaCatalogEntry *schema, CreateFunctionInfo *info); + DUCKDB_API CatalogEntry *CreateFunction(ClientContext &context, SchemaCatalogEntry *schema, + CreateFunctionInfo *info); //! Creates a table in the catalog. - CatalogEntry *CreateView(ClientContext &context, SchemaCatalogEntry *schema, CreateViewInfo *info); + DUCKDB_API CatalogEntry *CreateView(ClientContext &context, SchemaCatalogEntry *schema, CreateViewInfo *info); //! Creates a table in the catalog. - CatalogEntry *CreateSequence(ClientContext &context, SchemaCatalogEntry *schema, CreateSequenceInfo *info); + DUCKDB_API CatalogEntry *CreateSequence(ClientContext &context, SchemaCatalogEntry *schema, + CreateSequenceInfo *info); //! Creates a enum in the catalog. - CatalogEntry *CreateType(ClientContext &context, SchemaCatalogEntry *schema, CreateTypeInfo *info); + DUCKDB_API CatalogEntry *CreateType(ClientContext &context, SchemaCatalogEntry *schema, CreateTypeInfo *info); //! Creates a collation in the catalog - CatalogEntry *CreateCollation(ClientContext &context, SchemaCatalogEntry *schema, CreateCollationInfo *info); + DUCKDB_API CatalogEntry *CreateCollation(ClientContext &context, SchemaCatalogEntry *schema, + CreateCollationInfo *info); //! Drops an entry from the catalog - void DropEntry(ClientContext &context, DropInfo *info); + 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 - SchemaCatalogEntry *GetSchema(ClientContext &context, const string &name = DEFAULT_SCHEMA, bool if_exists = false, - QueryErrorContext error_context = QueryErrorContext()); + 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 - void ScanSchemas(ClientContext &context, std::function callback); + 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 - CatalogEntry *GetEntry(ClientContext &context, CatalogType type, const string &schema, const string &name, - bool if_exists = false, QueryErrorContext error_context = QueryErrorContext()); + DUCKDB_API CatalogEntry *GetEntry(ClientContext &context, CatalogType type, 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); template T *GetEntry(ClientContext &context, const string &schema_name, const string &name, bool if_exists = false, QueryErrorContext error_context = QueryErrorContext()); + //! 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); + //! Alter an existing entry in the catalog. - void Alter(ClientContext &context, AlterInfo *info); + DUCKDB_API void Alter(ClientContext &context, AlterInfo *info); private: //! The catalog version, incremented whenever anything changes in the catalog @@ -7537,26 +8090,30 @@ class Catalog { }; template <> -TableCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name, - bool if_exists, QueryErrorContext error_context); +DUCKDB_API TableCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name, + bool if_exists, QueryErrorContext error_context); template <> -SequenceCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name, - bool if_exists, QueryErrorContext error_context); +DUCKDB_API SequenceCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, + const string &name, bool if_exists, QueryErrorContext error_context); template <> -TableFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name, - bool if_exists, QueryErrorContext error_context); +DUCKDB_API TableFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, + const string &name, bool if_exists, + QueryErrorContext error_context); template <> -CopyFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name, - bool if_exists, QueryErrorContext error_context); +DUCKDB_API CopyFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, + const string &name, bool if_exists, + QueryErrorContext error_context); template <> -PragmaFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name, - bool if_exists, QueryErrorContext error_context); +DUCKDB_API PragmaFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, + const string &name, bool if_exists, + QueryErrorContext error_context); template <> -AggregateFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name, - bool if_exists, QueryErrorContext error_context); +DUCKDB_API AggregateFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, + const string &name, bool if_exists, + QueryErrorContext error_context); template <> -CollateCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name, - bool if_exists, QueryErrorContext error_context); +DUCKDB_API CollateCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name, + bool if_exists, QueryErrorContext error_context); } // namespace duckdb @@ -7591,6 +8148,7 @@ enum class LogicalOperatorType : uint8_t { LOGICAL_COPY_TO_FILE = 10, LOGICAL_DISTINCT = 11, LOGICAL_SAMPLE = 12, + LOGICAL_LIMIT_PERCENT = 13, // ----------------------------- // Data sources @@ -7921,7 +8479,7 @@ struct ColumnBinding { idx_t table_index; idx_t column_index; - ColumnBinding() : table_index(INVALID_INDEX), column_index(INVALID_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) { } @@ -7975,7 +8533,7 @@ class LogicalOperator { virtual string GetName() const; virtual string ParamsToString() const; - virtual string ToString(idx_t depth = 0) const; + virtual string ToString() const; void Print(); //! Debug method: verify that the integrity of expressions & child nodes are maintained virtual void Verify(); @@ -8082,6 +8640,20 @@ class BoundDistinctModifier : public BoundResultModifier { vector> target_distincts; }; +class BoundLimitPercentModifier : public BoundResultModifier { +public: + BoundLimitPercentModifier() : BoundResultModifier(ResultModifierType::LIMIT_PERCENT_MODIFIER) { + } + //! 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 @@ -8119,26 +8691,29 @@ typedef void (*aggregate_simple_update_t)(Vector inputs[], FunctionData *bind_da //! The type used for updating complex windowed aggregate functions (optional) typedef std::pair FrameBounds; typedef void (*aggregate_window_t)(Vector inputs[], FunctionData *bind_data, idx_t input_count, data_ptr_t state, - const FrameBounds &frame, const FrameBounds &prev, Vector &result, idx_t offset); + const FrameBounds &frame, const FrameBounds &prev, Vector &result, idx_t rid, + idx_t bias); class AggregateFunction : public BaseScalarFunction { public: - 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) + 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) : BaseScalarFunction(name, arguments, return_type, false), state_size(state_size), initialize(initialize), update(update), combine(combine), finalize(finalize), simple_update(simple_update), window(window), bind(bind), destructor(destructor), statistics(statistics) { } - 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) + 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) : AggregateFunction(string(), arguments, return_type, state_size, initialize, update, combine, finalize, simple_update, bind, destructor, statistics, window) { } @@ -8166,23 +8741,23 @@ class AggregateFunction : public BaseScalarFunction { //! The statistics propagation function (may be null) aggregate_statistics_t statistics; - bool operator==(const AggregateFunction &rhs) const { + 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; } - bool operator!=(const AggregateFunction &rhs) const { + DUCKDB_API bool operator!=(const AggregateFunction &rhs) const { return !(*this == rhs); } - static unique_ptr + DUCKDB_API static unique_ptr BindAggregateFunction(ClientContext &context, AggregateFunction bound_function, vector> children, unique_ptr filter = nullptr, bool is_distinct = false, unique_ptr order_bys = nullptr); - static unique_ptr BindSortedAggregate(AggregateFunction &bound_function, - vector> &children, - unique_ptr bind_info, - unique_ptr order_bys); + DUCKDB_API static unique_ptr BindSortedAggregate(AggregateFunction &bound_function, + vector> &children, + unique_ptr bind_info, + unique_ptr order_bys); public: template @@ -8261,10 +8836,10 @@ class AggregateFunction : public BaseScalarFunction { template static void UnaryWindow(Vector inputs[], FunctionData *bind_data, idx_t input_count, data_ptr_t state, - const FrameBounds &frame, const FrameBounds &prev, Vector &result, idx_t rid) { + const FrameBounds &frame, const FrameBounds &prev, Vector &result, idx_t rid, idx_t bias) { D_ASSERT(input_count == 1); AggregateExecutor::UnaryWindow(inputs[0], bind_data, state, frame, prev, - result, rid); + result, rid, bias); } template @@ -8585,7 +9160,7 @@ struct UDFWrapper { } template - static bool TypesMatch(LogicalType sql_type) { + static bool TypesMatch(const LogicalType &sql_type) { switch (sql_type.id()) { case LogicalTypeId::BOOLEAN: return std::is_same(); @@ -8600,11 +9175,13 @@ struct UDFWrapper { 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(); @@ -8875,22 +9452,18 @@ struct ArrowSchema; namespace duckdb { -enum class QueryResultType : uint8_t { MATERIALIZED_RESULT, STREAM_RESULT }; +enum class QueryResultType : uint8_t { MATERIALIZED_RESULT, STREAM_RESULT, PENDING_RESULT }; -//! 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 { +class BaseQueryResult { public: - //! Creates an successful empty query result - DUCKDB_API QueryResult(QueryResultType type, StatementType statement_type); + //! Creates a successful empty query result + DUCKDB_API BaseQueryResult(QueryResultType type, StatementType statement_type); //! Creates a successful query result with the specified names and types - DUCKDB_API QueryResult(QueryResultType type, StatementType statement_type, vector types, - vector names); + DUCKDB_API BaseQueryResult(QueryResultType type, StatementType statement_type, vector types, + vector names); //! Creates an unsuccessful query result with error condition - DUCKDB_API QueryResult(QueryResultType type, string error); - DUCKDB_API virtual ~QueryResult() { - } + DUCKDB_API BaseQueryResult(QueryResultType type, string error); + DUCKDB_API virtual ~BaseQueryResult(); //! The type of the result (MATERIALIZED or STREAMING) QueryResultType type; @@ -8904,6 +9477,27 @@ class QueryResult { bool success; //! The error string (in case execution was not successful) string error; + +public: + DUCKDB_API bool HasError(); + DUCKDB_API const string &GetError(); + DUCKDB_API idx_t ColumnCount(); +}; + +//! 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 empty query result + DUCKDB_API QueryResult(QueryResultType type, StatementType statement_type); + //! Creates a successful query result with the specified names and types + DUCKDB_API QueryResult(QueryResultType type, StatementType statement_type, vector types, + vector names); + //! Creates an unsuccessful query result with error condition + DUCKDB_API QueryResult(QueryResultType type, string error); + DUCKDB_API virtual ~QueryResult() override; + //! The next result (if any) unique_ptr next; @@ -8922,10 +9516,6 @@ class QueryResult { //! Fetch() until both results are exhausted. The data in the results will be lost. DUCKDB_API bool Equals(QueryResult &other); - DUCKDB_API idx_t ColumnCount() { - return types.size(); - } - DUCKDB_API bool TryFetch(unique_ptr &result, string &error) { try { result = Fetch(); @@ -9050,7 +9640,7 @@ class MaterializedQueryResult : public QueryResult { //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/main/prepared_statement.hpp +// duckdb/main/pending_query_result.hpp // // //===----------------------------------------------------------------------===// @@ -9058,75 +9648,28 @@ class MaterializedQueryResult : public QueryResult { +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/pending_execution_result.hpp +// +// +//===----------------------------------------------------------------------===// -namespace duckdb { -class ClientContext; -class PreparedStatementData; - -//! A prepared statement -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); - //! Create a prepared statement that was not successfully prepared - DUCKDB_API explicit PreparedStatement(string error); - - DUCKDB_API ~PreparedStatement(); - -public: - //! The client context this prepared statement belongs to - shared_ptr context; - //! The prepared statement data - shared_ptr data; - //! The query that is being prepared - string query; - //! Whether or not the statement was successfully prepared - bool success; - //! The error message (if success = false) - string error; - //! The amount of bound parameters - idx_t n_param; - -public: - //! Returns the number of columns in the result - idx_t ColumnCount(); - //! Returns the statement type of the underlying prepared statement object - StatementType GetStatementType(); - //! Returns the result SQL types of the prepared statement - const vector &GetTypes(); - //! Returns the result names of the prepared statement - const vector &GetNames(); - //! Execute the prepared statement with the given set of arguments - template - unique_ptr Execute(Args... args) { - vector values; - return ExecuteRecursive(values, args...); - } - //! Execute the prepared statement with the given set of values - DUCKDB_API unique_ptr Execute(vector &values, bool allow_stream_result = true); -private: - unique_ptr ExecuteRecursive(vector &values) { - return Execute(values); - } +namespace duckdb { - template - unique_ptr ExecuteRecursive(vector &values, T value, Args... args) { - values.push_back(Value::CreateValue(value)); - return ExecuteRecursive(values, args...); - } -}; +enum class PendingExecutionResult : uint8_t { RESULT_READY, RESULT_NOT_READY, EXECUTION_ERROR }; } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/main/relation.hpp +// duckdb/execution/executor.hpp // // //===----------------------------------------------------------------------===// @@ -9134,10 +9677,11 @@ class PreparedStatement { + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/enums/join_type.hpp +// duckdb/parallel/pipeline.hpp // // //===----------------------------------------------------------------------===// @@ -9145,41 +9689,22 @@ class PreparedStatement { +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/execution/physical_operator.hpp +// +// +//===----------------------------------------------------------------------===// -namespace duckdb { - -//===--------------------------------------------------------------------===// -// Join Types -//===--------------------------------------------------------------------===// -enum class JoinType : uint8_t { - INVALID = 0, // invalid join type - LEFT = 1, // left - RIGHT = 2, // right - INNER = 3, // inner - OUTER = 4, // outer - SEMI = 5, // SEMI join returns left side row ONLY if it has a join partner, no duplicates - ANTI = 6, // ANTI join returns left side row ONLY if it has NO join partner, no duplicates - MARK = 7, // MARK join returns marker indicating whether or not there is a join partner (true), there is no join - // partner (false) - SINGLE = 8 // SINGLE join is like LEFT OUTER JOIN, BUT returns at most one join partner per entry on the LEFT side - // (and NULL if no partner is found) -}; - -//! Convert join type to string -string JoinTypeToString(JoinType type); -//! True if join is left or full outer join -bool IsLeftOuterJoin(JoinType type); -//! True if join is rght or full outer join -bool IsRightOuterJoin(JoinType type); -} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/enums/relation_type.hpp +// duckdb/common/enums/physical_operator_type.hpp // // //===----------------------------------------------------------------------===// @@ -9191,170 +9716,97 @@ bool IsRightOuterJoin(JoinType type); namespace duckdb { //===--------------------------------------------------------------------===// -// Catalog Types +// Physical Operator Types //===--------------------------------------------------------------------===// -enum class RelationType : uint8_t { - INVALID_RELATION, - TABLE_RELATION, - PROJECTION_RELATION, - FILTER_RELATION, - EXPLAIN_RELATION, - CROSS_PRODUCT_RELATION, - JOIN_RELATION, - AGGREGATE_RELATION, - SET_OPERATION_RELATION, - DISTINCT_RELATION, - LIMIT_RELATION, - ORDER_RELATION, - CREATE_VIEW_RELATION, - CREATE_TABLE_RELATION, - INSERT_RELATION, - VALUE_LIST_RELATION, - DELETE_RELATION, - UPDATE_RELATION, - WRITE_CSV_RELATION, - READ_CSV_RELATION, - SUBQUERY_RELATION, - TABLE_FUNCTION_RELATION, - VIEW_RELATION, - QUERY_RELATION -}; - -string RelationTypeToString(RelationType type); - -} // namespace duckdb - - - - - - -#include - -namespace duckdb { -struct BoundStatement; - -class ClientContext; -class Binder; -class LogicalOperator; -class QueryNode; -class TableRef; - -class Relation : public std::enable_shared_from_this { -public: - DUCKDB_API Relation(ClientContext &context, RelationType type) : context(context), type(type) { - } - DUCKDB_API virtual ~Relation() { - } - - ClientContext &context; - RelationType type; - -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(); - - DUCKDB_API unique_ptr Execute(); - DUCKDB_API string ToString(); - DUCKDB_API virtual string ToString(idx_t depth) = 0; - - DUCKDB_API void Print(); - DUCKDB_API void Head(idx_t limit = 10); - - DUCKDB_API shared_ptr CreateView(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); - - //! Explain the query plan of this relation - DUCKDB_API unique_ptr Explain(); - - DUCKDB_API virtual unique_ptr GetTableRef(); - DUCKDB_API virtual bool IsReadOnly() { - return true; - } - -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); - - // 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); - - // 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(); - - // 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); +enum class PhysicalOperatorType : uint8_t { + INVALID, + ORDER_BY, + LIMIT, + LIMIT_PERCENT, + TOP_N, + WINDOW, + UNNEST, + SIMPLE_AGGREGATE, + HASH_GROUP_BY, + PERFECT_HASH_GROUP_BY, + FILTER, + PROJECTION, + COPY_TO_FILE, + RESERVOIR_SAMPLE, + STREAMING_SAMPLE, + STREAMING_WINDOW, + // ----------------------------- + // Scans + // ----------------------------- + TABLE_SCAN, + DUMMY_SCAN, + CHUNK_SCAN, + RECURSIVE_CTE_SCAN, + DELIM_SCAN, + EXPRESSION_SCAN, + // ----------------------------- + // Joins + // ----------------------------- + BLOCKWISE_NL_JOIN, + NESTED_LOOP_JOIN, + HASH_JOIN, + CROSS_PRODUCT, + PIECEWISE_MERGE_JOIN, + DELIM_JOIN, + INDEX_JOIN, + // ----------------------------- + // SetOps + // ----------------------------- + UNION, + RECURSIVE_CTE, - // ALIAS - DUCKDB_API shared_ptr Alias(const string &alias); + // ----------------------------- + // Updates + // ----------------------------- + INSERT, + DELETE_OPERATOR, + UPDATE, - //! 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); + // ----------------------------- + // Schema + // ----------------------------- + CREATE_TABLE, + CREATE_TABLE_AS, + CREATE_INDEX, + ALTER, + CREATE_SEQUENCE, + CREATE_VIEW, + CREATE_SCHEMA, + CREATE_MACRO, + DROP, + PRAGMA, + TRANSACTION, + CREATE_TYPE, - //! Write a relation to a CSV file - DUCKDB_API void WriteCSV(const string &csv_file); + // ----------------------------- + // Helpers + // ----------------------------- + EXPLAIN, + EXPLAIN_ANALYZE, + EMPTY_RESULT, + EXECUTE, + PREPARE, + VACUUM, + EXPORT, + SET, + LOAD, + INOUT_FUNCTION +}; - //! 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 unordered_map &named_parameters); +string PhysicalOperatorToString(PhysicalOperatorType type); -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; - } +} // namespace duckdb -protected: - DUCKDB_API string RenderWhitespace(idx_t depth); -}; -} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/main/stream_query_result.hpp +// duckdb/execution/execution_context.hpp // // //===----------------------------------------------------------------------===// @@ -9363,48 +9815,27 @@ class Relation : public std::enable_shared_from_this { - namespace duckdb { - class ClientContext; -class MaterializedQueryResult; -class PreparedStatementData; - -class StreamQueryResult : public QueryResult { -public: - //! Create a successful StreamQueryResult. StreamQueryResults should always be successful initially (it makes no - //! sense to stream an error). - DUCKDB_API StreamQueryResult(StatementType statement_type, shared_ptr context, - vector types, vector names, - shared_ptr prepared = nullptr); - DUCKDB_API ~StreamQueryResult() override; - - //! Whether or not the StreamQueryResult is still open - bool is_open; +class ThreadContext; +class ExecutionContext { public: - //! Fetches a DataChunk from the query result. - DUCKDB_API unique_ptr FetchRaw() override; - //! Converts the QueryResult to a string - DUCKDB_API string ToString() override; - //! Materializes the query result and turns it into a materialized query result - DUCKDB_API unique_ptr Materialize(); - - //! Closes the StreamQueryResult - DUCKDB_API void Close(); + ExecutionContext(ClientContext &client_p, ThreadContext &thread_p) : client(client_p), thread(thread_p) { + } -private: - //! The client context this StreamQueryResult belongs to - shared_ptr context; - //! The prepared statement data this StreamQueryResult was created with (if any) - shared_ptr prepared; + //! 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; }; } // namespace duckdb + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/main/table_description.hpp +// duckdb/common/enums/operator_result_type.hpp // // //===----------------------------------------------------------------------===// @@ -9415,294 +9846,367 @@ class StreamQueryResult : public QueryResult { namespace duckdb { -struct TableDescription { - //! The schema of the table - string schema; - //! The table name of the table - string table; - //! The columns of the table - vector columns; -}; - -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/sql_statement.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/printer.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 }; +//! 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 namespace duckdb { +class Event; +class PhysicalOperator; +class Pipeline; -//! Printer is a static class that allows printing to logs or stdout/stderr -class Printer { +// LCOV_EXCL_START +class OperatorState { public: - //! Print the object to stderr - static void Print(const string &str); - //! Prints Progress - static void PrintProgress(int percentage, const char *pbstr, int pbwidth); - //! Prints an empty line when progress bar is done - static void FinishProgressBarPrint(const char *pbstr, int pbwidth); -}; -} // namespace duckdb + virtual ~OperatorState() { + } + virtual void Finalize(PhysicalOperator *op, ExecutionContext &context) { + } +}; -namespace duckdb { -//! SQLStatement is the base class of any type of SQL statement. -class SQLStatement { +class GlobalSinkState { public: - explicit SQLStatement(StatementType type) : type(type) {}; - virtual ~SQLStatement() { + GlobalSinkState() : state(SinkFinalizeType::READY) { + } + virtual ~GlobalSinkState() { } - //! The statement type - StatementType type; - //! The statement location within the query string - idx_t stmt_location; - //! The statement length within the query string - idx_t stmt_length; - //! The number of prepared statement parameters (if any) - idx_t n_param; - //! The query text that corresponds to this SQL statement - string query; + SinkFinalizeType state; +}; +class LocalSinkState { public: - //! Create a copy of this SelectStatement - virtual unique_ptr Copy() const = 0; + virtual ~LocalSinkState() { + } }; -} // namespace duckdb - -namespace duckdb { +class GlobalSourceState { +public: + virtual ~GlobalSourceState() { + } -class ChunkCollection; -class ClientContext; -class DatabaseInstance; -class DuckDB; -class LogicalOperator; + virtual idx_t MaxThreads() { + return 1; + } +}; -typedef void (*warning_callback)(std::string); +class LocalSourceState { +public: + virtual ~LocalSourceState() { + } +}; +// LCOV_EXCL_STOP -//! A connection to a database. This represents a (client) connection that can -//! be used to query the database. -class Connection { +//! PhysicalOperator is the base class of the physical operators present in the +//! execution plan +class PhysicalOperator { public: - DUCKDB_API explicit Connection(DuckDB &database); - DUCKDB_API explicit Connection(DatabaseInstance &database); + PhysicalOperator(PhysicalOperatorType type, vector types, idx_t estimated_cardinality) + : type(type), types(std::move(types)), estimated_cardinality(estimated_cardinality) { + } + virtual ~PhysicalOperator() { + } - shared_ptr context; - warning_callback warning_cb; + //! The physical operator type + PhysicalOperatorType type; + //! The set of children of the operator + vector> children; + //! The types returned by this physical operator + vector types; + //! The estimated cardinality of this physical operator + idx_t estimated_cardinality; + //! The global sink state of this operator + unique_ptr sink_state; public: - //! Returns query profiling information for the current query - DUCKDB_API string GetProfilingInformation(ProfilerPrintFormat format = ProfilerPrintFormat::QUERY_TREE); + virtual string GetName() const; + virtual string ParamsToString() const { + return ""; + } + virtual string ToString() const; + void Print() const; - //! Interrupt execution of the current query - DUCKDB_API void Interrupt(); + //! Return a vector of the types that will be returned by this operator + const vector &GetTypes() const { + return types; + } - //! Enable query profiling - DUCKDB_API void EnableProfiling(); - //! Disable query profiling - DUCKDB_API void DisableProfiling(); + virtual bool Equals(const PhysicalOperator &other) const { + return false; + } - DUCKDB_API void SetWarningCallback(warning_callback); +public: + // Operator interface + virtual unique_ptr GetOperatorState(ClientContext &context) const; + virtual OperatorResultType Execute(ExecutionContext &context, DataChunk &input, DataChunk &chunk, + OperatorState &state) const; - //! 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(); + virtual bool ParallelOperator() const { + return false; + } - //! 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...); + virtual bool RequiresCache() const { + return false; } - //! 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); +public: + // Source interface + virtual unique_ptr GetLocalSourceState(ExecutionContext &context, + GlobalSourceState &gstate) const; + virtual unique_ptr GetGlobalSourceState(ClientContext &context) const; + virtual void GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate, + LocalSourceState &lstate) const; - //! 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); + virtual bool IsSource() const { + return false; + } - //! 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); + virtual bool ParallelSource() const { + return false; + } - //! Appends a DataChunk to the specified table - DUCKDB_API void Append(TableDescription &description, DataChunk &chunk); - //! Appends a ChunkCollection to the specified table - DUCKDB_API void Append(TableDescription &description, ChunkCollection &collection); +public: + // Sink interface - //! 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 unordered_map &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"); + //! The sink method is called constantly with new input, as long as new input is available. Note that this method + //! CAN be called in parallel, proper locking is needed when accessing data inside the GlobalSinkState. + virtual SinkResultType Sink(ExecutionContext &context, GlobalSinkState &gstate, LocalSinkState &lstate, + DataChunk &input) const; + // The combine is called when a single thread has completed execution of its part of the pipeline, it is the final + // time that a specific LocalSinkState is accessible. This method can be called in parallel while other Sink() or + // Combine() calls are active on the same GlobalSinkState. + virtual void Combine(ExecutionContext &context, GlobalSinkState &gstate, LocalSinkState &lstate) const; + //! The finalize is called when ALL threads are finished execution. It is called only once per pipeline, and is + //! entirely single threaded. + //! If Finalize returns SinkResultType::FINISHED, the sink is marked as finished + virtual SinkFinalizeType Finalize(Pipeline &pipeline, Event &event, ClientContext &context, + GlobalSinkState &gstate) const; - DUCKDB_API void BeginTransaction(); - DUCKDB_API void Commit(); - DUCKDB_API void Rollback(); - DUCKDB_API void SetAutoCommit(bool auto_commit); - DUCKDB_API bool IsAutoCommit(); + virtual unique_ptr GetLocalSinkState(ExecutionContext &context) const; + virtual unique_ptr GetGlobalSinkState(ClientContext &context) 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 bool IsSink() const { + return false; } - 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); + virtual bool ParallelSink() const { + return false; } - template - void CreateVectorizedFunction(const string &name, scalar_function_t udf_func, - LogicalType varargs = LogicalType::INVALID) { - UDFWrapper::RegisterFunction(name, udf_func, *context, move(varargs)); + virtual bool SinkOrderMatters() const { + return false; } +}; - 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)); - } +} // namespace duckdb - //------------------------------------- Aggreate Functions ----------------------------------------// - template - void CreateAggregateFunction(const string &name) { - AggregateFunction function = UDFWrapper::CreateAggregateFunction(name); - UDFWrapper::RegisterAggrFunction(function, *context); - } +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/function/table_function.hpp +// +// +//===----------------------------------------------------------------------===// - template - void CreateAggregateFunction(const string &name) { - AggregateFunction function = UDFWrapper::CreateAggregateFunction(name); - UDFWrapper::RegisterAggrFunction(function, *context); - } - 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); - } - 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); - } - 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); - } -private: - unique_ptr QueryParamsRecursive(const string &query, vector &values); +#include - 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 { +class BaseStatistics; +class LogicalGet; +struct ParallelState; +class TableFilterSet; + +struct FunctionOperatorData { + DUCKDB_API virtual ~FunctionOperatorData(); +}; + +struct TableFilterCollection { + DUCKDB_API explicit TableFilterCollection(TableFilterSet *table_filters); + + TableFilterSet *table_filters; +}; + +typedef unique_ptr (*table_function_bind_t)(ClientContext &context, vector &inputs, + named_parameter_map_t &named_parameters, + vector &input_table_types, + vector &input_table_names, + vector &return_types, vector &names); +typedef unique_ptr (*table_function_init_t)(ClientContext &context, const FunctionData *bind_data, + const vector &column_ids, + TableFilterCollection *filters); +typedef unique_ptr (*table_statistics_t)(ClientContext &context, const FunctionData *bind_data, + column_t column_index); +typedef void (*table_function_t)(ClientContext &context, const FunctionData *bind_data, + FunctionOperatorData *operator_state, DataChunk *input, DataChunk &output); + +typedef void (*table_function_parallel_t)(ClientContext &context, const FunctionData *bind_data, + FunctionOperatorData *operator_state, DataChunk *input, DataChunk &output, + ParallelState *parallel_state); + +typedef void (*table_function_cleanup_t)(ClientContext &context, const FunctionData *bind_data, + FunctionOperatorData *operator_state); +typedef idx_t (*table_function_max_threads_t)(ClientContext &context, const FunctionData *bind_data); +typedef unique_ptr (*table_function_init_parallel_state_t)(ClientContext &context, + const FunctionData *bind_data, + const vector &column_ids, + TableFilterCollection *filters); +typedef unique_ptr (*table_function_init_parallel_t)(ClientContext &context, + const FunctionData *bind_data, + ParallelState *state, + const vector &column_ids, + TableFilterCollection *filters); +typedef bool (*table_function_parallel_state_next_t)(ClientContext &context, const FunctionData *bind_data, + FunctionOperatorData *state, ParallelState *parallel_state); +typedef double (*table_function_progress_t)(ClientContext &context, const FunctionData *bind_data); +typedef void (*table_function_dependency_t)(unordered_set &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, + FunctionData *bind_data, + vector> &filters); +typedef string (*table_function_to_string_t)(const FunctionData *bind_data); + +class TableFunction : public SimpleNamedParameterFunction { +public: + DUCKDB_API + TableFunction(string name, vector arguments, table_function_t function, + table_function_bind_t bind = nullptr, table_function_init_t init = nullptr, + table_statistics_t statistics = nullptr, table_function_cleanup_t cleanup = nullptr, + table_function_dependency_t dependency = nullptr, table_function_cardinality_t cardinality = nullptr, + table_function_pushdown_complex_filter_t pushdown_complex_filter = nullptr, + table_function_to_string_t to_string = nullptr, table_function_max_threads_t max_threads = nullptr, + table_function_init_parallel_state_t init_parallel_state = nullptr, + table_function_parallel_t parallel_function = nullptr, + table_function_init_parallel_t parallel_init = nullptr, + table_function_parallel_state_next_t parallel_state_next = nullptr, bool projection_pushdown = false, + bool filter_pushdown = false, table_function_progress_t query_progress = nullptr); + DUCKDB_API + TableFunction(const vector &arguments, table_function_t function, table_function_bind_t bind = nullptr, + table_function_init_t init = nullptr, table_statistics_t statistics = nullptr, + table_function_cleanup_t cleanup = nullptr, table_function_dependency_t dependency = nullptr, + table_function_cardinality_t cardinality = nullptr, + table_function_pushdown_complex_filter_t pushdown_complex_filter = nullptr, + table_function_to_string_t to_string = nullptr, table_function_max_threads_t max_threads = nullptr, + table_function_init_parallel_state_t init_parallel_state = nullptr, + table_function_parallel_t parallel_function = nullptr, + table_function_init_parallel_t parallel_init = nullptr, + table_function_parallel_state_next_t parallel_state_next = nullptr, bool projection_pushdown = false, + bool filter_pushdown = false, table_function_progress_t query_progress = nullptr); + DUCKDB_API TableFunction(); + + //! Bind function + //! This function is used for determining the return type of a table producing function and returning bind data + //! The returned FunctionData object should be constant and should not be changed during execution. + table_function_bind_t bind; + //! (Optional) init function + //! Initialize the operator state of the function. The operator state is used to keep track of the progress in the + //! table function. + table_function_init_t init; + //! The main function + table_function_t function; + //! (Optional) statistics function + //! Returns the statistics of a specified column + table_statistics_t statistics; + //! (Optional) cleanup function + //! The final cleanup function, called after all data is exhausted from the main function + table_function_cleanup_t cleanup; + //! (Optional) dependency function + //! Sets up which catalog entries this table function depend on + table_function_dependency_t dependency; + //! (Optional) cardinality function + //! Returns the expected cardinality of this scan + table_function_cardinality_t cardinality; + //! (Optional) pushdown a set of arbitrary filter expressions, rather than only simple comparisons with a constant + //! Any functions remaining in the expression list will be pushed as a regular filter after the scan + table_function_pushdown_complex_filter_t pushdown_complex_filter; + //! (Optional) function for rendering the operator to a string in profiling output + table_function_to_string_t to_string; + //! (Optional) function that returns the maximum amount of threads that can work on this task + table_function_max_threads_t max_threads; + //! (Optional) initialize the parallel scan state, called once in total. + table_function_init_parallel_state_t init_parallel_state; + //! (Optional) Parallel version of the main function + table_function_parallel_t parallel_function; + //! (Optional) initialize the parallel scan given the parallel state. Called once per task. Return nullptr if there + //! is nothing left to scan. + table_function_init_parallel_t parallel_init; + //! (Optional) return the next chunk to process in the parallel scan, or return nullptr if there is none + table_function_parallel_state_next_t parallel_state_next; + //! (Optional) return how much of the table we have scanned up to this point (% of the data) + table_function_progress_t table_scan_progress; + //! Whether or not the table function supports projection pushdown. If not supported a projection will be added + //! that filters out unused columns. + bool projection_pushdown; + //! Whether or not the table function supports filter pushdown. If not supported a filter will be added + //! that applies the table filter directly. + bool filter_pushdown; }; } // namespace duckdb + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/main/database.hpp +// duckdb/parallel/parallel_state.hpp // // //===----------------------------------------------------------------------===// +namespace duckdb { + +struct ParallelState { + virtual ~ParallelState() { + } +}; +} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/main/config.hpp +// duckdb/parallel/task_scheduler.hpp // // //===----------------------------------------------------------------------===// + + + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/allocator.hpp +// duckdb/parallel/task.hpp // // //===----------------------------------------------------------------------===// @@ -9712,474 +10216,371 @@ class Connection { namespace duckdb { -class Allocator; class ClientContext; -class DatabaseInstance; +class Executor; -struct PrivateAllocatorData { - virtual ~PrivateAllocatorData() { - } -}; +enum class TaskExecutionMode : uint8_t { PROCESS_ALL, PROCESS_PARTIAL }; -typedef data_ptr_t (*allocate_function_ptr_t)(PrivateAllocatorData *private_data, idx_t size); -typedef void (*free_function_ptr_t)(PrivateAllocatorData *private_data, data_ptr_t pointer, idx_t size); -typedef data_ptr_t (*reallocate_function_ptr_t)(PrivateAllocatorData *private_data, data_ptr_t pointer, idx_t size); +enum class TaskExecutionResult : uint8_t { TASK_FINISHED, TASK_NOT_FINISHED, TASK_ERROR }; -class AllocatedData { +//! Generic parallel task +class Task { public: - AllocatedData(Allocator &allocator, data_ptr_t pointer, idx_t allocated_size); - ~AllocatedData(); - - data_ptr_t get() { - return pointer; - } - const_data_ptr_t get() const { - return pointer; - } - idx_t GetSize() const { - return allocated_size; + virtual ~Task() { } - void Reset(); -private: - Allocator &allocator; - data_ptr_t pointer; - idx_t allocated_size; + //! Execute the task in the specified execution mode + //! If mode is PROCESS_ALL, Execute should always finish processing and return TASK_FINISHED + //! If mode is PROCESS_PARTIAL, Execute can return TASK_NOT_FINISHED, in which case Execute will be called again + //! In case of an error, TASK_ERROR is returned + virtual TaskExecutionResult Execute(TaskExecutionMode mode) = 0; }; -class Allocator { +//! Execute a task within an executor, including exception handling +//! This should be used within queries +class ExecutorTask : public Task { public: - 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); + ExecutorTask(Executor &executor); + ExecutorTask(ClientContext &context); + virtual ~ExecutorTask(); - data_ptr_t AllocateData(idx_t size); - void FreeData(data_ptr_t pointer, idx_t size); - data_ptr_t ReallocateData(data_ptr_t pointer, idx_t size); + Executor &executor; - unique_ptr Allocate(idx_t size) { - return make_unique(*this, AllocateData(size), size); - } +public: + virtual TaskExecutionResult ExecuteTask(TaskExecutionMode mode) = 0; + TaskExecutionResult Execute(TaskExecutionMode mode) override; +}; - static data_ptr_t DefaultAllocate(PrivateAllocatorData *private_data, idx_t size) { - return (data_ptr_t)malloc(size); - } - static void DefaultFree(PrivateAllocatorData *private_data, data_ptr_t pointer, idx_t size) { - free(pointer); - } - static data_ptr_t DefaultReallocate(PrivateAllocatorData *private_data, data_ptr_t pointer, idx_t size) { - return (data_ptr_t)realloc(pointer, size); - } - static Allocator &Get(ClientContext &context); - static Allocator &Get(DatabaseInstance &db); +} // namespace duckdb - PrivateAllocatorData *GetPrivateData() { - return private_data.get(); - } -private: - allocate_function_ptr_t allocate_function; - free_function_ptr_t free_function; - reallocate_function_ptr_t reallocate_function; - unique_ptr private_data; -}; +namespace duckdb { -} // namespace duckdb +struct ConcurrentQueue; +struct QueueProducerToken; +class ClientContext; +class DatabaseInstance; +class TaskScheduler; -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/case_insensitive_map.hpp -// -// -//===----------------------------------------------------------------------===// +struct SchedulerThread; +struct ProducerToken { + ProducerToken(TaskScheduler &scheduler, unique_ptr token); + ~ProducerToken(); + TaskScheduler &scheduler; + unique_ptr token; + mutex producer_lock; +}; +//! The TaskScheduler is responsible for managing tasks and threads +class TaskScheduler { + // timeout for semaphore wait, default 50ms + constexpr static int64_t TASK_TIMEOUT_USECS = 50000; +public: + TaskScheduler(); + ~TaskScheduler(); + static TaskScheduler &GetScheduler(ClientContext &context); + static TaskScheduler &GetScheduler(DatabaseInstance &db); -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/string_util.hpp -// -// -//===----------------------------------------------------------------------===// + unique_ptr CreateProducer(); + //! Schedule a task to be executed by the task scheduler + void ScheduleTask(ProducerToken &producer, unique_ptr task); + //! Fetches a task from a specific producer, returns true if successful or false if no tasks were available + bool GetTaskFromProducer(ProducerToken &token, unique_ptr &task); + //! Run tasks forever until "marker" is set to false, "marker" must remain valid until the thread is joined + void ExecuteForever(atomic *marker); + //! Sets the amount of active threads executing tasks for the system; n-1 background threads will be launched. + //! The main thread will also be used for execution + void SetThreads(int32_t n); + //! Returns the number of threads + int32_t NumberOfThreads(); +private: + void SetThreadsInternal(int32_t n); + //! The task queue + unique_ptr queue; + //! The active background threads of the task scheduler + vector> threads; + //! Markers used by the various threads, if the markers are set to "false" the thread execution is stopped + vector>> markers; +}; +} // 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: - static bool CharacterIsSpace(char c) { - return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; - } - static bool CharacterIsNewline(char c) { - return c == '\n' || c == '\r'; - } - static bool CharacterIsDigit(char c) { - return c >= '0' && c <= '9'; - } - static char CharacterToLower(char c) { - if (c >= 'A' && c <= 'Z') { - return c - ('A' - 'a'); - } - return c; - } - - //! Returns true if the needle string exists in the haystack - static bool Contains(const string &haystack, const string &needle); - - //! Returns true if the target string starts with the given prefix - static bool StartsWith(string str, string prefix); - - //! Returns true if the target string ends with the given suffix. - static bool EndsWith(const string &str, const string &suffix); - - //! Repeat a string multiple times - static string Repeat(const string &str, const idx_t n); +class Executor; +class Event; - //! Split the input string based on newline char - static vector Split(const string &str, char delimiter); +//! The Pipeline class represents an execution pipeline +class Pipeline : public std::enable_shared_from_this { + friend class Executor; + friend class PipelineExecutor; + friend class PipelineEvent; + friend class PipelineFinishEvent; - //! Split the input string allong a quote. Note that any escaping is NOT supported. - static vector SplitWithQuote(const string &str, char delimiter = ',', char quote = '"'); +public: + Pipeline(Executor &execution_context); - //! Join multiple strings into one string. Components are concatenated by the given separator - static string Join(const vector &input, const string &separator); + Executor &executor; - //! 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; +public: + ClientContext &GetClientContext(); - // 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]); - } + void AddDependency(shared_ptr &pipeline); - // Append the remaining input components, after the first - for (size_t i = 1; i < count; i++) { - result += separator + f(input[i]); - } + void Ready(); + void Reset(); + void ResetSource(); + void Schedule(shared_ptr &event); - return result; - } + //! Finalize this pipeline + void Finalize(Event &event); - //! Return a string that formats the give number of bytes - static string BytesToHumanReadableString(idx_t bytes); + string ToString() const; + void Print() const; - //! Convert a string to uppercase - static string Upper(const string &str); + //! Returns query progress + bool GetProgress(double ¤t_percentage); - //! Convert a string to lowercase - static string Lower(const string &str); + //! Returns a list of all operators (including source and sink) involved in this pipeline + vector GetOperators() const; - //! Format a string using printf semantics - template - static string Format(const string fmt_str, Args... params) { - return Exception::ConstructMessage(fmt_str, params...); + PhysicalOperator *GetSink() { + return sink; } - //! Split the input string into a vector of strings based on the split string - static vector Split(const string &input, const string &split); - - //! Remove the whitespace char in the left end of the string - static void LTrim(string &str); - //! Remove the whitespace char in the right end of the string - static void RTrim(string &str); - //! Remove the whitespace char in the left and right end of the string - static void Trim(string &str); - - static string Replace(string source, const string &from, const string &to); - - //! Get the levenshtein distance from two strings - 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. - 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. - static vector TopNLevenshtein(const vector &strings, const string &target, idx_t n = 5, - idx_t threshold = 5); - static string CandidatesMessage(const vector &candidates, const string &candidate = "Candidate bindings"); -}; -} // namespace duckdb +private: + //! Whether or not the pipeline has been readied + bool ready; + //! The source of this pipeline + PhysicalOperator *source; + //! The chain of intermediate operators + vector operators; + //! The sink (i.e. destination) for data; this is e.g. a hash table to-be-built + PhysicalOperator *sink; + //! The global source state + unique_ptr source_state; -namespace duckdb { + //! The parent pipelines (i.e. pipelines that are dependent on this pipeline to finish) + vector> parents; + //! The dependencies of this pipeline + vector> dependencies; -struct CaseInsensitiveStringHashFunction { - uint64_t operator()(const string &str) const { - std::hash hasher; - return hasher(StringUtil::Lower(str)); - } -}; +private: + bool GetProgressInternal(ClientContext &context, PhysicalOperator *op, double ¤t_percentage); + void ScheduleSequentialTask(shared_ptr &event); + bool LaunchScanTasks(shared_ptr &event, idx_t max_threads); -struct CaseInsensitiveStringEquality { - bool operator()(const string &a, const string &b) const { - return StringUtil::Lower(a) == StringUtil::Lower(b); - } + bool ScheduleParallel(shared_ptr &event); }; -template -using case_insensitive_map_t = - unordered_map; - -using case_insensitive_set_t = unordered_set; - } // namespace duckdb - - - - - //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/function/replacement_scan.hpp +// duckdb/common/pair.hpp // // //===----------------------------------------------------------------------===// +#include + +namespace duckdb { +using std::make_pair; +using std::pair; +} // namespace duckdb + namespace duckdb { +class ClientContext; +class DataChunk; +class PhysicalOperator; +class PipelineExecutor; +class OperatorState; +class QueryProfiler; +class ThreadContext; +class Task; -class TableFunctionRef; +struct PipelineEventStack; +struct ProducerToken; -typedef unique_ptr (*replacement_scan_t)(const string &table_name, void *data); +using event_map_t = unordered_map; -//! 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, void *data = nullptr) : function(function), data(data) { - } +class Executor { + friend class Pipeline; + friend class PipelineTask; - replacement_scan_t function; - void *data; -}; +public: + explicit Executor(ClientContext &context); + ~Executor(); -} // namespace duckdb + ClientContext &context; -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/set.hpp -// -// -//===----------------------------------------------------------------------===// +public: + static Executor &Get(ClientContext &context); + void Initialize(PhysicalOperator *physical_plan); + void BuildPipelines(PhysicalOperator *op, Pipeline *current); + void CancelTasks(); + PendingExecutionResult ExecuteTask(); -#include + void Reset(); -namespace duckdb { -using std::set; -} + vector GetTypes(); + unique_ptr FetchChunk(); -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/enums/optimizer_type.hpp -// -// -//===----------------------------------------------------------------------===// + //! Push a new error + void PushError(ExceptionType type, const string &exception); + //! True if an error has been thrown + bool HasError(); + //! Throw the exception that was pushed using PushError. + //! Should only be called if HasError returns true + void ThrowException(); + //! Work on tasks for this specific executor, until there are no tasks remaining + void WorkOnTasks(); + //! Flush a thread context into the client context + void Flush(ThreadContext &context); + //! Returns the progress of the pipelines + bool GetPipelinesProgress(double ¤t_progress); + void CompletePipeline() { + completed_pipelines++; + } + ProducerToken &GetToken() { + return *producer; + } + void AddEvent(shared_ptr event); -namespace duckdb { + void ReschedulePipelines(const vector> &pipelines, vector> &events); -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 -}; +private: + void ScheduleEvents(); + void ScheduleEventsInternal(const vector> &pipelines, + unordered_map>> &child_pipelines, + vector> &events, bool main_schedule = true); -string OptimizerTypeToString(OptimizerType type); + void SchedulePipeline(const shared_ptr &pipeline, event_map_t &event_map, + vector> &events, bool complete_pipeline); + Pipeline *ScheduleUnionPipeline(const shared_ptr &pipeline, const Pipeline *parent, + event_map_t &event_map, vector> &events); + void ScheduleChildPipeline(Pipeline *parent, const shared_ptr &pipeline, event_map_t &event_map, + vector> &events); + void ExtractPipelines(shared_ptr &pipeline, vector> &result); + bool NextExecutor(); -} // namespace duckdb + void AddChildPipeline(Pipeline *current); -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/enums/window_aggregation_mode.hpp -// -// -//===----------------------------------------------------------------------===// + void VerifyPipeline(Pipeline &pipeline); + void VerifyPipelines(); + void ThrowExceptionInternal(); + +private: + PhysicalOperator *physical_plan; + mutex executor_lock; + //! The pipelines of the current query + vector> pipelines; + //! The root pipeline of the query + vector> root_pipelines; + //! The pipeline executor for the root pipeline + unique_ptr root_executor; + //! The current root pipeline index + idx_t root_pipeline_idx; + //! The producer of this query + unique_ptr producer; + //! Exceptions that occurred during the execution of the current query + vector> exceptions; + //! List of events + vector> events; + //! The query profiler + shared_ptr profiler; + //! The amount of completed pipelines of the query + atomic completed_pipelines; + //! The total amount of pipelines in the query + idx_t total_pipelines; + //! The adjacent union pipelines of each pipeline + //! Union pipelines have the same sink, but can be run concurrently along with this pipeline + unordered_map>> union_pipelines; + //! Child pipelines of this pipeline + //! Like union pipelines, child pipelines share the same sink + //! Unlike union pipelines, child pipelines should be run AFTER their dependencies are completed + //! i.e. they should be run after the dependencies are completed, but before finalize is called on the sink + unordered_map>> child_pipelines; + //! Dependencies of child pipelines + unordered_map> child_dependencies; + //! Duplicate eliminated join scan dependencies + unordered_map delim_join_dependencies; -namespace duckdb { + //! Active recursive CTE node (if any) + PhysicalOperator *recursive_cte; -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 + //! The last pending execution result (if any) + PendingExecutionResult execution_result; + //! The current task in process (if any) + unique_ptr task; }; - } // namespace duckdb namespace duckdb { class ClientContext; -class TableFunctionRef; -class CompressionFunction; - -struct CompressionFunctionSet; - -enum class AccessMode : uint8_t { UNDEFINED = 0, AUTOMATIC = 1, READ_ONLY = 2, READ_WRITE = 3 }; - -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 -}; - -enum class ConfigurationOptionType : uint32_t { - INVALID = 0, - ACCESS_MODE, - DEFAULT_ORDER_TYPE, - DEFAULT_NULL_ORDER, - ENABLE_EXTERNAL_ACCESS, - ENABLE_OBJECT_CACHE, - MAXIMUM_MEMORY, - THREADS -}; - -struct ConfigurationOption { - ConfigurationOptionType type; - const char *name; - const char *description; - LogicalTypeId parameter_type; -}; +class ClientContextLock; +class PreparedStatementData; -// this is optional and only used in tests at the moment -struct DBConfig { - friend class DatabaseInstance; - friend class StorageManager; +class PendingQueryResult : public BaseQueryResult { + friend class ClientContext; public: - DUCKDB_API DBConfig(); - DUCKDB_API ~DBConfig(); - - //! Access mode of the database (AUTOMATIC, READ_ONLY or READ_WRITE) - AccessMode access_mode = AccessMode::AUTOMATIC; - //! The allocator used by the system - Allocator allocator; - // 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 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 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; - //! 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; - //! Database configuration variables as controlled by SET - case_insensitive_map_t set_variables; - //! 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; - //! Replacement table scans are automatically attempted when a table name cannot be found in the schema - vector replacement_scans; - //! 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 flag that adds additional (unnecessary) free_list blocks to the storage - bool debug_many_free_list_blocks = false; - //! Debug setting for window aggregation mode: (window, combine, separate) - WindowAggregationMode window_mode = WindowAggregationMode::WINDOW; + DUCKDB_API PendingQueryResult(shared_ptr context, PreparedStatementData &statement, + vector types); + DUCKDB_API explicit PendingQueryResult(string error_message); + DUCKDB_API ~PendingQueryResult(); public: - DUCKDB_API static DBConfig &GetConfig(ClientContext &context); - DUCKDB_API static DBConfig &GetConfig(DatabaseInstance &db); - DUCKDB_API static vector GetOptions(); - DUCKDB_API static idx_t GetOptionCount(); + //! Executes a single task within the query, returning whether or not the query is ready. + //! If this returns RESULT_READY, the Execute function can be called to obtain a pointer to the result. + //! If this returns RESULT_NOT_READY, the ExecuteTask function should be called again. + //! If this returns EXECUTION_ERROR, an error occurred during execution. + //! The error message can be obtained by calling GetError() on the PendingQueryResult. + DUCKDB_API PendingExecutionResult ExecuteTask(); - //! 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 result of the query as an actual query result. + //! This returns (mostly) instantly if ExecuteTask has been called until RESULT_READY was returned. + DUCKDB_API unique_ptr Execute(bool allow_streaming_result = false); - DUCKDB_API void SetOption(const ConfigurationOption &option, const Value &value); - - DUCKDB_API static idx_t ParseMemoryLimit(const string &arg); + DUCKDB_API void Close(); - //! 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); +private: + shared_ptr context; private: - unique_ptr compression_functions; + void CheckExecutableInternal(ClientContextLock &lock); + + PendingExecutionResult ExecuteTaskInternal(ClientContextLock &lock); + unique_ptr ExecuteInternal(ClientContextLock &lock, bool allow_streaming_result = false); + unique_ptr LockContext(); }; } // namespace duckdb @@ -10187,7 +10588,7 @@ struct DBConfig { //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/main/extension.hpp +// duckdb/main/prepared_statement.hpp // // //===----------------------------------------------------------------------===// @@ -10197,1184 +10598,3995 @@ struct DBConfig { -namespace duckdb { -class DuckDB; - -//! The Extension class is the base class used to define extensions -class Extension { -public: - DUCKDB_API virtual void Load(DuckDB &db) = 0; - DUCKDB_API virtual ~Extension() = default; -}; - -} // 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; +class ClientContext; +class PreparedStatementData; +//! A prepared statement +class PreparedStatement { public: - DUCKDB_API DatabaseInstance(); - DUCKDB_API ~DatabaseInstance(); + //! 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); + //! Create a prepared statement that was not successfully prepared + DUCKDB_API explicit PreparedStatement(string error); - DBConfig config; + DUCKDB_API ~PreparedStatement(); public: - StorageManager &GetStorageManager(); - Catalog &GetCatalog(); - FileSystem &GetFileSystem(); - TransactionManager &GetTransactionManager(); - TaskScheduler &GetScheduler(); - ObjectCache &GetObjectCache(); - ConnectionManager &GetConnectionManager(); - - idx_t NumberOfThreads(); - - static DatabaseInstance &GetDatabase(ClientContext &context); - -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; -}; + //! The client context this prepared statement belongs to + shared_ptr context; + //! The prepared statement data + shared_ptr data; + //! The query that is being prepared + string query; + //! Whether or not the statement was successfully prepared + bool success; + //! The error message (if success = false) + string error; + //! The amount of bound parameters + idx_t n_param; -//! 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 ~DuckDB(); + //! Returns the number of columns in the result + idx_t ColumnCount(); + //! Returns the statement type of the underlying prepared statement object + StatementType GetStatementType(); + //! Returns the result SQL types of the prepared statement + const vector &GetTypes(); + //! Returns the result names of the prepared statement + const vector &GetNames(); - //! Reference to the actual database instance - shared_ptr instance; + //! Create a pending query result of the prepared statement with the given set of arguments + template + unique_ptr PendingQuery(Args... args) { + vector values; + return PendingQueryRecursive(values, args...); + } -public: - template - void LoadExtension() { - T extension; - extension.Load(*this); + //! Execute the prepared statement with the given set of arguments + template + unique_ptr Execute(Args... args) { + vector values; + return ExecuteRecursive(values, args...); } - DUCKDB_API FileSystem &GetFileSystem(); + //! Create a pending query result of the prepared statement with the given set of arguments + DUCKDB_API unique_ptr PendingQuery(vector &values); - DUCKDB_API idx_t NumberOfThreads(); - DUCKDB_API static const char *SourceID(); - DUCKDB_API static const char *LibraryVersion(); -}; + //! Execute the prepared statement with the given set of values + DUCKDB_API unique_ptr Execute(vector &values, bool allow_stream_result = true); -} // namespace duckdb +private: + unique_ptr PendingQueryRecursive(vector &values) { + return PendingQuery(values); + } + template + unique_ptr PendingQueryRecursive(vector &values, T value, Args... args) { + values.push_back(Value::CreateValue(value)); + return PendingQueryRecursive(values, args...); + } + unique_ptr ExecuteRecursive(vector &values) { + return Execute(values); + } + template + unique_ptr ExecuteRecursive(vector &values, T value, Args... args) { + values.push_back(Value::CreateValue(value)); + return ExecuteRecursive(values, args...); + } +}; -#ifdef DUCKDB_BUILD_LOADABLE_EXTENSION -#ifdef _WIN32 -#include -#include +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/relation.hpp +// +// +//===----------------------------------------------------------------------===// -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 triggerd 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 -*/ -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; - } - return NULL; -} -ExternC const PfnDliHook __pfnDliNotifyHook2 = duckdb_dllimport_delay_hook; -ExternC const PfnDliHook __pfnDliFailureHook2 = duckdb_dllimport_delay_hook; -} -#endif -#endif //===----------------------------------------------------------------------===// -// // DuckDB // -// duckdb.h +// duckdb/common/enums/join_type.hpp // // //===----------------------------------------------------------------------===// -#ifdef _WIN32 -#ifdef DUCKDB_BUILD_LIBRARY -#define DUCKDB_API __declspec(dllexport) -#else -#define DUCKDB_API __declspec(dllimport) -#endif -#else -#define DUCKDB_API -#endif -#include -#include -#include -#ifdef __cplusplus -extern "C" { -#endif +namespace duckdb { //===--------------------------------------------------------------------===// -// Type Information +// Join Types //===--------------------------------------------------------------------===// -typedef uint64_t idx_t; +enum class JoinType : uint8_t { + INVALID = 0, // invalid join type + LEFT = 1, // left + RIGHT = 2, // right + INNER = 3, // inner + OUTER = 4, // outer + SEMI = 5, // SEMI join returns left side row ONLY if it has a join partner, no duplicates + ANTI = 6, // ANTI join returns left side row ONLY if it has NO join partner, no duplicates + MARK = 7, // MARK join returns marker indicating whether or not there is a join partner (true), there is no join + // partner (false) + SINGLE = 8 // SINGLE join is like LEFT OUTER JOIN, BUT returns at most one join partner per entry on the LEFT side + // (and NULL if no partner is found) +}; -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 - 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 -} duckdb_type; +//! Convert join type to string +string JoinTypeToString(JoinType 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; +//! True if join is left or full outer join +bool IsLeftOuterJoin(JoinType type); -typedef struct { - int32_t year; - int8_t month; - int8_t day; -} duckdb_date_struct; +//! True if join is rght or full outer join +bool IsRightOuterJoin(JoinType type); -//! 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 -typedef struct { - int8_t hour; - int8_t min; - int8_t sec; - int32_t micros; -} duckdb_time_struct; +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/relation_type.hpp +// +// +//===----------------------------------------------------------------------===// -//! 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; -typedef struct { - duckdb_date_struct date; - duckdb_time_struct time; -} duckdb_timestamp_struct; -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 { - void *data; - idx_t size; -} duckdb_blob; +namespace duckdb { -typedef struct { - void *data; - bool *nullmask; - duckdb_type type; - char *name; +//===--------------------------------------------------------------------===// +// Catalog Types +//===--------------------------------------------------------------------===// +enum class RelationType : uint8_t { + INVALID_RELATION, + TABLE_RELATION, + PROJECTION_RELATION, + FILTER_RELATION, + EXPLAIN_RELATION, + CROSS_PRODUCT_RELATION, + JOIN_RELATION, + AGGREGATE_RELATION, + SET_OPERATION_RELATION, + DISTINCT_RELATION, + LIMIT_RELATION, + ORDER_RELATION, + CREATE_VIEW_RELATION, + CREATE_TABLE_RELATION, + INSERT_RELATION, + VALUE_LIST_RELATION, + DELETE_RELATION, + UPDATE_RELATION, + WRITE_CSV_RELATION, + READ_CSV_RELATION, + SUBQUERY_RELATION, + TABLE_FUNCTION_RELATION, + VIEW_RELATION, + QUERY_RELATION +}; + +string RelationTypeToString(RelationType type); + +} // namespace duckdb + + + + + + +#include + +namespace duckdb { +struct BoundStatement; + +class ClientContext; +class Binder; +class LogicalOperator; +class QueryNode; +class TableRef; + +class Relation : public std::enable_shared_from_this { +public: + DUCKDB_API Relation(ClientContext &context, RelationType type) : context(context), type(type) { + } + DUCKDB_API virtual ~Relation() { + } + + ClientContext &context; + RelationType type; + +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(); + + DUCKDB_API unique_ptr Execute(); + DUCKDB_API string ToString(); + DUCKDB_API virtual string ToString(idx_t depth) = 0; + + DUCKDB_API void Print(); + DUCKDB_API void Head(idx_t limit = 10); + + DUCKDB_API shared_ptr CreateView(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); + + //! Explain the query plan of this relation + DUCKDB_API unique_ptr Explain(); + + DUCKDB_API virtual unique_ptr GetTableRef(); + DUCKDB_API virtual bool IsReadOnly() { + return true; + } + +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); + + // 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(); + + // 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); + + // ALIAS + DUCKDB_API shared_ptr Alias(const string &alias); + + //! 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); + + //! Write a relation to a CSV file + DUCKDB_API void WriteCSV(const string &csv_file); + + //! 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: + //! 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; + } + +protected: + DUCKDB_API string RenderWhitespace(idx_t depth); +}; + +} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/stream_query_result.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { + +class ClientContext; +class ClientContextLock; +class Executor; +class MaterializedQueryResult; +class PreparedStatementData; + +class StreamQueryResult : public QueryResult { + friend class ClientContext; + +public: + //! Create a successful StreamQueryResult. StreamQueryResults should always be successful initially (it makes no + //! sense to stream an error). + DUCKDB_API StreamQueryResult(StatementType statement_type, shared_ptr context, + vector types, vector names); + DUCKDB_API ~StreamQueryResult() override; + +public: + //! Fetches a DataChunk from the query result. + DUCKDB_API unique_ptr FetchRaw() override; + //! Converts the QueryResult to a string + DUCKDB_API string ToString() override; + //! Materializes the query result and turns it into a materialized query result + DUCKDB_API unique_ptr Materialize(); + + DUCKDB_API bool IsOpen(); + + //! Closes the StreamQueryResult + DUCKDB_API void Close(); + +private: + //! The client context this StreamQueryResult belongs to + shared_ptr context; + +private: + unique_ptr LockContext(); + void CheckExecutableInternal(ClientContextLock &lock); + bool IsOpenInternal(ClientContextLock &lock); +}; + +} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/table_description.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +struct TableDescription { + //! The schema of the table + string schema; + //! The table name of the table + string table; + //! The columns of the table + vector columns; +}; + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/sql_statement.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/printer.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +//! Printer is a static class that allows printing to logs or stdout/stderr +class Printer { +public: + //! Print the object to stderr + DUCKDB_API static void Print(const string &str); + //! Prints Progress + DUCKDB_API static void PrintProgress(int percentage, const char *pbstr, int pbwidth); + //! Prints an empty line when progress bar is done + DUCKDB_API static void FinishProgressBarPrint(const char *pbstr, int pbwidth); + //! Whether or not we are printing to a terminal + DUCKDB_API static bool IsTerminal(); +}; +} // namespace duckdb + + +namespace duckdb { +//! 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; + //! The statement length within the query string + idx_t stmt_length; + //! The number of prepared statement parameters (if any) + idx_t n_param; + //! The query text that corresponds to this SQL statement + string query; + +protected: + SQLStatement(const SQLStatement &other) = default; + +public: + //! Create a copy of this SelectStatement + virtual unique_ptr Copy() const = 0; +}; +} // namespace duckdb + + +namespace duckdb { + +class ChunkCollection; +class ClientContext; +class DatabaseInstance; +class DuckDB; +class LogicalOperator; +class SelectStatement; + +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); + + 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(); + + //! 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...); + } + + //! 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); + //! Issues a query to the database and returns a Pending Query Result + DUCKDB_API unique_ptr PendingQuery(unique_ptr statement); + + //! 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); + + //! 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); + + //! 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); + + //! Appends a DataChunk to the specified table + DUCKDB_API void Append(TableDescription &description, DataChunk &chunk); + //! Appends a ChunkCollection to the specified table + DUCKDB_API void Append(TableDescription &description, ChunkCollection &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"); + //! 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, string alias = "queryrelation", + const string &error = "Expected a single SELECT statement"); + DUCKDB_API shared_ptr RelationFromQuery(unique_ptr select_stmt, + string alias = "queryrelation"); + + DUCKDB_API void BeginTransaction(); + DUCKDB_API void Commit(); + DUCKDB_API void Rollback(); + DUCKDB_API void SetAutoCommit(bool auto_commit); + DUCKDB_API bool IsAutoCommit(); + + //! Fetch a list of table names that are required for a given query + DUCKDB_API unordered_set GetTableNames(const string &query); + + template + void CreateScalarFunction(const string &name, TR (*udf_func)(Args...)) { + scalar_function_t function = UDFWrapper::CreateScalarFunction(name, udf_func); + UDFWrapper::RegisterFunction(name, function, *context); + } + + 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); + } + + template + void CreateVectorizedFunction(const string &name, scalar_function_t udf_func, + LogicalType varargs = LogicalType::INVALID) { + UDFWrapper::RegisterFunction(name, udf_func, *context, move(varargs)); + } + + 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)); + } + + //------------------------------------- Aggreate Functions ----------------------------------------// + template + void CreateAggregateFunction(const string &name) { + AggregateFunction function = UDFWrapper::CreateAggregateFunction(name); + UDFWrapper::RegisterAggrFunction(function, *context); + } + + template + void CreateAggregateFunction(const string &name) { + AggregateFunction function = UDFWrapper::CreateAggregateFunction(name); + UDFWrapper::RegisterAggrFunction(function, *context); + } + + 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); + } + + 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); + } + + 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); + } + +private: + unique_ptr QueryParamsRecursive(const string &query, vector &values); + + 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 +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/database.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/config.hpp +// +// +//===----------------------------------------------------------------------===// + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/allocator.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { +class Allocator; +class ClientContext; +class DatabaseInstance; + +struct PrivateAllocatorData { + virtual ~PrivateAllocatorData() { + } +}; + +typedef data_ptr_t (*allocate_function_ptr_t)(PrivateAllocatorData *private_data, idx_t size); +typedef void (*free_function_ptr_t)(PrivateAllocatorData *private_data, data_ptr_t pointer, idx_t size); +typedef data_ptr_t (*reallocate_function_ptr_t)(PrivateAllocatorData *private_data, data_ptr_t pointer, idx_t size); + +class AllocatedData { +public: + AllocatedData(Allocator &allocator, data_ptr_t pointer, idx_t allocated_size); + ~AllocatedData(); + + data_ptr_t get() { + return pointer; + } + const_data_ptr_t get() const { + return pointer; + } + idx_t GetSize() const { + return allocated_size; + } + void Reset(); + +private: + Allocator &allocator; + data_ptr_t pointer; + idx_t allocated_size; +}; + +class Allocator { +public: + 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); + + data_ptr_t AllocateData(idx_t size); + void FreeData(data_ptr_t pointer, idx_t size); + data_ptr_t ReallocateData(data_ptr_t pointer, idx_t size); + + unique_ptr Allocate(idx_t size) { + return make_unique(*this, AllocateData(size), size); + } + + static data_ptr_t DefaultAllocate(PrivateAllocatorData *private_data, idx_t size) { + return (data_ptr_t)malloc(size); + } + static void DefaultFree(PrivateAllocatorData *private_data, data_ptr_t pointer, idx_t size) { + free(pointer); + } + static data_ptr_t DefaultReallocate(PrivateAllocatorData *private_data, data_ptr_t pointer, idx_t size) { + return (data_ptr_t)realloc(pointer, size); + } + static Allocator &Get(ClientContext &context); + static Allocator &Get(DatabaseInstance &db); + + PrivateAllocatorData *GetPrivateData() { + return private_data.get(); + } + +private: + allocate_function_ptr_t allocate_function; + free_function_ptr_t free_function; + reallocate_function_ptr_t reallocate_function; + + unique_ptr private_data; +}; + +} // namespace duckdb + + + + + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/function/replacement_scan.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +class TableFunctionRef; + +typedef unique_ptr (*replacement_scan_t)(const string &table_name, void *data); + +//! 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, void *data = nullptr) : function(function), data(data) { + } + + replacement_scan_t function; + void *data; +}; + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/set.hpp +// +// +//===----------------------------------------------------------------------===// + + + +#include + +namespace duckdb { +using std::set; +} + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/optimizer_type.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +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 +}; + +string OptimizerTypeToString(OptimizerType type); +OptimizerType OptimizerTypeFromString(const string &str); + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/window_aggregation_mode.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +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 +}; + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/set_scope.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +enum class SetScope : uint8_t { + AUTOMATIC = 0, + LOCAL = 1, /* unused */ + SESSION = 2, + GLOBAL = 3 +}; + +} // namespace duckdb + + +namespace duckdb { +class ClientContext; +class TableFunctionRef; +class CompressionFunction; + +struct CompressionFunctionSet; +struct DBConfig; + +enum class AccessMode : uint8_t { UNDEFINED = 0, AUTOMATIC = 1, READ_ONLY = 2, READ_WRITE = 3 }; + +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 +}; + +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; +}; + +struct DBConfig { + friend class DatabaseInstance; + friend class StorageManager; + +public: + DUCKDB_API DBConfig(); + DUCKDB_API ~DBConfig(); + + //! Access mode of the database (AUTOMATIC, READ_ONLY or READ_WRITE) + AccessMode access_mode = AccessMode::AUTOMATIC; + //! The allocator used by the system + Allocator allocator; + // 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 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 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; + //! 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; + //! Replacement table scans are automatically attempted when a table name cannot be found in the schema + vector replacement_scans; + //! 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 flag that adds additional (unnecessary) free_list blocks to the storage + bool debug_many_free_list_blocks = false; + //! Debug setting for window aggregation mode: (window, combine, separate) + WindowAggregationMode window_mode = WindowAggregationMode::WINDOW; + + //! Extra parameters that can be SET for loaded extensions + case_insensitive_map_t extension_parameters; + //! Database configuration variables as controlled by SET + case_insensitive_map_t set_variables; + + DUCKDB_API void AddExtensionOption(string name, string description, LogicalType parameter, + set_option_callback_t function = nullptr); + +public: + DUCKDB_API static DBConfig &GetConfig(ClientContext &context); + DUCKDB_API static DBConfig &GetConfig(DatabaseInstance &db); + DUCKDB_API static vector GetOptions(); + DUCKDB_API static idx_t GetOptionCount(); + + //! 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 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); + +private: + unique_ptr compression_functions; +}; + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/extension.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { +class DuckDB; + +//! The Extension class is the base class used to define extensions +class Extension { +public: + DUCKDB_API virtual ~Extension(); + + DUCKDB_API virtual void Load(DuckDB &db) = 0; + DUCKDB_API virtual std::string Name() = 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; + +public: + DUCKDB_API DatabaseInstance(); + DUCKDB_API ~DatabaseInstance(); + + DBConfig config; + +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(); + + idx_t NumberOfThreads(); + + DUCKDB_API static DatabaseInstance &GetDatabase(ClientContext &context); + +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; +}; + +//! 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); + + 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); + SetExtensionLoaded(extension.Name()); + } + + 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); + DUCKDB_API void SetExtensionLoaded(const std::string &name); +}; + +} // namespace duckdb + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/loadable_extension.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 + +#include + +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 +*/ +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; + } + + return NULL; +} + +ExternC const PfnDliHook __pfnDliNotifyHook2 = duckdb_dllimport_delay_hook; +ExternC const PfnDliHook __pfnDliFailureHook2 = duckdb_dllimport_delay_hook; +} +#endif +#endif +//===----------------------------------------------------------------------===// +// +// 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/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 + 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 +} 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; + +typedef struct { + int8_t hour; + int8_t min; + int8_t sec; + int32_t micros; +} duckdb_time_struct; + +//! 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; + +typedef struct { + duckdb_date_struct date; + duckdb_time_struct time; +} duckdb_timestamp_struct; + +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 { + 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 { - idx_t column_count; - idx_t row_count; - idx_t rows_changed; - duckdb_column *columns; - char *error_message; - void *internal_data; -} duckdb_result; +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 void *duckdb_database; +typedef void *duckdb_connection; +typedef void *duckdb_prepared_statement; +typedef void *duckdb_appender; +typedef void *duckdb_arrow; +typedef void *duckdb_config; +typedef void *duckdb_arrow_schema; +typedef void *duckdb_arrow_array; + +typedef enum { DuckDBSuccess = 0, DuckDBError = 1 } duckdb_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); + +/*! +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. + +* 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); + +//===--------------------------------------------------------------------===// +// 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. + +* 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(); + +/*! +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`. + +In the source code, configuration options are defined in `config.cpp`. + +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); + +//===--------------------------------------------------------------------===// +// 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. + +Returns `NULL` if the column is out of range. + +* 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); + +/*! +Returns the column type of the specified column. + +Returns `DUCKDB_TYPE_INVALID` if the column is out of range. + +* 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); + +/*! +Returns the number of columns present in a the result object. + +* result: The result object. +* returns: The number of columns present in the result object. +*/ +DUCKDB_API idx_t duckdb_column_count(duckdb_result *result); + +/*! +Returns the number of rows present in a the result object. + +* 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); + +/*! +Returns the data of a specific column of a result in columnar format. This is the fastest way of accessing data in a +query result, as no conversion or type checking must be performed (outside of the original switch). If performance +is a concern, it is recommended to use this API over the `duckdb_value` functions. + +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. + +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]); +``` + +* 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); + +/*! +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]); +} +``` + +* 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); + +/*! +Returns the error message contained within the result. The error is only set if `duckdb_query` returns `DuckDBError`. + +The result of this function must not be freed. It will be cleaned up when `duckdb_destroy_result` is called. + +* result: The result object to fetch the nullmask from. +* returns: The error of the result. +*/ +DUCKDB_API char *duckdb_result_error(duckdb_result *result); + +//===--------------------------------------------------------------------===// +// Result Functions +//===--------------------------------------------------------------------===// + +// 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_column_data and duckdb_nullmask_data + +/*! + * 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); + +/*! + * 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); + +/*! + * 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); + +/*! + * 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); + +/*! + * 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); + +/*! + * 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 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); + +/*! + * 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); + +/*! + * 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); + +/*! + * 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); + +/*! + * 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); + +/*! + * 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); + +/*! + * 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); + +/*! + * 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); + +/*! +* returns: The char* value at the specified location, 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); + +/*! +* 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. + +The result must NOT be freed. +*/ +DUCKDB_API char *duckdb_value_varchar_internal(duckdb_result *result, idx_t col, idx_t row); + +/*! +* 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); + +//===--------------------------------------------------------------------===// +// 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`). + +* 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); + +/*! +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); + +/*! +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); + +//===--------------------------------------------------------------------===// +// 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. + +Note that after calling `duckdb_prepare`, 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 +* 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); + +/*! +Closes the prepared statement and de-allocates all memory allocated for that connection. + +* prepared_statement: The prepared statement to destroy. +*/ +DUCKDB_API void duckdb_destroy_prepare(duckdb_prepared_statement *prepared_statement); + +/*! +Returns the error message associated with the given prepared statement. +If the prepared statement has no error message, this returns `nullptr` instead. + +The error message should not be freed. It will be de-allocated when `duckdb_destroy_prepare` is called. + +* 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); + +/*! +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); + +/*! +Returns the parameter type for the parameter at the given index. + +Returns `DUCKDB_TYPE_INVALID` if the parameter index is out of range or the statement was not successfully prepared. + +* 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); + +/*! +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); + +/*! +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 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); + +/*! +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); + +/*! +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); + +/*! +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); + +/*! +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); + +/*! +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); + +/*! +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); + +/*! +Executes the prepared statement with the given bound parameters, and returns a materialized query result. + +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); + +//===--------------------------------------------------------------------===// +// 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. + +// 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. + +// Note that `duckdb_appender_destroy` should always be called on the resulting appender, even if the function returns +// `DuckDBError`. + +/*! +Creates an appender object. + +* 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. + +The error message should not be freed. It will be de-allocated when `duckdb_appender_destroy` is called. + +* 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); + +/*! +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. + +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. + +* appender: The appender to flush. +* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +*/ +DUCKDB_API duckdb_state duckdb_appender_flush(duckdb_appender appender); + +/*! +Close the appender, flushing all intermediate state in the appender to the table and closing it for further appends. + +This is generally not necessary. Call `duckdb_appender_destroy` instead. + +* 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); + +/*! +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. + +* 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); + +/*! +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); + +/*! +Finish the current row of appends. After end_row is called, the next row can be appended. + +* 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); + +/*! +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); + +/*! +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); + +/*! +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); + +/*! +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); + +/*! +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); + +//===--------------------------------------------------------------------===// +// 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. + +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. + +* 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); + +/*! +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`. + +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); + +#ifdef __cplusplus +} +#endif +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/types/date.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + + +namespace duckdb { + +//! The Date class is a static class that holds helper functions for the Date type. +class Date { +public: + static const string_t MONTH_NAMES[12]; + static const string_t MONTH_NAMES_ABBREVIATED[12]; + static const string_t DAY_NAMES[7]; + static const string_t DAY_NAMES_ABBREVIATED[7]; + static const int32_t NORMAL_DAYS[13]; + static const int32_t CUMULATIVE_DAYS[13]; + static const int32_t LEAP_DAYS[13]; + static const int32_t CUMULATIVE_LEAP_DAYS[13]; + static const int32_t CUMULATIVE_YEAR_DAYS[401]; + static const int8_t MONTH_PER_DAY_OF_YEAR[365]; + static const int8_t LEAP_MONTH_PER_DAY_OF_YEAR[366]; + + // min date is 5877642-06-23 (BC) (-2^31) + constexpr static const int32_t DATE_MIN_YEAR = -5877641; + constexpr static const int32_t DATE_MIN_MONTH = 6; + constexpr static const int32_t DATE_MIN_DAY = 23; + // max date is 5881580-07-11 (2^31) + constexpr static const int32_t DATE_MAX_YEAR = 5881580; + constexpr static const int32_t DATE_MAX_MONTH = 7; + constexpr static const int32_t DATE_MAX_DAY = 11; + constexpr static const int32_t EPOCH_YEAR = 1970; + + constexpr static const int32_t YEAR_INTERVAL = 400; + constexpr static const int32_t DAYS_PER_YEAR_INTERVAL = 146097; + +public: + //! Convert a string in the format "YYYY-MM-DD" to a date object + DUCKDB_API static date_t FromString(const string &str, bool strict = false); + //! Convert a string in the format "YYYY-MM-DD" to a date object + DUCKDB_API static date_t FromCString(const char *str, idx_t len, bool strict = false); + //! Convert a date object to a string in the format "YYYY-MM-DD" + DUCKDB_API static string ToString(date_t date); + //! Try to convert text in a buffer to a date; returns true if parsing was successful + DUCKDB_API static bool TryConvertDate(const char *buf, idx_t len, idx_t &pos, date_t &result, bool strict = false); + + //! Create a string "YYYY-MM-DD" from a specified (year, month, day) + //! combination + DUCKDB_API static string Format(int32_t year, int32_t month, int32_t day); + + //! Extract the year, month and day from a given date object + DUCKDB_API static void Convert(date_t date, int32_t &out_year, int32_t &out_month, int32_t &out_day); + //! Create a Date object from a specified (year, month, day) combination + DUCKDB_API static date_t FromDate(int32_t year, int32_t month, int32_t day); + DUCKDB_API static bool TryFromDate(int32_t year, int32_t month, int32_t day, date_t &result); + + //! Returns true if (year) is a leap year, and false otherwise + DUCKDB_API static bool IsLeapYear(int32_t year); + + //! Returns true if the specified (year, month, day) combination is a valid + //! date + DUCKDB_API static bool IsValid(int32_t year, int32_t month, int32_t day); + + //! The max number of days in a month of a given year + DUCKDB_API static int32_t MonthDays(int32_t year, int32_t month); + + //! Extract the epoch from the date (seconds since 1970-01-01) + DUCKDB_API static int64_t Epoch(date_t date); + //! Extract the epoch from the date (nanoseconds since 1970-01-01) + DUCKDB_API static int64_t EpochNanoseconds(date_t date); + //! Convert the epoch (seconds since 1970-01-01) to a date_t + DUCKDB_API static date_t EpochToDate(int64_t epoch); + + //! Extract the number of days since epoch (days since 1970-01-01) + DUCKDB_API static int32_t EpochDays(date_t date); + //! Convert the epoch number of days to a date_t + DUCKDB_API static date_t EpochDaysToDate(int32_t epoch); + + //! Extract year of a date entry + DUCKDB_API static int32_t ExtractYear(date_t date); + //! Extract year of a date entry, but optimized to first try the last year found + DUCKDB_API static int32_t ExtractYear(date_t date, int32_t *last_year); + DUCKDB_API static int32_t ExtractYear(timestamp_t ts, int32_t *last_year); + //! Extract month of a date entry + DUCKDB_API static int32_t ExtractMonth(date_t date); + //! Extract day of a date entry + DUCKDB_API static int32_t ExtractDay(date_t date); + //! Extract the day of the week (1-7) + DUCKDB_API static int32_t ExtractISODayOfTheWeek(date_t date); + //! Extract the day of the year + DUCKDB_API static int32_t ExtractDayOfTheYear(date_t date); + //! Extract the ISO week number + //! ISO weeks start on Monday and the first week of a year + //! contains January 4 of that year. + //! In the ISO week-numbering system, it is possible for early-January dates + //! to be part of the 52nd or 53rd week of the previous year. + DUCKDB_API static void ExtractISOYearWeek(date_t date, int32_t &year, int32_t &week); + DUCKDB_API static int32_t ExtractISOWeekNumber(date_t date); + DUCKDB_API static int32_t ExtractISOYearNumber(date_t date); + //! Extract the week number as Python handles it. + //! Either Monday or Sunday is the first day of the week, + //! and any date before the first Monday/Sunday returns week 0 + //! This is a bit more consistent because week numbers in a year are always incrementing + DUCKDB_API static int32_t ExtractWeekNumberRegular(date_t date, bool monday_first = true); + //! Returns the date of the monday of the current week. + DUCKDB_API static date_t GetMondayOfCurrentWeek(date_t date); + + //! Helper function to parse two digits from a string (e.g. "30" -> 30, "03" -> 3, "3" -> 3) + DUCKDB_API static bool ParseDoubleDigit(const char *buf, idx_t len, idx_t &pos, int32_t &result); + + DUCKDB_API static string ConversionError(const string &str); + DUCKDB_API static string ConversionError(string_t str); + +private: + static void ExtractYearOffset(int32_t &n, int32_t &year, int32_t &year_offset); +}; +} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/types/blob.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { + +//! The Blob class is a static class that holds helper functions for the Blob type. +class Blob { +public: + // map of integer -> hex value + static constexpr const char *HEX_TABLE = "0123456789ABCDEF"; + // reverse map of byte -> integer value, or -1 for invalid hex values + static const int HEX_MAP[256]; + //! map of index -> base64 character + static constexpr const char *BASE64_MAP = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + //! padding character used in base64 encoding + static constexpr const char BASE64_PADDING = '='; + +public: + //! Returns the string size of a blob -> string conversion + static idx_t GetStringSize(string_t blob); + //! Converts a blob to a string, writing the output to the designated output string. + //! The string needs to have space for at least GetStringSize(blob) bytes. + static void ToString(string_t blob, char *output); + //! Convert a blob object to a string + static string ToString(string_t blob); + + //! Returns the blob size of a string -> blob conversion + static bool TryGetBlobSize(string_t str, idx_t &result_size, string *error_message); + static idx_t GetBlobSize(string_t str); + //! Convert a string to a blob. This function should ONLY be called after calling GetBlobSize, since it does NOT + //! perform data validation. + static void ToBlob(string_t str, data_ptr_t output); + //! Convert a string object to a blob + static string ToBlob(string_t str); + + // base 64 conversion functions + //! Returns the string size of a blob -> base64 conversion + static idx_t ToBase64Size(string_t blob); + //! Converts a blob to a base64 string, output should have space for at least ToBase64Size(blob) bytes + static void ToBase64(string_t blob, char *output); + + //! Returns the string size of a base64 string -> blob conversion + static idx_t FromBase64Size(string_t str); + //! Converts a base64 string to a blob, output should have space for at least FromBase64Size(blob) bytes + static void FromBase64(string_t str, data_ptr_t output, idx_t output_size); +}; +} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/types/decimal.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +//! The Decimal class is a static class that holds helper functions for the Decimal type +class Decimal { +public: + static constexpr uint8_t MAX_WIDTH_INT16 = 4; + static constexpr uint8_t MAX_WIDTH_INT32 = 9; + static constexpr uint8_t MAX_WIDTH_INT64 = 18; + static constexpr uint8_t MAX_WIDTH_INT128 = 38; + static constexpr uint8_t MAX_WIDTH_DECIMAL = MAX_WIDTH_INT128; + +public: + static string ToString(int16_t value, uint8_t scale); + static string ToString(int32_t value, uint8_t scale); + static string ToString(int64_t value, uint8_t scale); + static string ToString(hugeint_t value, uint8_t scale); +}; +} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/types/uuid.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { + +//! The UUID class contains static operations for the UUID type +class UUID { +public: + constexpr static const uint8_t STRING_SIZE = 36; + //! Convert a uuid string to a hugeint object + static bool FromString(string str, hugeint_t &result); + //! Convert a uuid string to a hugeint object + static bool FromCString(const char *str, idx_t len, hugeint_t &result) { + return FromString(string(str, 0, len), result); + } + //! Convert a hugeint object to a uuid style string + static void ToString(hugeint_t input, char *buf); + + //! Convert a hugeint object to a uuid style string + static string ToString(hugeint_t input) { + char buff[STRING_SIZE]; + ToString(input, buff); + return string(buff, STRING_SIZE); + } + + static hugeint_t FromString(string str) { + hugeint_t result; + FromString(str, result); + return result; + } +}; + +} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/types/timestamp.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + +namespace duckdb { + +struct timestamp_struct { + int32_t year; + int8_t month; + int8_t day; + int8_t hour; + int8_t min; + int8_t sec; + int16_t msec; +}; +//! 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) + constexpr static const int32_t MIN_YEAR = -290308; + constexpr static const int32_t MIN_MONTH = 12; + constexpr static const int32_t MIN_DAY = 22; + +public: + //! Convert a string in the format "YYYY-MM-DD hh:mm:ss" to a timestamp object + DUCKDB_API static timestamp_t FromString(const string &str); + DUCKDB_API static bool TryConvertTimestamp(const char *str, idx_t len, timestamp_t &result); + DUCKDB_API static timestamp_t FromCString(const char *str, idx_t len); + //! Convert a date object to a string in the format "YYYY-MM-DD hh:mm:ss" + DUCKDB_API static string ToString(timestamp_t timestamp); + + DUCKDB_API static date_t GetDate(timestamp_t timestamp); + + DUCKDB_API static dtime_t GetTime(timestamp_t timestamp); + //! Create a Timestamp object from a specified (date, time) combination + 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); + + //! Extract the date and time from a given timestamp object + DUCKDB_API static void Convert(timestamp_t date, date_t &out_date, dtime_t &out_time); + //! Returns current timestamp + DUCKDB_API static timestamp_t GetCurrentTimestamp(); + + //! Convert the epoch (in sec) to a timestamp + DUCKDB_API static timestamp_t FromEpochSeconds(int64_t ms); + //! Convert the epoch (in ms) to a timestamp + DUCKDB_API static timestamp_t FromEpochMs(int64_t ms); + //! Convert the epoch (in microseconds) to a timestamp + DUCKDB_API static timestamp_t FromEpochMicroSeconds(int64_t micros); + //! Convert the epoch (in nanoseconds) to a timestamp + DUCKDB_API static timestamp_t FromEpochNanoSeconds(int64_t micros); + + //! Convert the epoch (in seconds) to a timestamp + DUCKDB_API static int64_t GetEpochSeconds(timestamp_t timestamp); + //! Convert the epoch (in ms) to a timestamp + DUCKDB_API static int64_t GetEpochMs(timestamp_t timestamp); + //! Convert a timestamp to epoch (in microseconds) + DUCKDB_API static int64_t GetEpochMicroSeconds(timestamp_t timestamp); + //! Convert a timestamp to epoch (in nanoseconds) + DUCKDB_API static int64_t GetEpochNanoSeconds(timestamp_t timestamp); + + DUCKDB_API static bool TryParseUTCOffset(const char *str, idx_t &pos, idx_t len, int &hour_offset, + int &minute_offset); + + DUCKDB_API static string ConversionError(const string &str); + DUCKDB_API static string ConversionError(string_t str); +}; +} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/types/time.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + +namespace duckdb { + +//! 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/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 + 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 +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/appender.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + + +namespace duckdb { + +class ClientContext; +class DuckDB; +class TableCatalogEntry; +class Connection; + +//! The Appender class can be used to append elements to a table. +class BaseAppender { +protected: + //! The amount of chunks that will be gathered in the chunk collection before flushing + static constexpr const idx_t FLUSH_COUNT = 100; + + //! The append types + vector types; + //! The buffered data for the append + ChunkCollection collection; + //! Internal chunk used for appends + unique_ptr chunk; + //! The current column to append to + idx_t column = 0; + +public: + DUCKDB_API BaseAppender(); + DUCKDB_API BaseAppender(vector types); + 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; + } + +protected: + void Destructor(); + virtual void FlushInternal(ChunkCollection &collection) = 0; + void InitializeChunk(); + void FlushChunk(); + + template + void AppendValueInternal(T value); + template + void AppendValueInternal(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(ChunkCollection &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(ChunkCollection &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); + +} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/client_context.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/catalog/catalog_entry/table_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/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 +}; + +//! 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 + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/bound_constraint.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { +//! Bound equivalent of Constraint +class BoundConstraint { +public: + explicit BoundConstraint(ConstraintType type) : type(type) {}; + virtual ~BoundConstraint() { + } + + ConstraintType type; +}; +} // namespace duckdb + + + + +namespace duckdb { + +class ColumnStatistics; +class DataTable; +struct CreateTableInfo; +struct BoundCreateTableInfo; + +struct RenameColumnInfo; +struct AddColumnInfo; +struct RemoveColumnInfo; +struct SetDefaultInfo; +struct ChangeColumnTypeInfo; + +//! 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 + vector 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; + //! A map of column name to column index + case_insensitive_map_t name_map; + +public: + unique_ptr AlterEntry(ClientContext &context, AlterInfo *info) override; + //! Returns whether or not a column with the given name exists + 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 + vector GetTypes(); + string ToSQL() override; -typedef void *duckdb_database; -typedef void *duckdb_connection; -typedef void *duckdb_prepared_statement; -typedef void *duckdb_appender; -typedef void *duckdb_arrow; -typedef void *duckdb_config; -typedef void *duckdb_arrow_schema; -typedef void *duckdb_arrow_array; + //! Serialize the meta information of the TableCatalogEntry a serializer + virtual void Serialize(Serializer &serializer); + //! Deserializes to a CreateTableInfo + static unique_ptr Deserialize(Deserializer &source); -typedef enum { DuckDBSuccess = 0, DuckDBError = 1 } duckdb_state; + unique_ptr Copy(ClientContext &context) override; -//===--------------------------------------------------------------------===// -// Open/Connect -//===--------------------------------------------------------------------===// + void SetAsRoot() override; -/*! -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. + void CommitAlter(AlterInfo &info); + void CommitDrop(); -* 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); + //! Returns the column index of the specified column name. + //! If the column does not exist: + //! If if_exists is true, returns DConstants::INVALID_INDEX + //! If if_exists is false, throws an exception + idx_t GetColumnIndex(string &name, bool if_exists = false); -/*! -Extended version of duckdb_open. Creates a new database or opens an existing database file stored at the the given path. +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); +}; +} // 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); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/catalog/catalog_entry/sequence_catalog_entry.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. -* 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. +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/parsed_data/create_sequence_info.hpp +// +// +//===----------------------------------------------------------------------===// -* connection: The connection to close. -*/ -DUCKDB_API void duckdb_disconnect(duckdb_connection *connection); -//===--------------------------------------------------------------------===// -// 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/parsed_data/create_info.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. +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/parsed_data/parse_info.hpp +// +// +//===----------------------------------------------------------------------===// -* returns: The amount of config options available. -*/ -DUCKDB_API size_t duckdb_config_count(); -/*! -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`. +struct ParseInfo { + virtual ~ParseInfo() { + } +}; -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); -/*! -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 { -//===--------------------------------------------------------------------===// -// 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`. +enum class OnCreateConflict : uint8_t { + // Standard: throw error + ERROR_ON_CONFLICT, + // CREATE IF NOT EXISTS, silently do nothing on conflict + IGNORE_ON_CONFLICT, + // CREATE OR REPLACE + REPLACE_ON_CONFLICT +}; -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. +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) { + } + ~CreateInfo() override { + } -* 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); + //! The to-be-created catalog type + CatalogType type; + //! The schema name of the entry + string schema; + //! What to do on create conflict + OnCreateConflict on_conflict; + //! Whether or not the entry is temporary + bool temporary; + //! Whether or not the entry is an internal entry + bool internal; + //! The SQL string of the CREATE statement + string sql; + +public: + virtual unique_ptr Copy() const = 0; + void CopyProperties(CreateInfo &other) const { + other.type = type; + other.schema = schema; + other.on_conflict = on_conflict; + other.temporary = temporary; + other.internal = internal; + other.sql = sql; + } +}; + +} // namespace duckdb + + + +namespace duckdb { + +struct CreateSequenceInfo : public CreateInfo { + CreateSequenceInfo() + : CreateInfo(CatalogType::SEQUENCE_ENTRY, INVALID_SCHEMA), name(string()), usage_count(0), increment(1), + min_value(1), max_value(NumericLimits::Maximum()), start_value(1), cycle(false) { + } + + //! Sequence name to create + string name; + //! Usage count of the sequence + uint64_t usage_count; + //! The increment value + int64_t increment; + //! The minimum value of the sequence + int64_t min_value; + //! The maximum value of the sequence + int64_t max_value; + //! The start value of the sequence + int64_t start_value; + //! Whether or not the sequence cycles + bool cycle; + +public: + unique_ptr Copy() const override { + auto result = make_unique(); + CopyProperties(*result); + result->name = name; + result->schema = schema; + result->usage_count = usage_count; + result->increment = increment; + result->min_value = min_value; + result->max_value = max_value; + result->start_value = start_value; + result->cycle = cycle; + return move(result); + } +}; + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/parsed_data/alter_table_info.hpp +// +// +//===----------------------------------------------------------------------===// -/*! -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. -Returns `NULL` if the column is out of range. -* 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); -/*! -Returns the column type of the specified column. -Returns `DUCKDB_TYPE_INVALID` if the column is out of range. +namespace duckdb { -* 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); +enum class AlterType : uint8_t { + INVALID = 0, + ALTER_TABLE = 1, + ALTER_VIEW = 2, + ALTER_SEQUENCE = 3, + CHANGE_OWNERSHIP = 4 +}; -/*! -Returns the number of columns present in a the result object. +struct AlterInfo : public ParseInfo { + AlterInfo(AlterType type, string schema, string name); + ~AlterInfo() override; -* result: The result object. -* returns: The number of columns present in the result object. -*/ -DUCKDB_API idx_t duckdb_column_count(duckdb_result *result); + AlterType type; + //! Schema name to alter + string schema; + //! Entry name to alter + string name; -/*! -Returns the number of rows present in a the result object. +public: + virtual CatalogType GetCatalogType() const = 0; + virtual unique_ptr Copy() const = 0; + void Serialize(Serializer &serializer) const; + virtual void Serialize(FieldWriter &writer) const = 0; + static unique_ptr Deserialize(Deserializer &source); +}; -* result: The result object. -* returns: The number of rows present in the result object. -*/ -DUCKDB_API idx_t duckdb_row_count(duckdb_result *result); +//===--------------------------------------------------------------------===// +// Change Ownership +//===--------------------------------------------------------------------===// +struct ChangeOwnershipInfo : public AlterInfo { + ChangeOwnershipInfo(CatalogType entry_catalog_type, string entry_schema, string entry_name, string owner_schema, + string owner_name); -/*! -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. + // Catalog type refers to the entry type, since this struct is usually built from an + // ALTER . OWNED BY . statement + // here it is only possible to know the type of who is to be owned + CatalogType entry_catalog_type; -* result: The result object. -* returns: The number of rows changed. -*/ -DUCKDB_API idx_t duckdb_rows_changed(duckdb_result *result); + string owner_schema; + string owner_name; -/*! -Returns the data of a specific column of a result in columnar format. This is the fastest way of accessing data in a -query result, as no conversion or type checking must be performed (outside of the original switch). If performance -is a concern, it is recommended to use this API over the `duckdb_value` functions. +public: + CatalogType GetCatalogType() const override; + unique_ptr Copy() const override; + void Serialize(FieldWriter &writer) const override; +}; -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. +//===--------------------------------------------------------------------===// +// Alter Table +//===--------------------------------------------------------------------===// +enum class AlterTableType : uint8_t { + INVALID = 0, + RENAME_COLUMN = 1, + RENAME_TABLE = 2, + ADD_COLUMN = 3, + REMOVE_COLUMN = 4, + ALTER_COLUMN_TYPE = 5, + SET_DEFAULT = 6 +}; -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]); -``` +struct AlterTableInfo : public AlterInfo { + AlterTableInfo(AlterTableType type, string schema, string table); + ~AlterTableInfo() override; -* 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); + AlterTableType alter_table_type; -/*! -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. +public: + CatalogType GetCatalogType() const override; + void Serialize(FieldWriter &writer) const override; + virtual void SerializeAlterTable(FieldWriter &writer) const = 0; + static unique_ptr Deserialize(FieldReader &reader); +}; -```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]); -} -``` +//===--------------------------------------------------------------------===// +// RenameColumnInfo +//===--------------------------------------------------------------------===// +struct RenameColumnInfo : public AlterTableInfo { + RenameColumnInfo(string schema, string table, string old_name_p, string new_name_p); + ~RenameColumnInfo() override; -* 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); + //! Column old name + string old_name; + //! Column new name + string new_name; -/*! -Returns the error message contained within the result. The error is only set if `duckdb_query` returns `DuckDBError`. +public: + unique_ptr Copy() const override; + void SerializeAlterTable(FieldWriter &writer) const override; + static unique_ptr Deserialize(FieldReader &reader, string schema, string table); +}; -The result of this function must not be freed. It will be cleaned up when `duckdb_destroy_result` is called. +//===--------------------------------------------------------------------===// +// RenameTableInfo +//===--------------------------------------------------------------------===// +struct RenameTableInfo : public AlterTableInfo { + RenameTableInfo(string schema, string table, string new_name); + ~RenameTableInfo() override; -* result: The result object to fetch the nullmask from. -* returns: The error of the result. -*/ -DUCKDB_API char *duckdb_result_error(duckdb_result *result); + //! Relation new name + string new_table_name; + +public: + unique_ptr Copy() const override; + void SerializeAlterTable(FieldWriter &writer) const override; + static unique_ptr Deserialize(FieldReader &reader, string schema, string table); +}; //===--------------------------------------------------------------------===// -// Result Functions +// AddColumnInfo //===--------------------------------------------------------------------===// +struct AddColumnInfo : public AlterTableInfo { + AddColumnInfo(string schema, string table, ColumnDefinition new_column); + ~AddColumnInfo() override; -// 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_column_data and duckdb_nullmask_data + //! New column + ColumnDefinition new_column; -/*! - * 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); +public: + unique_ptr Copy() const override; + void SerializeAlterTable(FieldWriter &writer) const override; + static unique_ptr Deserialize(FieldReader &reader, string schema, string table); +}; -/*! - * 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); +//===--------------------------------------------------------------------===// +// RemoveColumnInfo +//===--------------------------------------------------------------------===// +struct RemoveColumnInfo : public AlterTableInfo { + RemoveColumnInfo(string schema, string table, string removed_column, bool if_exists); + ~RemoveColumnInfo() override; -/*! - * 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); + //! The column to remove + string removed_column; + //! Whether or not an error should be thrown if the column does not exist + bool if_exists; -/*! - * 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); +public: + unique_ptr Copy() const override; + void SerializeAlterTable(FieldWriter &writer) const override; + static unique_ptr Deserialize(FieldReader &reader, string schema, string table); +}; -/*! - * 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); +//===--------------------------------------------------------------------===// +// ChangeColumnTypeInfo +//===--------------------------------------------------------------------===// +struct ChangeColumnTypeInfo : public AlterTableInfo { + ChangeColumnTypeInfo(string schema, string table, string column_name, LogicalType target_type, + unique_ptr expression); + ~ChangeColumnTypeInfo() override; + + //! The column name to alter + string column_name; + //! The target type of the column + LogicalType target_type; + //! The expression used for data conversion + unique_ptr expression; -/*! - * 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); +public: + unique_ptr Copy() const override; + void SerializeAlterTable(FieldWriter &writer) const override; + static unique_ptr Deserialize(FieldReader &reader, string schema, string table); +}; -/*! - * 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); +//===--------------------------------------------------------------------===// +// SetDefaultInfo +//===--------------------------------------------------------------------===// +struct SetDefaultInfo : public AlterTableInfo { + SetDefaultInfo(string schema, string table, string column_name, unique_ptr new_default); + ~SetDefaultInfo() override; -/*! - * 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); + //! The column name to alter + string column_name; + //! The expression used for data conversion + unique_ptr expression; -/*! - * 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); +public: + unique_ptr Copy() const override; + void SerializeAlterTable(FieldWriter &writer) const override; + static unique_ptr Deserialize(FieldReader &reader, string schema, string table); +}; -/*! - * 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); +//===--------------------------------------------------------------------===// +// Alter View +//===--------------------------------------------------------------------===// +enum class AlterViewType : uint8_t { INVALID = 0, RENAME_VIEW = 1 }; -/*! - * 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); +struct AlterViewInfo : public AlterInfo { + AlterViewInfo(AlterViewType type, string schema, string view); + ~AlterViewInfo() override; -/*! - * 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); + AlterViewType alter_view_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); +public: + CatalogType GetCatalogType() const override; + void Serialize(FieldWriter &writer) const override; + virtual void SerializeAlterView(FieldWriter &writer) const = 0; + static unique_ptr Deserialize(FieldReader &reader); +}; -/*! - * 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); +//===--------------------------------------------------------------------===// +// RenameViewInfo +//===--------------------------------------------------------------------===// +struct RenameViewInfo : public AlterViewInfo { + RenameViewInfo(string schema, string view, string new_name); + ~RenameViewInfo() override; -/*! - * 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); + //! Relation new name + string new_view_name; -/*! - * 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); +public: + unique_ptr Copy() const override; + void SerializeAlterView(FieldWriter &writer) const override; + static unique_ptr Deserialize(FieldReader &reader, string schema, string table); +}; -/*! -* returns: The char* value at the specified location, 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); +} // namespace duckdb -/*! -* 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. -The result must NOT be freed. -*/ -DUCKDB_API char *duckdb_value_varchar_internal(duckdb_result *result, idx_t col, idx_t row); +namespace duckdb { +class Serializer; +class Deserializer; -/*! -* 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); +struct SequenceValue { + SequenceValue() : usage_count(0), counter(-1) { + } + SequenceValue(uint64_t usage_count, int64_t counter) : usage_count(usage_count), counter(counter) { + } -/*! - * 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); + uint64_t usage_count; + int64_t counter; +}; -//===--------------------------------------------------------------------===// -// Helpers -//===--------------------------------------------------------------------===// -/*! -Allocate `size` bytes of memory using the duckdb internal malloc function. Any memory allocated in this manner -should be freed using `duckdb_free`. +//! A sequence catalog entry +class SequenceCatalogEntry : public StandardEntry { +public: + //! Create a real TableCatalogEntry and initialize storage for it + SequenceCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateSequenceInfo *info); + + //! Lock for getting a value on the sequence + mutex lock; + //! The amount of times the sequence has been used + uint64_t usage_count; + //! The sequence counter + int64_t counter; + //! The most recently returned value + int64_t last_value; + //! The increment value + int64_t increment; + //! The minimum value of the sequence + int64_t start_value; + //! The minimum value of the sequence + int64_t min_value; + //! The maximum value of the sequence + int64_t max_value; + //! Whether or not the sequence cycles + bool cycle; + +public: + //! Serialize the meta information of the SequenceCatalogEntry a serializer + virtual void Serialize(Serializer &serializer); + //! Deserializes to a CreateTableInfo + static unique_ptr Deserialize(Deserializer &source); + + string ToSQL() override; + + CatalogEntry *AlterOwnership(ClientContext &context, AlterInfo *info); +}; +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/transaction/transaction.hpp +// +// +//===----------------------------------------------------------------------===// -* 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); -//===--------------------------------------------------------------------===// -// 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`). +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/transaction/undo_buffer.hpp +// +// +//===----------------------------------------------------------------------===// -* 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`). -* 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`). +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/undo_flags.hpp +// +// +//===----------------------------------------------------------------------===// -* 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); -/*! -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); +namespace duckdb { -//===--------------------------------------------------------------------===// -// Hugeint Helpers -//===--------------------------------------------------------------------===// -/*! -Converts a duckdb_hugeint object (as obtained from a `DUCKDB_TYPE_HUGEINT` column) into a double. +enum class UndoFlags : uint32_t { // far to big but aligned (TM) + EMPTY_ENTRY = 0, + CATALOG_ENTRY = 1, + INSERT_TUPLE = 2, + DELETE_TUPLE = 3, + UPDATE_TUPLE = 4 +}; -* val: The hugeint value. -* returns: The converted `double` element. -*/ -DUCKDB_API double duckdb_hugeint_to_double(duckdb_hugeint val); +} // namespace duckdb -/*! -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. +namespace duckdb { -* val: The double value. -* returns: The converted `duckdb_hugeint` element. -*/ -DUCKDB_API duckdb_hugeint duckdb_double_to_hugeint(double val); +class WriteAheadLog; -//===--------------------------------------------------------------------===// -// 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 +struct UndoChunk { + explicit UndoChunk(idx_t size); + ~UndoChunk(); -/*! -Create a prepared statement object from a query. + data_ptr_t WriteEntry(UndoFlags type, uint32_t len); -Note that after calling `duckdb_prepare`, the prepared statement should always be destroyed using -`duckdb_destroy_prepare`, even if the prepare fails. + unique_ptr data; + idx_t current_position; + idx_t maximum_size; + unique_ptr next; + UndoChunk *prev; +}; -If the prepare fails, `duckdb_prepare_error` can be called to obtain the reason why the prepare failed. +//! The undo buffer of a transaction is used to hold previous versions of tuples +//! that might be required in the future (because of rollbacks or previous +//! transactions accessing them) +class UndoBuffer { +public: + struct IteratorState { + UndoChunk *current; + data_ptr_t start; + data_ptr_t end; + }; -* 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: + UndoBuffer(); -/*! -Closes the prepared statement and de-allocates all memory allocated for that connection. + //! Reserve space for an entry of the specified type and length in the undo + //! buffer + data_ptr_t CreateEntry(UndoFlags type, idx_t len); -* prepared_statement: The prepared statement to destroy. -*/ -DUCKDB_API void duckdb_destroy_prepare(duckdb_prepared_statement *prepared_statement); + bool ChangesMade(); + idx_t EstimatedSize(); -/*! -Returns the error message associated with the given prepared statement. -If the prepared statement has no error message, this returns `nullptr` instead. + //! Cleanup the undo buffer + void Cleanup(); + //! Commit the changes made in the UndoBuffer: should be called on commit + void Commit(UndoBuffer::IteratorState &iterator_state, WriteAheadLog *log, transaction_t commit_id); + //! Revert committed changes made in the UndoBuffer up until the currently committed state + void RevertCommit(UndoBuffer::IteratorState &iterator_state, transaction_t transaction_id); + //! Rollback the changes made in this UndoBuffer: should be called on + //! rollback + void Rollback() noexcept; -The error message should not be freed. It will be de-allocated when `duckdb_destroy_prepare` is called. +private: + unique_ptr head; + UndoChunk *tail; -* 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); +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); +}; -/*! -Returns the number of parameters that can be provided to the given prepared statement. +} // namespace duckdb -Returns 0 if the query was not successfully prepared. +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/transaction/local_storage.hpp +// +// +//===----------------------------------------------------------------------===// -* prepared_statement: The prepared statement to obtain the number of parameters for. -*/ -DUCKDB_API idx_t duckdb_nparams(duckdb_prepared_statement prepared_statement); -/*! -Returns the parameter type for the parameter at the given index. -Returns `DUCKDB_TYPE_INVALID` if the parameter index is out of range or the statement was not successfully prepared. -* 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 +// +// duckdb/storage/table/scan_state.hpp +// +// +//===----------------------------------------------------------------------===// -/*! -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); -/*! -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); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/storage/buffer/buffer_handle.hpp +// +// +//===----------------------------------------------------------------------===// -/*! -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 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); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/storage/storage_info.hpp +// +// +//===----------------------------------------------------------------------===// -/*! -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); +namespace duckdb { +class Serializer; +class Deserializer; +struct FileHandle; -/*! -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); +//! The version number of the database storage format +extern const uint64_t VERSION_NUMBER; -/*! -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); +using block_id_t = int64_t; -/*! -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); +#define INVALID_BLOCK (-1) -/*! -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); +// maximum block id, 2^62 +#define MAXIMUM_BLOCK 4611686018427388000LL -/*! -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); +//! The MainHeader is the first header in the storage file. The MainHeader is typically written only once for a database +//! file. +struct MainHeader { + static constexpr idx_t MAGIC_BYTE_SIZE = 4; + static constexpr idx_t MAGIC_BYTE_OFFSET = sizeof(uint64_t); + static constexpr idx_t FLAG_COUNT = 4; + // the magic bytes in front of the file + // should be "DUCK" + static const char MAGIC_BYTES[]; + //! The version of the database + uint64_t version_number; + //! The set of flags used by the database + uint64_t flags[FLAG_COUNT]; -/*! -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); + static void CheckMagicBytes(FileHandle &handle); -/*! -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); + void Serialize(Serializer &ser); + static MainHeader Deserialize(Deserializer &source); +}; -/*! -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); +//! The DatabaseHeader contains information about the current state of the database. Every storage file has two +//! DatabaseHeaders. On startup, the DatabaseHeader with the highest iteration count is used as the active header. When +//! a checkpoint is performed, the active DatabaseHeader is switched by increasing the iteration count of the +//! DatabaseHeader. +struct DatabaseHeader { + //! The iteration count, increases by 1 every time the storage is checkpointed. + uint64_t iteration; + //! A pointer to the initial meta block + block_id_t meta_block; + //! A pointer to the block containing the free list + block_id_t free_list; + //! The number of blocks that is in the file as of this database header. If the file is larger than BLOCK_SIZE * + //! block_count any blocks appearing AFTER block_count are implicitly part of the free_list. + uint64_t block_count; -/*! -Executes the prepared statement with the given bound parameters, and returns a materialized query result. + void Serialize(Serializer &ser); + static DatabaseHeader Deserialize(Deserializer &source); +}; -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); -/*! -Executes the prepared statement with the given bound parameters, and returns an arrow query result. +namespace duckdb { +class BlockHandle; +class FileBuffer; -* 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); +class BufferHandle { +public: + BufferHandle(shared_ptr handle, FileBuffer *node); + ~BufferHandle(); -//===--------------------------------------------------------------------===// -// Appender -//===--------------------------------------------------------------------===// + //! The block handle + shared_ptr handle; + //! The managed buffer node + FileBuffer *node; + data_ptr_t Ptr(); +}; -// 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 -// 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. +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/storage/storage_lock.hpp +// +// +//===----------------------------------------------------------------------===// -// Note that `duckdb_appender_destroy` should always be called on the resulting appender, even if the function returns -// `DuckDBError`. -/*! -Creates an appender object. -* 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. -The error message should not be freed. It will be de-allocated when `duckdb_appender_destroy` is called. -* 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); -/*! -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. +namespace duckdb { +class StorageLock; -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. +enum class StorageLockType { SHARED = 0, EXCLUSIVE = 1 }; -* appender: The appender to flush. -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_appender_flush(duckdb_appender appender); +class StorageLockKey { +public: + StorageLockKey(StorageLock &lock, StorageLockType type); + ~StorageLockKey(); -/*! -Close the appender, flushing all intermediate state in the appender to the table and closing it for further appends. +private: + StorageLock &lock; + StorageLockType type; +}; -This is generally not necessary. Call `duckdb_appender_destroy` instead. +class StorageLock { + friend class StorageLockKey; -* 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); +public: + StorageLock(); -/*! -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 an exclusive lock + unique_ptr GetExclusiveLock(); + //! Get a shared lock + unique_ptr GetSharedLock(); -* 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: + mutex exclusive_lock; + atomic read_count; -/*! -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); +private: + //! Release an exclusive lock + void ReleaseExclusiveLock(); + //! Release a shared lock + void ReleaseSharedLock(); +}; -/*! -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); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/execution/adaptive_filter.hpp +// +// +//===----------------------------------------------------------------------===// -/*! -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); -/*! -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); -/*! -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 +// +// duckdb/planner/expression/bound_aggregate_expression.hpp +// +// +//===----------------------------------------------------------------------===// -/*! -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); -/*! -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); -//===--------------------------------------------------------------------===// -// 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); +#include -/*! -Fetch the internal arrow schema from the arrow result. +namespace duckdb { +class BoundAggregateExpression : public Expression { +public: + BoundAggregateExpression(AggregateFunction function, vector> children, + unique_ptr filter, unique_ptr bind_info, bool distinct); -* 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); + //! The bound function expression + AggregateFunction function; + //! List of arguments to the function + vector> children; + //! The bound function data (if any) + unique_ptr bind_info; + //! True to aggregate on distinct values + bool distinct; -/*! -Fetch an internal arrow array from the arrow result. + //! Filter for this aggregate + unique_ptr filter; -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. +public: + bool IsAggregate() const override { + return true; + } + bool IsFoldable() const override { + return false; + } -* 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); + string ToString() const override; + + hash_t Hash() const override; + bool Equals(const BaseExpression *other) const override; + unique_ptr Copy() override; +}; +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/expression/bound_between_expression.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. +namespace duckdb { -* result: The result object. -* returns: The number of rows changed. -*/ -DUCKDB_API idx_t duckdb_arrow_rows_changed(duckdb_arrow result); +class BoundBetweenExpression : public Expression { +public: + BoundBetweenExpression(unique_ptr input, unique_ptr lower, unique_ptr upper, + bool lower_inclusive, bool upper_inclusive); -/*! -Returns the error message contained within the result. The error is only set if `duckdb_query_arrow` returns -`DuckDBError`. + unique_ptr input; + unique_ptr lower; + unique_ptr upper; + bool lower_inclusive; + bool upper_inclusive; -The error message should not be freed. It will be de-allocated when `duckdb_destroy_arrow` is called. +public: + string ToString() const override; -* 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); + bool Equals(const BaseExpression *other) const override; -/*! -Closes the result and de-allocates all memory allocated for the arrow result. + unique_ptr Copy() override; -* result: The result to destroy. -*/ -DUCKDB_API void duckdb_destroy_arrow(duckdb_arrow *result); +public: + ExpressionType LowerComparisonType() { + return lower_inclusive ? ExpressionType::COMPARE_GREATERTHANOREQUALTO : ExpressionType::COMPARE_GREATERTHAN; + } + ExpressionType UpperComparisonType() { + return upper_inclusive ? ExpressionType::COMPARE_LESSTHANOREQUALTO : ExpressionType::COMPARE_LESSTHAN; + } +}; +} // namespace duckdb -#ifdef __cplusplus -} -#endif //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/types/date.hpp +// duckdb/planner/expression/bound_case_expression.hpp // // //===----------------------------------------------------------------------===// @@ -11383,205 +14595,123 @@ DUCKDB_API void duckdb_destroy_arrow(duckdb_arrow *result); +namespace duckdb { +struct BoundCaseCheck { + unique_ptr when_expr; + unique_ptr then_expr; +}; +class BoundCaseExpression : public Expression { +public: + BoundCaseExpression(LogicalType type); + BoundCaseExpression(unique_ptr when_expr, unique_ptr then_expr, + unique_ptr else_expr); -namespace duckdb { + vector case_checks; + unique_ptr else_expr; -//! The Date class is a static class that holds helper functions for the Date type. -class Date { public: - static const string_t MONTH_NAMES[12]; - static const string_t MONTH_NAMES_ABBREVIATED[12]; - static const string_t DAY_NAMES[7]; - static const string_t DAY_NAMES_ABBREVIATED[7]; - static const int32_t NORMAL_DAYS[13]; - static const int32_t CUMULATIVE_DAYS[13]; - static const int32_t LEAP_DAYS[13]; - static const int32_t CUMULATIVE_LEAP_DAYS[13]; - static const int32_t CUMULATIVE_YEAR_DAYS[401]; - static const int8_t MONTH_PER_DAY_OF_YEAR[365]; - static const int8_t LEAP_MONTH_PER_DAY_OF_YEAR[366]; + string ToString() const override; - // min date is 5877642-06-23 (BC) (-2^31) - constexpr static const int32_t DATE_MIN_YEAR = -5877641; - constexpr static const int32_t DATE_MIN_MONTH = 6; - constexpr static const int32_t DATE_MIN_DAY = 23; - // max date is 5881580-07-11 (2^31) - constexpr static const int32_t DATE_MAX_YEAR = 5881580; - constexpr static const int32_t DATE_MAX_MONTH = 7; - constexpr static const int32_t DATE_MAX_DAY = 11; - constexpr static const int32_t EPOCH_YEAR = 1970; + bool Equals(const BaseExpression *other) const override; - constexpr static const int32_t YEAR_INTERVAL = 400; - constexpr static const int32_t DAYS_PER_YEAR_INTERVAL = 146097; + unique_ptr Copy() override; +}; +} // namespace duckdb -public: - //! Convert a string in the format "YYYY-MM-DD" to a date object - DUCKDB_API static date_t FromString(const string &str, bool strict = false); - //! Convert a string in the format "YYYY-MM-DD" to a date object - DUCKDB_API static date_t FromCString(const char *str, idx_t len, bool strict = false); - //! Convert a date object to a string in the format "YYYY-MM-DD" - DUCKDB_API static string ToString(date_t date); - //! Try to convert text in a buffer to a date; returns true if parsing was successful - DUCKDB_API static bool TryConvertDate(const char *buf, idx_t len, idx_t &pos, date_t &result, bool strict = false); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/expression/bound_cast_expression.hpp +// +// +//===----------------------------------------------------------------------===// - //! Create a string "YYYY-MM-DD" from a specified (year, month, day) - //! combination - DUCKDB_API static string Format(int32_t year, int32_t month, int32_t day); - //! Extract the year, month and day from a given date object - DUCKDB_API static void Convert(date_t date, int32_t &out_year, int32_t &out_month, int32_t &out_day); - //! Create a Date object from a specified (year, month, day) combination - DUCKDB_API static date_t FromDate(int32_t year, int32_t month, int32_t day); - DUCKDB_API static bool TryFromDate(int32_t year, int32_t month, int32_t day, date_t &result); - //! Returns true if (year) is a leap year, and false otherwise - DUCKDB_API static bool IsLeapYear(int32_t year); - //! Returns true if the specified (year, month, day) combination is a valid - //! date - DUCKDB_API static bool IsValid(int32_t year, int32_t month, int32_t day); - //! The max number of days in a month of a given year - DUCKDB_API static int32_t MonthDays(int32_t year, int32_t month); +namespace duckdb { - //! Extract the epoch from the date (seconds since 1970-01-01) - DUCKDB_API static int64_t Epoch(date_t date); - //! Extract the epoch from the date (nanoseconds since 1970-01-01) - DUCKDB_API static int64_t EpochNanoseconds(date_t date); - //! Convert the epoch (seconds since 1970-01-01) to a date_t - DUCKDB_API static date_t EpochToDate(int64_t epoch); +class BoundCastExpression : public Expression { +public: + BoundCastExpression(unique_ptr child, LogicalType target_type, bool try_cast = false); - //! Extract the number of days since epoch (days since 1970-01-01) - DUCKDB_API static int32_t EpochDays(date_t date); - //! Convert the epoch number of days to a date_t - DUCKDB_API static date_t EpochDaysToDate(int32_t epoch); + //! The child type + unique_ptr child; + //! Whether to use try_cast or not. try_cast converts cast failures into NULLs instead of throwing an error. + bool try_cast; - //! Extract year of a date entry - DUCKDB_API static int32_t ExtractYear(date_t date); - //! Extract year of a date entry, but optimized to first try the last year found - DUCKDB_API static int32_t ExtractYear(date_t date, int32_t *last_year); - DUCKDB_API static int32_t ExtractYear(timestamp_t ts, int32_t *last_year); - //! Extract month of a date entry - DUCKDB_API static int32_t ExtractMonth(date_t date); - //! Extract day of a date entry - DUCKDB_API static int32_t ExtractDay(date_t date); - //! Extract the day of the week (1-7) - DUCKDB_API static int32_t ExtractISODayOfTheWeek(date_t date); - //! Extract the day of the year - DUCKDB_API static int32_t ExtractDayOfTheYear(date_t date); - //! Extract the ISO week number - //! ISO weeks start on Monday and the first week of a year - //! contains January 4 of that year. - //! In the ISO week-numbering system, it is possible for early-January dates - //! to be part of the 52nd or 53rd week of the previous year. - DUCKDB_API static int32_t ExtractISOWeekNumber(date_t date); - //! Extract the week number as Python handles it. - //! Either Monday or Sunday is the first day of the week, - //! and any date before the first Monday/Sunday returns week 0 - //! This is a bit more consistent because week numbers in a year are always incrementing - DUCKDB_API static int32_t ExtractWeekNumberRegular(date_t date, bool monday_first = true); - //! Returns the date of the monday of the current week. - DUCKDB_API static date_t GetMondayOfCurrentWeek(date_t date); +public: + LogicalType source_type() { + return child->return_type; + } - //! Helper function to parse two digits from a string (e.g. "30" -> 30, "03" -> 3, "3" -> 3) - DUCKDB_API static bool ParseDoubleDigit(const char *buf, idx_t len, idx_t &pos, int32_t &result); + //! Cast an expression to the specified SQL type if required + static unique_ptr AddCastToType(unique_ptr expr, const LogicalType &target_type); + //! 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); - DUCKDB_API static string ConversionError(const string &str); - DUCKDB_API static string ConversionError(string_t str); + string ToString() const override; -private: - static void ExtractYearOffset(int32_t &n, int32_t &year, int32_t &year_offset); + bool Equals(const BaseExpression *other) const override; + + unique_ptr Copy() override; }; } // namespace duckdb + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/arrow.hpp +// duckdb/planner/expression/bound_columnref_expression.hpp // // //===----------------------------------------------------------------------===// -#ifndef ARROW_FLAG_DICTIONARY_ORDERED -#include -#ifdef __cplusplus -extern "C" { -#endif -#define ARROW_FLAG_DICTIONARY_ORDERED 1 -#define ARROW_FLAG_NULLABLE 2 -#define ARROW_FLAG_MAP_KEYS_SORTED 4 -struct ArrowSchema { - // Array type description - const char *format; - const char *name; - const char *metadata; - int64_t flags; - int64_t n_children; - struct ArrowSchema **children; - struct ArrowSchema *dictionary; - // Release callback - void (*release)(struct ArrowSchema *); - // Opaque producer-specific data - void *private_data; -}; +namespace duckdb { -struct ArrowArray { - // Array data description - int64_t length; - int64_t null_count; - int64_t offset; - int64_t n_buffers; - int64_t n_children; - const void **buffers; - struct ArrowArray **children; - struct ArrowArray *dictionary; +//! 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); - // Release callback - void (*release)(struct ArrowArray *); - // Opaque producer-specific data - void *private_data; -}; + //! 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; -// EXPERIMENTAL -struct ArrowArrayStream { - // Callback to get the stream type - // (will be the same for all arrays in the stream). - // Return value: 0 if successful, an `errno`-compatible error code otherwise. - int (*get_schema)(struct ArrowArrayStream *, struct ArrowSchema *out); - // Callback to get the next array - // (if no error and the array is released, the stream has ended) - // Return value: 0 if successful, an `errno`-compatible error code otherwise. - int (*get_next)(struct ArrowArrayStream *, struct ArrowArray *out); +public: + bool IsScalar() const override { + return false; + } + bool IsFoldable() const override { + return false; + } - // Callback to get optional detailed error information. - // This must only be called if the last stream operation failed - // with a non-0 return code. The returned pointer is only valid until - // the next operation on this stream (including release). - // If unavailable, NULL is returned. - const char *(*get_last_error)(struct ArrowArrayStream *); + string ToString() const override; - // Release callback: release the stream's own resources. - // Note that arrays returned by `get_next` must be individually released. - void (*release)(struct ArrowArrayStream *); - // Opaque producer-specific data - void *private_data; -}; + bool Equals(const BaseExpression *other) const override; + hash_t Hash() const override; -#ifdef __cplusplus -} -#endif + unique_ptr Copy() override; +}; +} // namespace duckdb -#endif //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/types/blob.hpp +// duckdb/planner/expression/bound_comparison_expression.hpp // // //===----------------------------------------------------------------------===// @@ -11590,55 +14720,31 @@ struct ArrowArrayStream { - namespace duckdb { -//! The Blob class is a static class that holds helper functions for the Blob type. -class Blob { +class BoundComparisonExpression : public Expression { public: - // map of integer -> hex value - static constexpr const char *HEX_TABLE = "0123456789ABCDEF"; - // reverse map of byte -> integer value, or -1 for invalid hex values - static const int HEX_MAP[256]; - //! map of index -> base64 character - static constexpr const char *BASE64_MAP = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - //! padding character used in base64 encoding - static constexpr const char BASE64_PADDING = '='; + BoundComparisonExpression(ExpressionType type, unique_ptr left, unique_ptr right); -public: - //! Returns the string size of a blob -> string conversion - static idx_t GetStringSize(string_t blob); - //! Converts a blob to a string, writing the output to the designated output string. - //! The string needs to have space for at least GetStringSize(blob) bytes. - static void ToString(string_t blob, char *output); - //! Convert a blob object to a string - static string ToString(string_t blob); + unique_ptr left; + unique_ptr right; - //! Returns the blob size of a string -> blob conversion - static bool TryGetBlobSize(string_t str, idx_t &result_size, string *error_message); - static idx_t GetBlobSize(string_t str); - //! Convert a string to a blob. This function should ONLY be called after calling GetBlobSize, since it does NOT - //! perform data validation. - static void ToBlob(string_t str, data_ptr_t output); - //! Convert a string object to a blob - static string ToBlob(string_t str); +public: + string ToString() const override; - // base 64 conversion functions - //! Returns the string size of a blob -> base64 conversion - static idx_t ToBase64Size(string_t blob); - //! Converts a blob to a base64 string, output should have space for at least ToBase64Size(blob) bytes - static void ToBase64(string_t blob, char *output); + bool Equals(const BaseExpression *other) const override; - //! Returns the string size of a base64 string -> blob conversion - static idx_t FromBase64Size(string_t str); - //! Converts a base64 string to a blob, output should have space for at least FromBase64Size(blob) bytes - static void FromBase64(string_t str, data_ptr_t output, idx_t output_size); + unique_ptr Copy() override; + +public: + static LogicalType BindComparison(LogicalType left_type, LogicalType right_type); }; } // namespace duckdb + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/types/decimal.hpp +// duckdb/planner/expression/bound_conjunction_expression.hpp // // //===----------------------------------------------------------------------===// @@ -11649,26 +14755,26 @@ class Blob { namespace duckdb { -//! The Decimal class is a static class that holds helper functions for the Decimal type -class Decimal { +class BoundConjunctionExpression : public Expression { public: - static constexpr uint8_t MAX_WIDTH_INT16 = 4; - static constexpr uint8_t MAX_WIDTH_INT32 = 9; - static constexpr uint8_t MAX_WIDTH_INT64 = 18; - static constexpr uint8_t MAX_WIDTH_INT128 = 38; - static constexpr uint8_t MAX_WIDTH_DECIMAL = MAX_WIDTH_INT128; + explicit BoundConjunctionExpression(ExpressionType type); + BoundConjunctionExpression(ExpressionType type, unique_ptr left, unique_ptr right); + + vector> children; public: - static string ToString(int16_t value, uint8_t scale); - static string ToString(int32_t value, uint8_t scale); - static string ToString(int64_t value, uint8_t scale); - static string ToString(hugeint_t value, uint8_t scale); + string ToString() const override; + + bool Equals(const BaseExpression *other) const override; + + unique_ptr Copy() override; }; } // namespace duckdb + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/types/uuid.hpp +// duckdb/planner/expression/bound_constant_expression.hpp // // //===----------------------------------------------------------------------===// @@ -11680,37 +14786,26 @@ class Decimal { namespace duckdb { -//! The UUID class contains static operations for the UUID type -class UUID { +class BoundConstantExpression : public Expression { public: - //! Convert a uuid string to a hugeint object - static bool FromString(string str, hugeint_t &result); - //! Convert a uuid string to a hugeint object - static bool FromCString(const char *str, idx_t len, hugeint_t &result) { - return FromString(string(str, 0, len), result); - } - //! Convert a hugeint object to a uuid style string - static void ToString(hugeint_t input, char *buf); + explicit BoundConstantExpression(Value value); - //! Convert a hugeint object to a uuid style string - static string ToString(hugeint_t input) { - char buff[36]; - ToString(input, buff); - return string(buff, 36); - } + Value value; - static hugeint_t FromString(string str) { - hugeint_t result; - FromString(str, result); - return result; - } -}; +public: + string ToString() const override; + + bool Equals(const BaseExpression *other) const override; + hash_t Hash() const override; + unique_ptr Copy() override; +}; } // namespace duckdb + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/types/timestamp.hpp +// duckdb/planner/expression/bound_default_expression.hpp // // //===----------------------------------------------------------------------===// @@ -11719,71 +14814,36 @@ class UUID { - - namespace duckdb { -struct timestamp_struct { - int32_t year; - int8_t month; - int8_t day; - int8_t hour; - int8_t min; - int8_t sec; - int16_t msec; -}; -//! The Timestamp class is a static class that holds helper functions for the Timestamp -//! type. -class Timestamp { +class BoundDefaultExpression : public Expression { public: - //! Convert a string in the format "YYYY-MM-DD hh:mm:ss" to a timestamp object - DUCKDB_API static timestamp_t FromString(const string &str); - DUCKDB_API static bool TryConvertTimestamp(const char *str, idx_t len, timestamp_t &result); - DUCKDB_API static timestamp_t FromCString(const char *str, idx_t len); - //! Convert a date object to a string in the format "YYYY-MM-DD hh:mm:ss" - DUCKDB_API static string ToString(timestamp_t timestamp); - - DUCKDB_API static date_t GetDate(timestamp_t timestamp); - - DUCKDB_API static dtime_t GetTime(timestamp_t timestamp); - //! Create a Timestamp object from a specified (date, time) combination - 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); - - //! Extract the date and time from a given timestamp object - DUCKDB_API static void Convert(timestamp_t date, date_t &out_date, dtime_t &out_time); - //! Returns current timestamp - DUCKDB_API static timestamp_t GetCurrentTimestamp(); - - //! Convert the epoch (in sec) to a timestamp - DUCKDB_API static timestamp_t FromEpochSeconds(int64_t ms); - //! Convert the epoch (in ms) to a timestamp - DUCKDB_API static timestamp_t FromEpochMs(int64_t ms); - //! Convert the epoch (in microseconds) to a timestamp - DUCKDB_API static timestamp_t FromEpochMicroSeconds(int64_t micros); - //! Convert the epoch (in nanoseconds) to a timestamp - DUCKDB_API static timestamp_t FromEpochNanoSeconds(int64_t micros); + explicit BoundDefaultExpression(LogicalType type = LogicalType()) + : Expression(ExpressionType::VALUE_DEFAULT, ExpressionClass::BOUND_DEFAULT, type) { + } - //! Convert the epoch (in seconds) to a timestamp - DUCKDB_API static int64_t GetEpochSeconds(timestamp_t timestamp); - //! Convert the epoch (in ms) to a timestamp - DUCKDB_API static int64_t GetEpochMs(timestamp_t timestamp); - //! Convert a timestamp to epoch (in microseconds) - DUCKDB_API static int64_t GetEpochMicroSeconds(timestamp_t timestamp); - //! Convert a timestamp to epoch (in nanoseconds) - DUCKDB_API static int64_t GetEpochNanoSeconds(timestamp_t timestamp); +public: + bool IsScalar() const override { + return false; + } + bool IsFoldable() const override { + return false; + } - DUCKDB_API static bool TryParseUTCOffset(const char *str, idx_t &pos, idx_t len, int &hour_offset, - int &minute_offset); + string ToString() const override { + return "DEFAULT"; + } - DUCKDB_API static string ConversionError(const string &str); - DUCKDB_API static string ConversionError(string_t str); + unique_ptr Copy() override { + return make_unique(return_type); + } }; } // namespace duckdb + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/types/time.hpp +// duckdb/planner/expression/bound_function_expression.hpp // // //===----------------------------------------------------------------------===// @@ -11793,39 +14853,41 @@ class Timestamp { - namespace duckdb { +class ScalarFunctionCatalogEntry; -//! The Time class is a static class that holds helper functions for the Time -//! type. -class Time { +//! Represents a function call that has been bound to a base function +class BoundFunctionExpression : public Expression { 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); + BoundFunctionExpression(LogicalType return_type, ScalarFunction bound_function, + vector> arguments, unique_ptr bind_info, + bool is_operator = false); + + // The bound function expression + ScalarFunction function; + //! List of child-expressions of the function + vector> children; + //! The bound function data (if any) + unique_ptr bind_info; + //! Whether or not the function is an operator, only used for rendering + bool is_operator; - 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); +public: + bool HasSideEffects() const override; + bool IsFoldable() const override; + string ToString() const override; - DUCKDB_API static string ConversionError(const string &str); - DUCKDB_API static string ConversionError(string_t str); + hash_t Hash() const override; + bool Equals(const BaseExpression *other) const override; -private: - static bool TryConvertInternal(const char *buf, idx_t len, idx_t &pos, dtime_t &result, bool strict); + unique_ptr Copy() override; }; - } // namespace duckdb + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/serializer/buffered_serializer.hpp +// duckdb/planner/expression/bound_operator_expression.hpp // // //===----------------------------------------------------------------------===// @@ -11836,45 +14898,25 @@ class Time { namespace duckdb { -#define SERIALIZER_DEFAULT_SIZE 1024 - -struct BinaryData { - unique_ptr data; - idx_t size; -}; - -class BufferedSerializer : public Serializer { +class BoundOperatorExpression : public Expression { public: - //! Serializes to a buffer allocated by the serializer, will expand when - //! writing past the initial threshold - 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; + BoundOperatorExpression(ExpressionType type, LogicalType return_type); - BinaryData blob; + vector> children; public: - void WriteData(const_data_ptr_t buffer, uint64_t write_size) override; + string ToString() const override; - //! Retrieves the data after the writing has been completed - BinaryData GetData() { - return std::move(blob); - } + bool Equals(const BaseExpression *other) const override; - void Reset() { - blob.size = 0; - } + unique_ptr Copy() override; }; - } // namespace duckdb + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/main/appender.hpp +// duckdb/planner/expression/bound_parameter_expression.hpp // // //===----------------------------------------------------------------------===// @@ -11884,140 +14926,73 @@ class BufferedSerializer : public Serializer { - - namespace duckdb { -class ClientContext; -class DuckDB; -class TableCatalogEntry; -class Connection; - -//! The Appender class can be used to append elements to a table. -class Appender { - //! The amount of chunks that will be gathered in the chunk collection before flushing - static constexpr const idx_t FLUSH_COUNT = 100; +class BoundParameterExpression : public Expression { +public: + explicit BoundParameterExpression(idx_t parameter_nr); - //! A reference to a database connection that created this appender - shared_ptr context; - //! The table description (including column names) - unique_ptr description; - //! The append types - vector types; - //! The buffered data for the append - ChunkCollection collection; - //! Internal chunk used for appends - unique_ptr chunk; - //! The current column to append to - idx_t column = 0; + idx_t parameter_nr; + Value *value; 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(); + bool IsScalar() const override; + bool HasParameter() const override; + bool IsFoldable() const override; - //! 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(); + string ToString() const override; - // Append functions - template - void Append(T value) { - throw Exception("Undefined type for Appender::Append!"); - } + bool Equals(const BaseExpression *other) const override; + hash_t Hash() const override; - DUCKDB_API void Append(const char *value, uint32_t length); + unique_ptr Copy() override; +}; +} // namespace duckdb - // prepared statements - template - void AppendRow(Args... args) { - BeginRow(); - AppendRowRecursive(args...); - } +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/expression/bound_reference_expression.hpp +// +// +//===----------------------------------------------------------------------===// - //! 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; - } -private: - void InitializeChunk(); - void FlushChunk(); - template - void AppendValueInternal(T value); - template - void AppendValueInternal(Vector &vector, SRC input); - void AppendRowRecursive() { - EndRow(); - } +namespace duckdb { - template - void AppendRowRecursive(T value, Args... args) { - Append(value); - AppendRowRecursive(args...); +//! A BoundReferenceExpression represents a physical index into a DataChunk +class BoundReferenceExpression : public Expression { +public: + BoundReferenceExpression(string alias, LogicalType type, idx_t index); + BoundReferenceExpression(LogicalType type, idx_t index); + + //! Index used to access data in the chunks + idx_t index; + +public: + bool IsScalar() const override { + return false; + } + bool IsFoldable() const override { + return false; } - void AppendValue(const Value &value); -}; + string ToString() const override; -template <> -void DUCKDB_API Appender::Append(bool value); -template <> -void DUCKDB_API Appender::Append(int8_t value); -template <> -void DUCKDB_API Appender::Append(int16_t value); -template <> -void DUCKDB_API Appender::Append(int32_t value); -template <> -void DUCKDB_API Appender::Append(int64_t value); -template <> -void DUCKDB_API Appender::Append(hugeint_t value); -template <> -void DUCKDB_API Appender::Append(uint8_t value); -template <> -void DUCKDB_API Appender::Append(uint16_t value); -template <> -void DUCKDB_API Appender::Append(uint32_t value); -template <> -void DUCKDB_API Appender::Append(uint64_t value); -template <> -void DUCKDB_API Appender::Append(float value); -template <> -void DUCKDB_API Appender::Append(double value); -template <> -void DUCKDB_API Appender::Append(date_t value); -template <> -void DUCKDB_API Appender::Append(dtime_t value); -template <> -void DUCKDB_API Appender::Append(timestamp_t value); -template <> -void DUCKDB_API Appender::Append(interval_t value); -template <> -void DUCKDB_API Appender::Append(const char *value); -template <> -void DUCKDB_API Appender::Append(string_t value); -template <> -void DUCKDB_API Appender::Append(Value value); -template <> -void DUCKDB_API Appender::Append(std::nullptr_t value); + hash_t Hash() const override; + bool Equals(const BaseExpression *other) const override; + unique_ptr Copy() override; +}; } // namespace duckdb + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/main/client_context.hpp +// duckdb/planner/expression/bound_subquery_expression.hpp // // //===----------------------------------------------------------------------===// @@ -12027,7 +15002,7 @@ void DUCKDB_API Appender::Append(std::nullptr_t value); //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/catalog/catalog_entry/schema_catalog_entry.hpp +// duckdb/common/enums/subquery_type.hpp // // //===----------------------------------------------------------------------===// @@ -12035,10 +15010,26 @@ void DUCKDB_API Appender::Append(std::nullptr_t value); + +namespace duckdb { + +//===--------------------------------------------------------------------===// +// Subquery Types +//===--------------------------------------------------------------------===// +enum class SubqueryType : uint8_t { + INVALID = 0, + SCALAR = 1, // Regular scalar subquery + EXISTS = 2, // EXISTS (SELECT...) + NOT_EXISTS = 3, // NOT EXISTS(SELECT...) + ANY = 4, // x = ANY(SELECT...) OR x IN (SELECT...) +}; + +} // namespace duckdb + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/catalog/catalog_set.hpp +// duckdb/planner/binder.hpp // // //===----------------------------------------------------------------------===// @@ -12046,77 +15037,155 @@ void DUCKDB_API Appender::Append(std::nullptr_t value); + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/catalog/default/default_generator.hpp +// duckdb/parser/tokens.hpp // // //===----------------------------------------------------------------------===// +namespace duckdb { +//===--------------------------------------------------------------------===// +// Statements +//===--------------------------------------------------------------------===// +class SQLStatement; +class AlterStatement; +class CallStatement; +class CopyStatement; +class CreateStatement; +class DeleteStatement; +class DropStatement; +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; -namespace duckdb { -class ClientContext; +//===--------------------------------------------------------------------===// +// Query Node +//===--------------------------------------------------------------------===// +class QueryNode; +class SelectNode; +class SetOperationNode; +class RecursiveCTENode; -class DefaultGenerator { -public: - explicit DefaultGenerator(Catalog &catalog) : catalog(catalog), created_all_entries(false) { - } - virtual ~DefaultGenerator() { - } +//===--------------------------------------------------------------------===// +// Expressions +//===--------------------------------------------------------------------===// +class ParsedExpression; + +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; - Catalog &catalog; - atomic created_all_entries; +//===--------------------------------------------------------------------===// +// Constraints +//===--------------------------------------------------------------------===// +class Constraint; -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; -}; +class NotNullConstraint; +class CheckConstraint; +class UniqueConstraint; -} // namespace duckdb +//===--------------------------------------------------------------------===// +// TableRefs +//===--------------------------------------------------------------------===// +class TableRef; +class BaseTableRef; +class CrossProductRef; +class JoinRef; +class SubqueryRef; +class TableFunctionRef; +class EmptyTableRef; +class ExpressionListRef; + +//===--------------------------------------------------------------------===// +// Other +//===--------------------------------------------------------------------===// +struct SampleOptions; +} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/pair.hpp +// duckdb/planner/bind_context.hpp // // //===----------------------------------------------------------------------===// -#include - -namespace duckdb { -using std::make_pair; -using std::pair; -} // namespace duckdb - - //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/catalog/catalog_entry/table_catalog_entry.hpp +// 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: + TableFunctionCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateTableFunctionInfo *info); + + //! The table function + vector functions; +}; +} // namespace duckdb + + + + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/catalog/standard_entry.hpp +// duckdb/parser/expression/columnref_expression.hpp // // //===----------------------------------------------------------------------===// @@ -12125,29 +15194,59 @@ using std::pair; + namespace duckdb { -class SchemaCatalogEntry; -//! A StandardEntry is a catalog entry that is a member of a schema -class StandardEntry : public CatalogEntry { +//! Represents a reference to a column from either the FROM clause or from an +//! alias +class ColumnRefExpression : public ParsedExpression { public: - StandardEntry(CatalogType type, SchemaCatalogEntry *schema, Catalog *catalog, string name) - : CatalogEntry(type, catalog, name), schema(schema) { - } - ~StandardEntry() override { + //! 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); + + //! The stack of names in order of which they appear (column_names[0].column_names[1].column_names[2]....) + vector column_names; + +public: + bool IsQualified() const; + const string &GetColumnName() const; + const string &GetTableName() const; + bool IsScalar() const override { + return false; } - //! The schema the entry belongs to - SchemaCatalogEntry *schema; + string GetName() const override; + string ToString() const override; + + static bool Equals(const ColumnRefExpression *a, const ColumnRefExpression *b); + hash_t Hash() const override; + + unique_ptr Copy() const override; + + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(ExpressionType type, FieldReader &source); }; } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/qualified_name_set.hpp +// +// +//===----------------------------------------------------------------------===// + + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/parser/constraint.hpp +// duckdb/parser/qualified_name.hpp // // //===----------------------------------------------------------------------===// @@ -12156,48 +15255,80 @@ class StandardEntry : public CatalogEntry { + namespace duckdb { -class Serializer; -class Deserializer; +struct QualifiedName { + string schema; + string name; -//===--------------------------------------------------------------------===// -// 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 + //! 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(string input) { + string schema; + string name; + idx_t idx = 0; + vector entries; + string entry; + normal: + //! quote + for (; idx < input.size(); idx++) { + if (input[idx] == '"') { + idx++; + goto quoted; + } else if (input[idx] == '.') { + goto separator; + } + entry += input[idx]; + } + goto end; + separator: + entries.push_back(entry); + entry = ""; + idx++; + goto normal; + 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!"); + end: + if (entries.empty()) { + schema = INVALID_SCHEMA; + name = entry; + } else if (entries.size() == 1) { + schema = entries[0]; + name = entry; + } else { + throw ParserException("Expected schema.entry or entry: too many entries found"); + } + return QualifiedName {schema, name}; + } }; -//! Constraint is the base class of any type of table constraint. -class Constraint { -public: - explicit Constraint(ConstraintType type) : type(type) {}; - virtual ~Constraint() { +struct QualifiedColumnName { + QualifiedColumnName() { + } + QualifiedColumnName(string table_p, string column_p) : table(move(table_p)), column(move(column_p)) { } - ConstraintType type; - -public: - virtual string ToString() const = 0; - void Print(); - - virtual unique_ptr Copy() = 0; - //! Serializes a Constraint to a stand-alone binary blob - virtual void Serialize(Serializer &serializer); - //! Deserializes a blob back into a Constraint, returns NULL if - //! deserialization is not possible - static unique_ptr Deserialize(Deserializer &source); + string schema; + string table; + string column; }; + } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/planner/bound_constraint.hpp +// duckdb/common/types/hash.hpp // // //===----------------------------------------------------------------------===// @@ -12208,373 +15339,764 @@ class Constraint { namespace duckdb { -//! Bound equivalent of Constraint -class BoundConstraint { -public: - explicit BoundConstraint(ConstraintType type) : type(type) {}; - virtual ~BoundConstraint() { + +struct string_t; + +// efficient hash function that maximizes the avalanche effect and minimizes +// bias +// see: https://nullprogram.com/blog/2018/07/31/ + +inline hash_t murmurhash64(uint64_t x) { + return x * UINT64_C(0xbf58476d1ce4e5b9); +} + +inline hash_t murmurhash32(uint32_t x) { + return murmurhash64(x); +} + +template +hash_t Hash(T value) { + return murmurhash32(value); +} + +//! Combine two hashes by XORing them +inline hash_t CombineHash(hash_t left, hash_t right) { + return left ^ right; +} + +template <> +hash_t Hash(uint64_t val); +template <> +hash_t Hash(int64_t val); +template <> +hash_t Hash(hugeint_t val); +template <> +hash_t Hash(float val); +template <> +hash_t Hash(double val); +template <> +hash_t Hash(const char *val); +template <> +hash_t Hash(char *val); +template <> +hash_t Hash(string_t val); +template <> +hash_t Hash(interval_t val); +hash_t Hash(const char *val, size_t size); +hash_t Hash(uint8_t *val, size_t size); + +} // namespace duckdb + + + +namespace duckdb { + +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); } +}; - ConstraintType type; +struct QualifiedColumnEquality { + bool operator()(const QualifiedColumnName &a, const QualifiedColumnName &b) const { + return a.schema == b.schema && a.table == b.table && a.column == b.column; + } }; -} // namespace duckdb +using qualified_column_set_t = unordered_set; +} // namespace duckdb -namespace duckdb { +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/expression_binder.hpp +// +// +//===----------------------------------------------------------------------===// -class ColumnStatistics; -class DataTable; -struct CreateTableInfo; -struct BoundCreateTableInfo; -struct RenameColumnInfo; -struct AddColumnInfo; -struct RemoveColumnInfo; -struct SetDefaultInfo; -struct ChangeColumnTypeInfo; -//! 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 - vector 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; - //! A map of column name to column index - case_insensitive_map_t name_map; +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/expression/bound_expression.hpp +// +// +//===----------------------------------------------------------------------===// -public: - unique_ptr AlterEntry(ClientContext &context, AlterInfo *info) override; - //! Returns whether or not a column with the given name exists - 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 - vector GetTypes(); - string ToSQL() override; - //! Serialize the meta information of the TableCatalogEntry a serializer - virtual void Serialize(Serializer &serializer); - //! Deserializes to a CreateTableInfo - static unique_ptr Deserialize(Deserializer &source); - 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_exists is true, returns INVALID_INDEX - //! If if_exists is false, throws an exception - idx_t 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); +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) + : ParsedExpression(ExpressionType::INVALID, ExpressionClass::BOUND_EXPRESSION), expr(move(expr)) { + } + + unique_ptr expr; + +public: + string ToString() const override { + return expr->ToString(); + } + + bool Equals(const BaseExpression *other) const override { + return false; + } + hash_t Hash() const override { + return 0; + } + + unique_ptr Copy() const override { + throw SerializationException("Cannot copy or serialize bound expression"); + } + + void Serialize(FieldWriter &writer) const override { + throw SerializationException("Cannot copy or serialize bound expression"); + } }; + } // namespace duckdb -#include -#include + + + + namespace duckdb { -struct AlterInfo; +class Binder; class ClientContext; +class QueryNode; -typedef unordered_map> set_lock_map_t; +class ScalarFunctionCatalogEntry; +class AggregateFunctionCatalogEntry; +class MacroCatalogEntry; +class CatalogEntry; +class SimpleFunction; -struct MappingValue { - explicit MappingValue(idx_t index_) : index(index_), timestamp(0), deleted(false), parent(nullptr) { +struct MacroBinding; + +struct BoundColumnReferenceInfo { + string name; + idx_t query_location; +}; + +struct BindResult { + BindResult() { + } + explicit BindResult(string error) : error(error) { + } + explicit BindResult(unique_ptr expr) : expression(move(expr)) { } - idx_t index; - transaction_t timestamp; - bool deleted; - unique_ptr child; - MappingValue *parent; + bool HasError() { + return !error.empty(); + } + + unique_ptr expression; + string error; }; -//! The Catalog Set stores (key, value) map of a set of CatalogEntries -class CatalogSet { - friend class DependencyManager; +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; public: - explicit CatalogSet(Catalog &catalog, unique_ptr defaults = nullptr); + unique_ptr Bind(unique_ptr &expr, LogicalType *result_type = nullptr, + bool root_expression = true); - //! Create an entry in the catalog set. Returns whether or not it was - //! successful. - bool CreateEntry(ClientContext &context, const string &name, unique_ptr value, - unordered_set &dependencies); + //! 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 AlterEntry(ClientContext &context, const string &name, AlterInfo *alter_info); + string Bind(unique_ptr *expr, idx_t depth, bool root_expression = false); - bool DropEntry(ClientContext &context, const string &name, bool cascade); + unique_ptr CreateStructExtract(unique_ptr base, string field_name); + BindResult BindQualifiedColumnName(ColumnRefExpression &colref, const string &table_name); - void CleanupEntry(CatalogEntry *catalog_entry); + unique_ptr QualifyColumnName(const string &column_name, string &error_message); + unique_ptr QualifyColumnName(ColumnRefExpression &colref, string &error_message); - //! Returns the entry with the specified name - CatalogEntry *GetEntry(ClientContext &context, const string &name); + // Bind table names to ColumnRefExpressions + void QualifyColumnNames(unique_ptr &expr); + static void QualifyColumnNames(Binder &binder, unique_ptr &expr); - //! 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); + static unique_ptr PushCollation(ClientContext &context, unique_ptr source, + const string &collation, bool equality_only = false); + static void TestCollation(ClientContext &context, const string &collation); - //! Rollback to be the currently valid entry for a certain catalog - //! entry - void Undo(CatalogEntry *entry); + bool BindCorrelatedColumns(unique_ptr &expr); - //! Scan the catalog set, invoking the callback method for every committed entry - void Scan(const std::function &callback); - //! Scan the catalog set, invoking the callback method for every entry - void Scan(ClientContext &context, const std::function &callback); + void BindChild(unique_ptr &expr, idx_t depth, string &error); + static void ExtractCorrelatedExpressions(Binder &binder, Expression &expr); - template - vector GetEntries(ClientContext &context) { - vector result; - Scan(context, [&](CatalogEntry *entry) { result.push_back((T *)entry); }); - return result; - } + 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); - static bool HasConflict(ClientContext &context, transaction_t timestamp); - static bool UseTimestamp(ClientContext &context, transaction_t timestamp); + static void ResolveParameterType(LogicalType &type); + static void ResolveParameterType(unique_ptr &expr); - CatalogEntry *GetEntryFromIndex(idx_t index); - void UpdateTimestamp(CatalogEntry *entry, transaction_t timestamp); + //! 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); -private: - //! Adjusts table dependencies on the event of an UNDO - void AdjustTableDependencies(CatalogEntry *entry); - //! Adjust one dependency - void AdjustDependency(CatalogEntry *entry, TableCatalogEntry *table, ColumnDefinition &column, bool remove); - //! Adjust Enum dependency - void AdjustEnumDependency(CatalogEntry *entry, ColumnDefinition &column, bool remove); - //! Given a root entry, gets the entry valid for this transaction - CatalogEntry *GetEntryForTransaction(ClientContext &context, CatalogEntry *current); - CatalogEntry *GetCommittedEntry(CatalogEntry *current); - bool GetEntryInternal(ClientContext &context, const string &name, idx_t &entry_index, CatalogEntry *&entry); - bool GetEntryInternal(ClientContext &context, idx_t entry_index, CatalogEntry *&entry); - //! Drops an entry from the catalog set; must hold the catalog_lock to safely call this - void DropEntryInternal(ClientContext &context, idx_t entry_index, CatalogEntry &entry, bool cascade, - set_lock_map_t &lock_set); - 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, idx_t entry_index); - void DeleteMapping(ClientContext &context, const string &name); +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); + BindResult BindExpression(OperatorExpression &expr, idx_t depth); + BindResult BindExpression(ParameterExpression &expr, idx_t depth); + BindResult BindExpression(PositionalReferenceExpression &ref, idx_t depth); + BindResult BindExpression(StarExpression &expr, idx_t depth); + BindResult BindExpression(SubqueryExpression &expr, idx_t depth); -private: - Catalog &catalog; - //! The catalog lock is used to make changes to the data - mutex catalog_lock; - //! Mapping of string to catalog entry - case_insensitive_map_t> mapping; - //! The set of catalog entries - unordered_map> entries; - //! The current catalog entry index - idx_t current_entry = 0; - //! The generator used to generate default internal entries - unique_ptr defaults; +protected: + virtual BindResult BindGroupingFunction(OperatorExpression &op, idx_t depth); + virtual BindResult BindFunction(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, MacroCatalogEntry *macro, idx_t depth, + unique_ptr *expr_ptr); + + void ReplaceMacroParametersRecursive(unique_ptr &expr); + + virtual string UnsupportedAggregateMessage(); + virtual string UnsupportedUnnestMessage(); + + Binder &binder; + ClientContext &context; + ExpressionBinder *stored_binder; + MacroBinding *macro_binding; + vector bound_columns; }; } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/table_binding.hpp +// +// +//===----------------------------------------------------------------------===// + -namespace duckdb { -class ClientContext; -class StandardEntry; + + + + + +namespace duckdb { +class BindContext; +class BoundQueryNode; +class ColumnRefExpression; +class SubqueryRef; +class LogicalGet; class TableCatalogEntry; class TableFunctionCatalogEntry; -class SequenceCatalogEntry; -class Serializer; -class Deserializer; +class BoundTableFunction; -enum class OnCreateConflict : uint8_t; +//! A Binding represents a binding to a table, table-producing function or subquery with a specified table index. +struct Binding { + Binding(const string &alias, vector types, vector names, idx_t index); + virtual ~Binding() = default; -struct AlterTableInfo; -struct CreateIndexInfo; -struct CreateFunctionInfo; -struct CreateCollationInfo; -struct CreateViewInfo; -struct BoundCreateTableInfo; -struct CreatePragmaFunctionInfo; -struct CreateSequenceInfo; -struct CreateSchemaInfo; -struct CreateTableFunctionInfo; -struct CreateCopyFunctionInfo; -struct CreateTypeInfo; + //! 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; -struct DropInfo; +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 TableCatalogEntry *GetTableEntry(); +}; -//! A schema in the catalog -class SchemaCatalogEntry : public CatalogEntry { - friend class Catalog; +//! 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, LogicalGet &get, idx_t index, + bool add_row_id = false); + + //! the underlying LogicalGet + LogicalGet &get; public: - SchemaCatalogEntry(Catalog *catalog, string name, bool is_internal); + BindResult Bind(ColumnRefExpression &colref, idx_t depth) override; + TableCatalogEntry *GetTableEntry() override; + string ColumnNotFoundError(const string &column_name) const override; +}; -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; +//! MacroBinding is like the Binding, except the alias and index are set by default. Used for binding Macro +//! Params/Arguments. +struct MacroBinding : public Binding { + static constexpr const char *MACRO_NAME = "0_macro_parameters"; public: - //! Scan the specified catalog set, invoking the callback method for every entry - void Scan(ClientContext &context, CatalogType type, const std::function &callback); - //! Scan the specified catalog set, invoking the callback method for every committed entry - void Scan(CatalogType type, const std::function &callback); + MacroBinding(vector types_p, vector names_p, string macro_name); - //! Serialize the meta information of the SchemaCatalogEntry a serializer - virtual void Serialize(Serializer &serializer); - //! Deserializes to a CreateSchemaInfo - static unique_ptr Deserialize(Deserializer &source); + //! Arguments + vector> arguments; + //! The name of the macro + string macro_name; - string ToSQL() override; +public: + BindResult Bind(ColumnRefExpression &colref, idx_t depth) override; - //! Creates an index with the given name in the schema - CatalogEntry *CreateIndex(ClientContext &context, CreateIndexInfo *info, TableCatalogEntry *table); + //! Given the parameter colref, returns a copy of the argument that was supplied for this parameter + unique_ptr ParamToArg(ColumnRefExpression &colref); +}; -private: - //! Create a scalar or aggregate function within the given schema - CatalogEntry *CreateFunction(ClientContext &context, CreateFunctionInfo *info); - //! Creates a table with the given name in the schema - CatalogEntry *CreateTable(ClientContext &context, BoundCreateTableInfo *info); - //! Creates a view with the given name in the schema - CatalogEntry *CreateView(ClientContext &context, CreateViewInfo *info); - //! Creates a sequence with the given name in the schema - CatalogEntry *CreateSequence(ClientContext &context, CreateSequenceInfo *info); - //! Create a table function within the given schema - CatalogEntry *CreateTableFunction(ClientContext &context, CreateTableFunctionInfo *info); - //! Create a copy function within the given schema - CatalogEntry *CreateCopyFunction(ClientContext &context, CreateCopyFunctionInfo *info); - //! Create a pragma function within the given schema - CatalogEntry *CreatePragmaFunction(ClientContext &context, CreatePragmaFunctionInfo *info); - //! Create a collation within the given schema - CatalogEntry *CreateCollation(ClientContext &context, CreateCollationInfo *info); - //! Create a enum within the given schema - CatalogEntry *CreateType(ClientContext &context, CreateTypeInfo *info); +} // namespace duckdb - //! Drops an entry from the schema - void DropEntry(ClientContext &context, DropInfo *info); - //! Alters a catalog entry - void Alter(ClientContext &context, AlterInfo *info); +namespace duckdb { +class Binder; +class LogicalGet; +class BoundQueryNode; + +class StarExpression; + +struct UsingColumnSet { + string primary_binding; + unordered_set bindings; +}; + +//! 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; + +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); + + 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); + + 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; + } + + //! 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, + LogicalGet &get); + //! 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, LogicalGet &get); + //! Adds a subquery with a given alias to the BindContext. + void AddSubquery(idx_t index, const string &alias, SubqueryRef &ref, BoundQueryNode &subquery); + //! 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); + + //! 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); + + //! Add an implicit join condition (e.g. USING (x)) + void AddUsingBinding(const string &column_name, UsingColumnSet *set); + + void AddUsingBindingSet(unique_ptr set); + + //! 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); + + //! 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); + + case_insensitive_map_t> GetCTEBindings() { + return cte_bindings; + } + void SetCTEBindings(case_insensitive_map_t> bindings) { + cte_bindings = bindings; + } + + //! 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); + + //! Add all the bindings from a BindContext to this BindContext. The other BindContext is destroyed in the process. + void AddContext(BindContext other); + + //! 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); - //! 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); +private: + void AddBinding(const string &alias, unique_ptr binding); - //! Get the catalog set for the specified type - CatalogSet &GetCatalogSet(CatalogType type); +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 set of CTE bindings + case_insensitive_map_t> cte_bindings; }; } // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/deque.hpp -// -// -//===----------------------------------------------------------------------===// -#include + namespace duckdb { -using std::deque; -} -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/enums/output_type.hpp -// -// -//===----------------------------------------------------------------------===// +class BoundResultModifier; +class BoundSelectNode; +class ClientContext; +class ExpressionBinder; +class LimitModifier; +class OrderBinder; +class TableCatalogEntry; +class ViewCatalogEntry; +struct CreateInfo; +struct BoundCreateTableInfo; +struct BoundCreateFunctionInfo; +struct CommonTableExpressionInfo; +enum class BindingMode : uint8_t { STANDARD_BINDING, EXTRACT_NAMES }; +struct CorrelatedColumnInfo { + ColumnBinding binding; + LogicalType type; + string name; + idx_t depth; + explicit CorrelatedColumnInfo(BoundColumnRefExpression &expr) + : binding(expr.binding), type(expr.return_type), name(expr.GetName()), depth(expr.depth) { + } -namespace duckdb { + bool operator==(const CorrelatedColumnInfo &rhs) const { + return binding == rhs.binding; + } +}; -enum class ExplainOutputType : uint8_t { ALL = 0, OPTIMIZED_ONLY = 1, PHYSICAL_ONLY = 2 }; +//! 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; -} // namespace duckdb +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 + vector *parameters; + //! Whether or not the bound statement is read-only + bool read_only; + //! Whether or not the statement requires a valid transaction to run + bool requires_valid_transaction; + //! Whether or not the statement can be streamed to the client + bool allow_stream_result; + //! The alias for the currently processing subquery, if it exists + string alias; + //! Macro parameter bindings (if any) + MacroBinding *macro_binding = nullptr; -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/progress_bar.hpp -// -// -//===----------------------------------------------------------------------===// +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); -#ifndef DUCKDB_NO_THREADS -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/thread.hpp -// -// -//===----------------------------------------------------------------------===// + unique_ptr Bind(TableRef &ref); + unique_ptr CreatePlan(BoundTableRef &ref); + //! Generates an unused index for a table + idx_t GenerateTableIndex(); + //! 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); -#include + bool CTEIsAlreadyBound(CommonTableExpressionInfo *cte); -namespace duckdb { -using std::thread; -} + //! Add the view to the set of currently bound views - used for detecting recursive view definitions + void AddBoundView(ViewCatalogEntry *view); -#include -#endif + 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); + + string FormatError(ParsedExpression &expr_context, const string &message); + string FormatError(TableRef &ref_context, const string &message); + + 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...); + } + + 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(); + +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; + +private: + //! Bind the default values of the columns of a table + void BindDefaultValues(vector &columns, vector> &bound_defaults); + //! Bind a delimiter value (LIMIT or OFFSET) + unique_ptr BindDelimiter(ClientContext &context, 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(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(SetStatement &stmt); + BoundStatement Bind(LoadStatement &stmt); + + unique_ptr BindNode(SelectNode &node); + unique_ptr BindNode(SetOperationNode &node); + unique_ptr BindNode(RecursiveCTENode &node); + unique_ptr BindNode(QueryNode &node); + + 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); + + 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); + + bool BindFunctionParameters(vector> &expressions, vector &arguments, + vector ¶meters, named_parameter_map_t &named_parameters, + unique_ptr &subquery, string &error); + + 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); + + unique_ptr BindTable(TableCatalogEntry &table, BaseTableRef &ref); + unique_ptr BindView(ViewCatalogEntry &view, BaseTableRef &ref); + unique_ptr BindTableOrView(BaseTableRef &ref); + + 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(LimitModifier &limit_mod); + unique_ptr BindLimitPercent(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); + + string FindBinding(const string &using_column, const string &join_side); + bool TryFindBinding(const string &using_column, const string &join_side, string &result); + + void AddUsingBindingSet(unique_ptr set); + string RetrieveUsingBinding(Binder ¤t_binder, UsingColumnSet *current_set, const string &column_name, + const string &join_side, UsingColumnSet *new_set); + +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); +}; + +} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/execution/executor.hpp +// duckdb/planner/bound_query_node.hpp // // //===----------------------------------------------------------------------===// @@ -12586,7 +16108,7 @@ using std::thread; //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/parallel/pipeline.hpp +// duckdb/parser/query_node.hpp // // //===----------------------------------------------------------------------===// @@ -12594,22 +16116,23 @@ using std::thread; + + + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/execution/physical_operator.hpp +// duckdb/parser/common_table_expression_info.hpp // // //===----------------------------------------------------------------------===// - - //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/enums/physical_operator_type.hpp +// duckdb/parser/statement/select_statement.hpp // // //===----------------------------------------------------------------------===// @@ -12618,97 +16141,23 @@ using std::thread; -namespace duckdb { - -//===--------------------------------------------------------------------===// -// Physical Operator Types -//===--------------------------------------------------------------------===// -enum class PhysicalOperatorType : uint8_t { - INVALID, - ORDER_BY, - LIMIT, - TOP_N, - WINDOW, - UNNEST, - SIMPLE_AGGREGATE, - HASH_GROUP_BY, - PERFECT_HASH_GROUP_BY, - FILTER, - PROJECTION, - COPY_TO_FILE, - RESERVOIR_SAMPLE, - STREAMING_SAMPLE, - // ----------------------------- - // Scans - // ----------------------------- - TABLE_SCAN, - DUMMY_SCAN, - CHUNK_SCAN, - RECURSIVE_CTE_SCAN, - DELIM_SCAN, - EXPRESSION_SCAN, - // ----------------------------- - // Joins - // ----------------------------- - BLOCKWISE_NL_JOIN, - NESTED_LOOP_JOIN, - HASH_JOIN, - CROSS_PRODUCT, - PIECEWISE_MERGE_JOIN, - DELIM_JOIN, - INDEX_JOIN, - // ----------------------------- - // SetOps - // ----------------------------- - UNION, - RECURSIVE_CTE, - - // ----------------------------- - // Updates - // ----------------------------- - INSERT, - DELETE_OPERATOR, - UPDATE, - // ----------------------------- - // Schema - // ----------------------------- - CREATE_TABLE, - CREATE_TABLE_AS, - CREATE_INDEX, - ALTER, - CREATE_SEQUENCE, - CREATE_VIEW, - CREATE_SCHEMA, - CREATE_MACRO, - DROP, - PRAGMA, - TRANSACTION, - CREATE_TYPE, - // ----------------------------- - // Helpers - // ----------------------------- - EXPLAIN, - EMPTY_RESULT, - EXECUTE, - PREPARE, - VACUUM, - EXPORT, - SET, - LOAD, - INOUT_FUNCTION -}; +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/tableref.hpp +// +// +//===----------------------------------------------------------------------===// -string PhysicalOperatorToString(PhysicalOperatorType type); -} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/execution/execution_context.hpp +// duckdb/common/enums/tableref_type.hpp // // //===----------------------------------------------------------------------===// @@ -12718,18 +16167,20 @@ string PhysicalOperatorToString(PhysicalOperatorType type); namespace duckdb { -class ClientContext; -class ThreadContext; -class ExecutionContext { -public: - ExecutionContext(ClientContext &client_p, ThreadContext &thread_p) : client(client_p), thread(thread_p) { - } - - //! 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; +//===--------------------------------------------------------------------===// +// 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 }; } // namespace duckdb @@ -12737,7 +16188,7 @@ class ExecutionContext { //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/enums/operator_result_type.hpp +// duckdb/parser/parsed_data/sample_options.hpp // // //===----------------------------------------------------------------------===// @@ -12746,477 +16197,643 @@ class ExecutionContext { -namespace duckdb { - -//! 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 }; - -//! 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 namespace duckdb { -class Event; -class PhysicalOperator; -class Pipeline; -// LCOV_EXCL_START -class OperatorState { -public: - virtual ~OperatorState() { - } - - virtual void Finalize(PhysicalOperator *op, ExecutionContext &context) { - } -}; - -class GlobalSinkState { -public: - GlobalSinkState() : state(SinkFinalizeType::READY) { - } - virtual ~GlobalSinkState() { - } +enum class SampleMethod : uint8_t { SYSTEM_SAMPLE = 0, BERNOULLI_SAMPLE = 1, RESERVOIR_SAMPLE = 2 }; - SinkFinalizeType state; -}; - -class LocalSinkState { -public: - virtual ~LocalSinkState() { - } -}; +string SampleMethodToString(SampleMethod method); -class GlobalSourceState { -public: - virtual ~GlobalSourceState() { - } +struct SampleOptions { + Value sample_size; + bool is_percentage; + SampleMethod method; + int64_t seed = -1; - virtual idx_t MaxThreads() { - return 1; - } + unique_ptr Copy(); + void Serialize(Serializer &serializer); + static unique_ptr Deserialize(Deserializer &source); + static bool Equals(SampleOptions *a, SampleOptions *b); }; -class LocalSourceState { -public: - virtual ~LocalSourceState() { - } -}; -// LCOV_EXCL_STOP +} // namespace duckdb -//! PhysicalOperator is the base class of the physical operators present in the -//! execution plan -class PhysicalOperator { + +namespace duckdb { +class Deserializer; +class Serializer; + +//! Represents a generic expression that returns a table. +class TableRef { public: - PhysicalOperator(PhysicalOperatorType type, vector types, idx_t estimated_cardinality) - : type(type), types(std::move(types)), estimated_cardinality(estimated_cardinality) { + explicit TableRef(TableReferenceType type) : type(type) { } - virtual ~PhysicalOperator() { + virtual ~TableRef() { } - //! The physical operator type - PhysicalOperatorType type; - //! The set of children of the operator - vector> children; - //! The types returned by this physical operator - vector types; - //! The extimated cardinality of this physical operator - idx_t estimated_cardinality; - //! The global sink state of this operator - unique_ptr sink_state; + 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; public: - virtual string GetName() const; - virtual string ParamsToString() const { - return ""; - } + //! Convert the object to a string virtual string ToString() const; - void Print() const; + void Print(); - //! Return a vector of the types that will be returned by this operator - const vector &GetTypes() const { - return types; - } + virtual bool Equals(const TableRef *other) const; - virtual bool Equals(const PhysicalOperator &other) const { - return false; - } + virtual unique_ptr Copy() = 0; -public: - // Operator interface - virtual unique_ptr GetOperatorState(ClientContext &context) const; - virtual OperatorResultType Execute(ExecutionContext &context, DataChunk &input, DataChunk &chunk, - OperatorState &state) const; + //! 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); - virtual bool ParallelOperator() const { - return false; - } + //! Copy the properties of this table ref to the target + void CopyProperties(TableRef &target) const; +}; +} // namespace duckdb - virtual bool RequiresCache() const { - return false; - } -public: - // Source interface - virtual unique_ptr GetLocalSourceState(ExecutionContext &context, - GlobalSourceState &gstate) const; - virtual unique_ptr GetGlobalSourceState(ClientContext &context) const; - virtual void GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate, - LocalSourceState &lstate) const; +namespace duckdb { - virtual bool IsSource() const { - return false; - } +class QueryNode; - virtual bool ParallelSource() const { - return false; +//! SelectStatement is a typical SELECT clause +class SelectStatement : public SQLStatement { +public: + SelectStatement() : SQLStatement(StatementType::SELECT_STATEMENT) { } -public: - // Sink interface + //! The main query node + unique_ptr node; - //! The sink method is called constantly with new input, as long as new input is available. Note that this method - //! CAN be called in parallel, proper locking is needed when accessing data inside the GlobalSinkState. - virtual SinkResultType Sink(ExecutionContext &context, GlobalSinkState &gstate, LocalSinkState &lstate, - DataChunk &input) const; - // The combine is called when a single thread has completed execution of its part of the pipeline, it is the final - // time that a specific LocalSinkState is accessible. This method can be called in parallel while other Sink() or - // Combine() calls are active on the same GlobalSinkState. - virtual void Combine(ExecutionContext &context, GlobalSinkState &gstate, LocalSinkState &lstate) const; - //! The finalize is called when ALL threads are finished execution. It is called only once per pipeline, and is - //! entirely single threaded. - //! If Finalize returns SinkResultType::FINISHED, the sink is marked as finished - virtual SinkFinalizeType Finalize(Pipeline &pipeline, Event &event, ClientContext &context, - GlobalSinkState &gstate) const; +protected: + SelectStatement(const SelectStatement &other); - virtual unique_ptr GetLocalSinkState(ExecutionContext &context) const; - virtual unique_ptr GetGlobalSinkState(ClientContext &context) const; +public: + //! 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 - virtual bool IsSink() const { - return false; - } - virtual bool ParallelSink() const { - return false; - } +namespace duckdb { - virtual bool SinkOrderMatters() const { - return false; - } +class SelectStatement; + +struct CommonTableExpressionInfo { + vector aliases; + unique_ptr query; }; } // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/function/table_function.hpp -// -// -//===----------------------------------------------------------------------===// +namespace duckdb { +enum QueryNodeType : uint8_t { + SELECT_NODE = 1, + SET_OPERATION_NODE = 2, + BOUND_SUBQUERY_NODE = 3, + RECURSIVE_CTE_NODE = 4 +}; +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) + unordered_map> cte_map; + virtual const vector> &GetSelectList() const = 0; +public: + 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); + +protected: + //! Copy base QueryNode properties from another expression to this one, + //! used in Copy method + void CopyProperties(QueryNode &other) const; +}; + +} // namespace duckdb -#include namespace duckdb { -class BaseStatistics; -class LogicalGet; -struct ParallelState; -class TableFilterSet; -struct FunctionOperatorData { - virtual ~FunctionOperatorData() { +//! Bound equivalent of QueryNode +class BoundQueryNode { +public: + explicit BoundQueryNode(QueryNodeType type) : type(type) { } -}; - -struct TableFilterCollection { - TableFilterSet *table_filters; - explicit TableFilterCollection(TableFilterSet *table_filters) : table_filters(table_filters) { + virtual ~BoundQueryNode() { } + + //! The type of the query node, either SetOperation or Select + QueryNodeType type; + //! The result modifiers that should be applied to this query node + vector> modifiers; + + //! The names returned by this QueryNode. + vector names; + //! The types returned by this QueryNode. + vector types; + +public: + virtual idx_t GetRootIndex() = 0; }; -typedef unique_ptr (*table_function_bind_t)(ClientContext &context, vector &inputs, - unordered_map &named_parameters, - vector &input_table_types, - vector &input_table_names, - vector &return_types, vector &names); -typedef unique_ptr (*table_function_init_t)(ClientContext &context, const FunctionData *bind_data, - const vector &column_ids, - TableFilterCollection *filters); -typedef unique_ptr (*table_statistics_t)(ClientContext &context, const FunctionData *bind_data, - column_t column_index); -typedef void (*table_function_t)(ClientContext &context, const FunctionData *bind_data, - FunctionOperatorData *operator_state, DataChunk *input, DataChunk &output); +} // namespace duckdb -typedef void (*table_function_parallel_t)(ClientContext &context, const FunctionData *bind_data, - FunctionOperatorData *operator_state, DataChunk *input, DataChunk &output, - ParallelState *parallel_state); -typedef void (*table_function_cleanup_t)(ClientContext &context, const FunctionData *bind_data, - FunctionOperatorData *operator_state); -typedef idx_t (*table_function_max_threads_t)(ClientContext &context, const FunctionData *bind_data); -typedef unique_ptr (*table_function_init_parallel_state_t)(ClientContext &context, - const FunctionData *bind_data, - const vector &column_ids, - TableFilterCollection *filters); -typedef unique_ptr (*table_function_init_parallel_t)(ClientContext &context, - const FunctionData *bind_data, - ParallelState *state, - const vector &column_ids, - TableFilterCollection *filters); -typedef bool (*table_function_parallel_state_next_t)(ClientContext &context, const FunctionData *bind_data, - FunctionOperatorData *state, ParallelState *parallel_state); -typedef int (*table_function_progress_t)(ClientContext &context, const FunctionData *bind_data); -typedef void (*table_function_dependency_t)(unordered_set &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, - FunctionData *bind_data, - vector> &filters); -typedef string (*table_function_to_string_t)(const FunctionData *bind_data); -class TableFunction : public SimpleNamedParameterFunction { +namespace duckdb { + +class BoundSubqueryExpression : public Expression { public: - TableFunction(string name, vector arguments, table_function_t function, - table_function_bind_t bind = nullptr, table_function_init_t init = nullptr, - table_statistics_t statistics = nullptr, table_function_cleanup_t cleanup = nullptr, - table_function_dependency_t dependency = nullptr, table_function_cardinality_t cardinality = nullptr, - table_function_pushdown_complex_filter_t pushdown_complex_filter = nullptr, - table_function_to_string_t to_string = nullptr, table_function_max_threads_t max_threads = nullptr, - table_function_init_parallel_state_t init_parallel_state = nullptr, - table_function_parallel_t parallel_function = nullptr, - table_function_init_parallel_t parallel_init = nullptr, - table_function_parallel_state_next_t parallel_state_next = nullptr, bool projection_pushdown = false, - bool filter_pushdown = false, table_function_progress_t query_progress = nullptr) - : SimpleNamedParameterFunction(std::move(name), move(arguments)), bind(bind), init(init), function(function), - statistics(statistics), cleanup(cleanup), dependency(dependency), cardinality(cardinality), - pushdown_complex_filter(pushdown_complex_filter), to_string(to_string), max_threads(max_threads), - init_parallel_state(init_parallel_state), parallel_function(parallel_function), parallel_init(parallel_init), - parallel_state_next(parallel_state_next), table_scan_progress(query_progress), - projection_pushdown(projection_pushdown), filter_pushdown(filter_pushdown) { - } - TableFunction(const vector &arguments, table_function_t function, table_function_bind_t bind = nullptr, - table_function_init_t init = nullptr, table_statistics_t statistics = nullptr, - table_function_cleanup_t cleanup = nullptr, table_function_dependency_t dependency = nullptr, - table_function_cardinality_t cardinality = nullptr, - table_function_pushdown_complex_filter_t pushdown_complex_filter = nullptr, - table_function_to_string_t to_string = nullptr, table_function_max_threads_t max_threads = nullptr, - table_function_init_parallel_state_t init_parallel_state = nullptr, - table_function_parallel_t parallel_function = nullptr, - table_function_init_parallel_t parallel_init = nullptr, - table_function_parallel_state_next_t parallel_state_next = nullptr, bool projection_pushdown = false, - bool filter_pushdown = false, table_function_progress_t query_progress = nullptr) - : TableFunction(string(), arguments, function, bind, init, statistics, cleanup, dependency, cardinality, - pushdown_complex_filter, to_string, max_threads, init_parallel_state, parallel_function, - parallel_init, parallel_state_next, projection_pushdown, filter_pushdown, query_progress) { + explicit BoundSubqueryExpression(LogicalType return_type); + + bool IsCorrelated() { + return binder->correlated_columns.size() > 0; + } + + //! The binder used to bind the subquery node + shared_ptr binder; + //! The bound subquery node + unique_ptr subquery; + //! The subquery type + SubqueryType subquery_type; + //! the child expression to compare with (in case of IN, ANY, ALL operators) + unique_ptr child; + //! The comparison type of the child expression with the subquery (in case of ANY, ALL operators) + ExpressionType comparison_type; + //! The LogicalType of the subquery result. Only used for ANY expressions. + LogicalType child_type; + //! The target LogicalType of the subquery result (i.e. to which type it should be casted, if child_type <> + //! child_target). Only used for ANY expressions. + LogicalType child_target; + +public: + bool HasSubquery() const override { + return true; } - TableFunction() : SimpleNamedParameterFunction("", {}) { + bool IsScalar() const override { + return false; } - - //! Bind function - //! This function is used for determining the return type of a table producing function and returning bind data - //! The returned FunctionData object should be constant and should not be changed during execution. - table_function_bind_t bind; - //! (Optional) init function - //! Initialize the operator state of the function. The operator state is used to keep track of the progress in the - //! table function. - table_function_init_t init; - //! The main function - table_function_t function; - //! (Optional) statistics function - //! Returns the statistics of a specified column - table_statistics_t statistics; - //! (Optional) cleanup function - //! The final cleanup function, called after all data is exhausted from the main function - table_function_cleanup_t cleanup; - //! (Optional) dependency function - //! Sets up which catalog entries this table function depend on - table_function_dependency_t dependency; - //! (Optional) cardinality function - //! Returns the expected cardinality of this scan - table_function_cardinality_t cardinality; - //! (Optional) pushdown a set of arbitrary filter expressions, rather than only simple comparisons with a constant - //! Any functions remaining in the expression list will be pushed as a regular filter after the scan - table_function_pushdown_complex_filter_t pushdown_complex_filter; - //! (Optional) function for rendering the operator to a string in profiling output - table_function_to_string_t to_string; - //! (Optional) function that returns the maximum amount of threads that can work on this task - table_function_max_threads_t max_threads; - //! (Optional) initialize the parallel scan state, called once in total. - table_function_init_parallel_state_t init_parallel_state; - //! (Optional) Parallel version of the main function - table_function_parallel_t parallel_function; - //! (Optional) initialize the parallel scan given the parallel state. Called once per task. Return nullptr if there - //! is nothing left to scan. - table_function_init_parallel_t parallel_init; - //! (Optional) return the next chunk to process in the parallel scan, or return nullptr if there is none - table_function_parallel_state_next_t parallel_state_next; - //! (Optional) return how much of the table we have scanned up to this point (% of the data) - table_function_progress_t table_scan_progress; - //! Whether or not the table function supports projection pushdown. If not supported a projection will be added - //! that filters out unused columns. - bool projection_pushdown; - //! Whether or not the table function supports filter pushdown. If not supported a filter will be added - //! that applies the table filter directly. - bool filter_pushdown; - - string ToString() override { - return SimpleNamedParameterFunction::ToString(); + bool IsFoldable() const override { + return false; } -}; + string ToString() const override; + + bool Equals(const BaseExpression *other) const override; + + unique_ptr Copy() override; +}; } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/parallel/parallel_state.hpp +// duckdb/planner/expression/bound_unnest_expression.hpp // // //===----------------------------------------------------------------------===// + + namespace duckdb { -struct ParallelState { - virtual ~ParallelState() { - } -}; +//! Represents a function call that has been bound to a base function +class BoundUnnestExpression : public Expression { +public: + explicit BoundUnnestExpression(LogicalType return_type); + + unique_ptr child; + +public: + bool IsFoldable() const override; + string ToString() const override; + + hash_t Hash() const override; + bool Equals(const BaseExpression *other) const override; + unique_ptr Copy() override; +}; } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/parallel/task_scheduler.hpp +// duckdb/planner/expression/bound_window_expression.hpp // // //===----------------------------------------------------------------------===// - - - //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/parallel/task.hpp +// duckdb/parser/expression/window_expression.hpp // // //===----------------------------------------------------------------------===// + + + namespace duckdb { -class ClientContext; -class Executor; -//! Generic parallel task -class Task { +enum class WindowBoundary : uint8_t { + INVALID = 0, + UNBOUNDED_PRECEDING = 1, + UNBOUNDED_FOLLOWING = 2, + CURRENT_ROW_RANGE = 3, + CURRENT_ROW_ROWS = 4, + EXPR_PRECEDING_ROWS = 5, + EXPR_FOLLOWING_ROWS = 6, + EXPR_PRECEDING_RANGE = 7, + EXPR_FOLLOWING_RANGE = 8 +}; + +//! The WindowExpression represents a window function in the query. They are a special case of aggregates which is why +//! they inherit from them. +class WindowExpression : public ParsedExpression { public: - virtual ~Task() { + WindowExpression(ExpressionType type, string schema_name, const string &function_name); + + //! Schema of the aggregate function + string schema; + //! Name of the aggregate function + string function_name; + //! The child expression of the main window aggregate + vector> children; + //! The set of expressions to partition by + vector> partitions; + //! The set of ordering clauses + vector orders; + //! True to ignore NULL values + bool ignore_nulls; + //! The window boundaries + WindowBoundary start = WindowBoundary::INVALID; + WindowBoundary end = WindowBoundary::INVALID; + + unique_ptr start_expr; + unique_ptr end_expr; + //! Offset and default expressions for WINDOW_LEAD and WINDOW_LAG functions + unique_ptr offset_expr; + unique_ptr default_expr; + +public: + bool IsWindow() const override { + return true; } - //! Execute the task - virtual void Execute() = 0; + //! Get the name of the expression + string GetName() const override; + //! Convert the Expression to a String + string ToString() const override; + + static bool Equals(const WindowExpression *a, const WindowExpression *b); + + unique_ptr Copy() const override; + + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(ExpressionType type, FieldReader &source); }; +} // namespace duckdb + -//! Execute a task within an executor, including exception handling -//! This should be used within queries -class ExecutorTask : public Task { -public: - ExecutorTask(Executor &executor); - ExecutorTask(ClientContext &context); - virtual ~ExecutorTask(); - Executor &executor; + +namespace duckdb { +class AggregateFunction; + +class BoundWindowExpression : public Expression { public: - virtual void ExecuteTask() = 0; - void Execute() override; + BoundWindowExpression(ExpressionType type, LogicalType return_type, unique_ptr aggregate, + unique_ptr bind_info); + + //! The bound aggregate function + unique_ptr aggregate; + //! The bound function info + unique_ptr bind_info; + //! The child expressions of the main window aggregate + vector> children; + //! The set of expressions to partition by + vector> partitions; + //! Statistics belonging to the partitions expressions + vector> partitions_stats; + //! The set of ordering clauses + vector orders; + //! True to ignore NULL values + bool ignore_nulls; + //! The window boundaries + WindowBoundary start = WindowBoundary::INVALID; + WindowBoundary end = WindowBoundary::INVALID; + + unique_ptr start_expr; + unique_ptr end_expr; + //! Offset and default expressions for WINDOW_LEAD and WINDOW_LAG functions + unique_ptr offset_expr; + unique_ptr default_expr; + +public: + bool IsWindow() const override { + return true; + } + bool IsFoldable() const override { + return false; + } + + string ToString() const override; + + bool KeysAreCompatible(const BoundWindowExpression *other) const; + bool Equals(const BaseExpression *other) const override; + + unique_ptr Copy() override; }; +} // namespace duckdb + + +#include +namespace duckdb { + +class AdaptiveFilter { +public: + explicit AdaptiveFilter(const Expression &expr); + explicit AdaptiveFilter(TableFilterSet *table_filters); + void AdaptRuntimeStatistics(double duration); + vector permutation; + +private: + //! used for adaptive expression reordering + idx_t iteration_count; + idx_t swap_idx; + idx_t right_random_border; + idx_t observe_interval; + idx_t execute_interval; + double runtime_sum; + double prev_mean; + bool observe; + bool warmup; + vector swap_likeliness; + std::default_random_engine generator; +}; } // namespace duckdb +namespace duckdb { +class ColumnSegment; +class LocalTableStorage; +class Index; +class RowGroup; +class UpdateSegment; +class TableScanState; +class ColumnSegment; +class ValiditySegment; +class TableFilterSet; + +struct SegmentScanState { + virtual ~SegmentScanState() { + } +}; + +struct IndexScanState { + virtual ~IndexScanState() { + } +}; + +typedef unordered_map> buffer_handle_set_t; + +struct ColumnScanState { + //! The column segment that is currently being scanned + ColumnSegment *current; + //! The current row index of the scan + idx_t row_index; + //! The internal row index (i.e. the position of the SegmentScanState) + idx_t internal_index; + //! Segment scan state + unique_ptr scan_state; + //! Child states of the vector + vector child_states; + //! Whether or not InitializeState has been called for this segment + bool initialized = false; + //! If this segment has already been checked for skipping purposes + bool segment_checked = false; + +public: + //! Move the scan state forward by "count" rows (including all child states) + void Next(idx_t count); + //! Move ONLY this state forward by "count" rows (i.e. not the child states) + void NextInternal(idx_t count); + //! Move the scan state forward by STANDARD_VECTOR_SIZE rows + void NextVector(); +}; + +struct ColumnFetchState { + //! The set of pinned block handles for this set of fetches + buffer_handle_set_t handles; + //! Any child states of the fetch + vector> child_states; +}; + +struct LocalScanState { + ~LocalScanState(); + + void SetStorage(LocalTableStorage *storage); + LocalTableStorage *GetStorage() { + return storage; + } + + idx_t chunk_index; + idx_t max_index; + idx_t last_chunk_count; + TableFilterSet *table_filters; + +private: + LocalTableStorage *storage = nullptr; +}; + +class RowGroupScanState { +public: + RowGroupScanState(TableScanState &parent_p) : parent(parent_p), vector_index(0), max_row(0) { + } + + //! The parent scan state + TableScanState &parent; + //! The current row_group we are scanning + RowGroup *row_group; + //! The vector index within the row_group + idx_t vector_index; + //! The maximum row index of this row_group scan + idx_t max_row; + //! Child column scans + unique_ptr column_scans; + +public: + //! Move to the next vector, skipping past the current one + void NextVector(); +}; + +class TableScanState { +public: + TableScanState() : row_group_scan_state(*this), max_row(0) {}; + + //! The row_group scan state + RowGroupScanState row_group_scan_state; + //! The total maximum row index + idx_t max_row; + //! The column identifiers of the scan + vector column_ids; + //! The table filters (if any) + TableFilterSet *table_filters = nullptr; + //! Adaptive filter info (if any) + unique_ptr adaptive_filter; + //! Transaction-local scan state + LocalScanState local_state; + +public: + //! Move to the next vector + void NextVector(); +}; + +class CreateIndexScanState : public TableScanState { +public: + vector> locks; + unique_lock append_lock; + unique_lock delete_lock; +}; + +} // namespace duckdb + namespace duckdb { +class DataTable; +class WriteAheadLog; +struct TableAppendState; -struct ConcurrentQueue; -struct QueueProducerToken; -class ClientContext; -class TaskScheduler; +class LocalTableStorage { +public: + explicit LocalTableStorage(DataTable &table); + ~LocalTableStorage(); -struct SchedulerThread; + DataTable &table; + //! The main chunk collection holding the data + ChunkCollection collection; + //! The set of unique indexes + vector> indexes; + //! The set of deleted entries + unordered_map> deleted_entries; + //! The number of deleted rows + idx_t deleted_rows; + //! The number of active scans + atomic active_scans; -struct ProducerToken { - ProducerToken(TaskScheduler &scheduler, unique_ptr token); - ~ProducerToken(); +public: + void InitializeScan(LocalScanState &state, TableFilterSet *table_filters = nullptr); + idx_t EstimatedSize(); - TaskScheduler &scheduler; - unique_ptr token; - mutex producer_lock; + void Clear(); }; -//! The TaskScheduler is responsible for managing tasks and threads -class TaskScheduler { - // timeout for semaphore wait, default 50ms - constexpr static int64_t TASK_TIMEOUT_USECS = 50000; +//! The LocalStorage class holds appends that have not been committed yet +class LocalStorage { +public: + struct CommitState { + unordered_map> append_states; + }; public: - TaskScheduler(); - ~TaskScheduler(); + explicit LocalStorage(Transaction &transaction) : transaction(transaction) { + } - static TaskScheduler &GetScheduler(ClientContext &context); + //! Initialize a scan of the local storage + void InitializeScan(DataTable *table, LocalScanState &state, TableFilterSet *table_filters); + //! Scan + void Scan(LocalScanState &state, const vector &column_ids, DataChunk &result); - unique_ptr CreateProducer(); - //! Schedule a task to be executed by the task scheduler - void ScheduleTask(ProducerToken &producer, unique_ptr task); - //! Fetches a task from a specific producer, returns true if successful or false if no tasks were available - bool GetTaskFromProducer(ProducerToken &token, unique_ptr &task); - //! Run tasks forever until "marker" is set to false, "marker" must remain valid until the thread is joined - void ExecuteForever(atomic *marker); + //! Append a chunk to the local storage + void Append(DataTable *table, DataChunk &chunk); + //! Delete a set of rows from the local storage + idx_t Delete(DataTable *table, Vector &row_ids, idx_t count); + //! Update a set of rows in the local storage + void Update(DataTable *table, Vector &row_ids, const vector &column_ids, DataChunk &data); - //! Sets the amount of active threads executing tasks for the system; n-1 background threads will be launched. - //! The main thread will also be used for execution - void SetThreads(int32_t n); - //! Returns the number of threads - int32_t NumberOfThreads(); + //! Commits the local storage, writing it to the WAL and completing the commit + void Commit(LocalStorage::CommitState &commit_state, Transaction &transaction, WriteAheadLog *log, + transaction_t commit_id); + + bool ChangesMade() noexcept { + return table_storage.size() > 0; + } + idx_t EstimatedSize(); + + bool Find(DataTable *table) { + return table_storage.find(table) != table_storage.end(); + } + + idx_t AddedRows(DataTable *table) { + auto entry = table_storage.find(table); + if (entry == table_storage.end()) { + return 0; + } + return entry->second->collection.Count() - entry->second->deleted_rows; + } + + void AddColumn(DataTable *old_dt, DataTable *new_dt, ColumnDefinition &new_column, Expression *default_value); + void ChangeType(DataTable *old_dt, DataTable *new_dt, idx_t changed_idx, const LogicalType &target_type, + const vector &bound_columns, Expression &cast_expr); private: - void SetThreadsInternal(int32_t n); + LocalTableStorage *GetStorage(DataTable *table); - //! The task queue - unique_ptr queue; - //! The active background threads of the task scheduler - vector> threads; - //! Markers used by the various threads, if the markers are set to "false" the thread execution is stopped - vector>> markers; + template + bool ScanTableStorage(DataTable &table, LocalTableStorage &storage, T &&fun); + +private: + Transaction &transaction; + unordered_map> table_storage; + + void Flush(DataTable &table, LocalTableStorage &storage); }; } // namespace duckdb @@ -13224,252 +16841,430 @@ class TaskScheduler { namespace duckdb { -class Executor; -class Event; +class SequenceCatalogEntry; -//! The Pipeline class represents an execution pipeline -class Pipeline : public std::enable_shared_from_this { - friend class Executor; - friend class PipelineExecutor; - friend class PipelineEvent; - friend class PipelineFinishEvent; +class ColumnData; +class ClientContext; +class CatalogEntry; +class DataTable; +class DatabaseInstance; +class WriteAheadLog; + +class ChunkVectorInfo; + +struct DeleteInfo; +struct UpdateInfo; + +//! The transaction object holds information about a currently running or past +//! transaction +class Transaction { public: - Pipeline(Executor &execution_context); + Transaction(weak_ptr context, transaction_t start_time, transaction_t transaction_id, + timestamp_t start_timestamp, idx_t catalog_version) + : context(move(context)), 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), storage(*this), is_invalidated(false) { + } + + 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; + //! The set of uncommitted appends for the transaction + LocalStorage storage; + //! Map of all sequences that were used during the transaction and the value they had in this transaction + unordered_map sequence_usage; + //! Whether or not the transaction has been invalidated + bool is_invalidated; - Executor &executor; +public: + static Transaction &GetTransaction(ClientContext &context); + + 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 { + undo_buffer.Rollback(); + } + //! Cleanup the undo buffer + void Cleanup() { + undo_buffer.Cleanup(); + } + + void Invalidate() { + is_invalidated = true; + } + bool IsInvalidated() { + return is_invalidated; + } + bool ChangesMade(); + + timestamp_t GetCurrentTransactionStartTimestamp() { + return start_timestamp; + } + + 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); + +private: + //! The undo buffer is used to store old versions of rows that are updated + //! or deleted + UndoBuffer undo_buffer; + + Transaction(const Transaction &) = delete; +}; + +} // namespace duckdb + +#include +#include + +namespace duckdb { +struct AlterInfo; + +class ClientContext; + +typedef unordered_map> set_lock_map_t; + +struct MappingValue { + explicit MappingValue(idx_t index_) : index(index_), timestamp(0), deleted(false), parent(nullptr) { + } + + idx_t index; + transaction_t timestamp; + bool deleted; + unique_ptr child; + MappingValue *parent; +}; + +//! The Catalog Set stores (key, value) map of a set of CatalogEntries +class CatalogSet { + friend class DependencyManager; + friend class EntryDropper; public: - ClientContext &GetClientContext(); + DUCKDB_API explicit CatalogSet(Catalog &catalog, unique_ptr defaults = nullptr); - void AddDependency(shared_ptr &pipeline); + //! Create an entry in the catalog set. Returns whether or not it was + //! successful. + DUCKDB_API bool CreateEntry(ClientContext &context, const string &name, unique_ptr value, + unordered_set &dependencies); - void Ready(); - void Reset(); - void ResetSource(); - void Schedule(shared_ptr &event); + DUCKDB_API bool AlterEntry(ClientContext &context, const string &name, AlterInfo *alter_info); - //! Finalize this pipeline - void Finalize(Event &event); + DUCKDB_API bool DropEntry(ClientContext &context, const string &name, bool cascade); + + bool AlterOwnership(ClientContext &context, ChangeOwnershipInfo *info); + + void CleanupEntry(CatalogEntry *catalog_entry); + + //! Returns the entry with the specified name + DUCKDB_API CatalogEntry *GetEntry(ClientContext &context, const string &name); - string ToString() const; - void Print() const; + //! 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); - //! Returns query progress - bool GetProgress(int ¤t_percentage); + //! Rollback to be the currently valid entry for a certain catalog + //! entry + void Undo(CatalogEntry *entry); - //! Returns a list of all operators (including source and sink) involved in this pipeline - vector GetOperators() const; + //! 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(ClientContext &context, const std::function &callback); - PhysicalOperator *GetSink() { - return sink; + template + vector GetEntries(ClientContext &context) { + vector result; + Scan(context, [&](CatalogEntry *entry) { result.push_back((T *)entry); }); + return result; } -private: - //! Whether or not the pipeline has been readied - bool ready; - //! The source of this pipeline - PhysicalOperator *source; - //! The chain of intermediate operators - vector operators; - //! The sink (i.e. destination) for data; this is e.g. a hash table to-be-built - PhysicalOperator *sink; - - //! The global source state - unique_ptr source_state; + DUCKDB_API static bool HasConflict(ClientContext &context, transaction_t timestamp); + DUCKDB_API static bool UseTimestamp(ClientContext &context, transaction_t timestamp); - //! The parent pipelines (i.e. pipelines that are dependent on this pipeline to finish) - vector> parents; - //! The dependencies of this pipeline - vector> dependencies; + CatalogEntry *GetEntryFromIndex(idx_t index); + void UpdateTimestamp(CatalogEntry *entry, transaction_t timestamp); private: - bool GetProgressInternal(ClientContext &context, PhysicalOperator *op, int ¤t_percentage); - void ScheduleSequentialTask(shared_ptr &event); - bool LaunchScanTasks(shared_ptr &event, idx_t max_threads); + //! Adjusts table dependencies on the event of an UNDO + void AdjustTableDependencies(CatalogEntry *entry); + //! Adjust one dependency + void AdjustDependency(CatalogEntry *entry, TableCatalogEntry *table, ColumnDefinition &column, bool remove); + //! Adjust Enum dependency + void AdjustEnumDependency(CatalogEntry *entry, ColumnDefinition &column, bool remove); + //! Given a root entry, gets the entry valid for this transaction + CatalogEntry *GetEntryForTransaction(ClientContext &context, CatalogEntry *current); + CatalogEntry *GetCommittedEntry(CatalogEntry *current); + bool GetEntryInternal(ClientContext &context, const string &name, idx_t &entry_index, CatalogEntry *&entry); + bool GetEntryInternal(ClientContext &context, idx_t entry_index, CatalogEntry *&entry); + //! Drops an entry from the catalog set; must hold the catalog_lock to safely call this + void DropEntryInternal(ClientContext &context, idx_t 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, idx_t entry_index); + void DeleteMapping(ClientContext &context, const string &name); + void DropEntryDependencies(ClientContext &context, idx_t entry_index, CatalogEntry &entry, bool cascade); - bool ScheduleParallel(shared_ptr &event); +private: + Catalog &catalog; + //! The catalog lock is used to make changes to the data + mutex catalog_lock; + //! Mapping of string to catalog entry + case_insensitive_map_t> mapping; + //! The set of catalog entries + unordered_map> entries; + //! The current catalog entry index + idx_t current_entry = 0; + //! The generator used to generate default internal entries + unique_ptr defaults; }; - } // namespace duckdb - namespace duckdb { class ClientContext; -class DataChunk; -class PhysicalOperator; -class PipelineExecutor; -class OperatorState; -class ThreadContext; -class Task; -struct PipelineEventStack; -struct ProducerToken; +class StandardEntry; +class TableCatalogEntry; +class TableFunctionCatalogEntry; +class SequenceCatalogEntry; +class Serializer; +class Deserializer; -using event_map_t = unordered_map; +enum class OnCreateConflict : uint8_t; -class Executor { - friend class Pipeline; - friend class PipelineTask; +struct AlterTableInfo; +struct CreateIndexInfo; +struct CreateFunctionInfo; +struct CreateCollationInfo; +struct CreateViewInfo; +struct BoundCreateTableInfo; +struct CreatePragmaFunctionInfo; +struct CreateSequenceInfo; +struct CreateSchemaInfo; +struct CreateTableFunctionInfo; +struct CreateCopyFunctionInfo; +struct CreateTypeInfo; + +struct DropInfo; + +//! A schema in the catalog +class SchemaCatalogEntry : public CatalogEntry { + friend class Catalog; public: - explicit Executor(ClientContext &context); - ~Executor(); + SchemaCatalogEntry(Catalog *catalog, string name, bool is_internal); - ClientContext &context; +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 Executor &Get(ClientContext &context); + //! Scan the specified catalog set, invoking the callback method for every entry + void Scan(ClientContext &context, CatalogType type, const std::function &callback); + //! Scan the specified catalog set, invoking the callback method for every committed entry + void Scan(CatalogType type, const std::function &callback); - void Initialize(PhysicalOperator *physical_plan); - void BuildPipelines(PhysicalOperator *op, Pipeline *current); + //! Serialize the meta information of the SchemaCatalogEntry a serializer + virtual void Serialize(Serializer &serializer); + //! Deserializes to a CreateSchemaInfo + static unique_ptr Deserialize(Deserializer &source); - void Reset(); + string ToSQL() override; - vector GetTypes(); + //! Creates an index with the given name in the schema + CatalogEntry *CreateIndex(ClientContext &context, CreateIndexInfo *info, TableCatalogEntry *table); - unique_ptr FetchChunk(); +private: + //! Create a scalar or aggregate function within the given schema + CatalogEntry *CreateFunction(ClientContext &context, CreateFunctionInfo *info); + //! Creates a table with the given name in the schema + CatalogEntry *CreateTable(ClientContext &context, BoundCreateTableInfo *info); + //! Creates a view with the given name in the schema + CatalogEntry *CreateView(ClientContext &context, CreateViewInfo *info); + //! Creates a sequence with the given name in the schema + CatalogEntry *CreateSequence(ClientContext &context, CreateSequenceInfo *info); + //! Create a table function within the given schema + CatalogEntry *CreateTableFunction(ClientContext &context, CreateTableFunctionInfo *info); + //! Create a copy function within the given schema + CatalogEntry *CreateCopyFunction(ClientContext &context, CreateCopyFunctionInfo *info); + //! Create a pragma function within the given schema + CatalogEntry *CreatePragmaFunction(ClientContext &context, CreatePragmaFunctionInfo *info); + //! Create a collation within the given schema + CatalogEntry *CreateCollation(ClientContext &context, CreateCollationInfo *info); + //! Create a enum within the given schema + CatalogEntry *CreateType(ClientContext &context, CreateTypeInfo *info); - //! Push a new error - void PushError(ExceptionType type, const string &exception); - //! True if an error has been thrown - bool HasError(); - //! Throw the exception that was pushed using PushError. - //! Should only be called if HasError returns true - void ThrowException(); + //! Drops an entry from the schema + void DropEntry(ClientContext &context, DropInfo *info); - //! Work on tasks for this specific executor, until there are no tasks remaining - void WorkOnTasks(); + //! Append a scalar or aggregate function within the given schema + CatalogEntry *AddFunction(ClientContext &context, CreateFunctionInfo *info); - //! Flush a thread context into the client context - void Flush(ThreadContext &context); + //! Alters a catalog entry + void Alter(ClientContext &context, AlterInfo *info); - //! Returns the progress of the pipelines - bool GetPipelinesProgress(int ¤t_progress); + //! 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); - void CompletePipeline() { - completed_pipelines++; - } - ProducerToken &GetToken() { - return *producer; - } - void AddEvent(shared_ptr event); + //! Get the catalog set for the specified type + CatalogSet &GetCatalogSet(CatalogType type); +}; +} // namespace duckdb - void ReschedulePipelines(const vector> &pipelines, vector> &events); -private: - void ScheduleEvents(); - void ScheduleEventsInternal(const vector> &pipelines, - unordered_map>> &child_pipelines, - vector> &events, bool main_schedule = true); - void SchedulePipeline(const shared_ptr &pipeline, event_map_t &event_map, - vector> &events, bool complete_pipeline); - Pipeline *ScheduleUnionPipeline(const shared_ptr &pipeline, const Pipeline *parent, - event_map_t &event_map, vector> &events); - void ScheduleChildPipeline(Pipeline *parent, const shared_ptr &pipeline, event_map_t &event_map, - vector> &events); - void ExtractPipelines(shared_ptr &pipeline, vector> &result); - bool NextExecutor(); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/deque.hpp +// +// +//===----------------------------------------------------------------------===// - void AddChildPipeline(Pipeline *current); - void VerifyPipeline(Pipeline &pipeline); - void VerifyPipelines(); - void ThrowExceptionInternal(); -private: - PhysicalOperator *physical_plan; +#include + +namespace duckdb { +using std::deque; +} + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/progress_bar.hpp +// +// +//===----------------------------------------------------------------------===// + + - mutex executor_lock; - //! The pipelines of the current query - vector> pipelines; - //! The root pipeline of the query - vector> root_pipelines; - //! The pipeline executor for the root pipeline - unique_ptr root_executor; - //! The current root pipeline index - idx_t root_pipeline_idx; - //! The producer of this query - unique_ptr producer; - //! Exceptions that occurred during the execution of the current query - vector> exceptions; - //! List of events - vector> events; - //! The amount of completed pipelines of the query - atomic completed_pipelines; - //! The total amount of pipelines in the query - idx_t total_pipelines; - //! The adjacent union pipelines of each pipeline - //! Union pipelines have the same sink, but can be run concurrently along with this pipeline - unordered_map>> union_pipelines; - //! Child pipelines of this pipeline - //! Like union pipelines, child pipelines share the same sink - //! Unlike union pipelines, child pipelines should be run AFTER their dependencies are completed - //! i.e. they should be run after the dependencies are completed, but before finalize is called on the sink - unordered_map>> child_pipelines; - //! Dependencies of child pipelines - unordered_map> child_dependencies; - //! Duplicate eliminated join scan dependencies - unordered_map delim_join_dependencies; +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/profiler.hpp +// +// +//===----------------------------------------------------------------------===// - //! Active recursive CTE node (if any) - PhysicalOperator *recursive_cte; + + + + + +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; }; -} // namespace duckdb +using Profiler = BaseProfiler; + +} // namespace duckdb namespace duckdb { + class ProgressBar { public: - explicit ProgressBar(Executor *executor, idx_t show_progress_after, idx_t time_update_bar = 100) - : executor(executor), show_progress_after(show_progress_after), time_update_bar(time_update_bar), - current_percentage(-1), stop(false) { - } - ~ProgressBar(); + explicit ProgressBar(Executor &executor, idx_t show_progress_after); //! Starts the thread void Start(); - //! Stops the thread - void Stop(); + //! Updates the progress bar and prints it to the screen + void Update(bool final); //! Gets current percentage - int GetCurrentPercentage(); - - void Initialize(idx_t show_progress_after) { - this->show_progress_after = show_progress_after; - } + double GetCurrentPercentage(); private: - const string PROGRESS_BAR_STRING = "||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||"; + const string PROGRESS_BAR_STRING = "============================================================"; static constexpr const idx_t PROGRESS_BAR_WIDTH = 60; - Executor *executor = nullptr; -#ifndef DUCKDB_NO_THREADS - thread progress_bar_thread; - std::condition_variable c; - mutex m; -#endif + +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; - idx_t time_update_bar; - atomic current_percentage; - atomic stop; - //! In case our progress bar tries to use a scan operator that is not implemented we don't print anything + //! The current progress percentage + double current_percentage; + //! Whether or not profiling is supported for the current query bool supported = true; - //! Starts the Progress Bar Thread that prints the progress bar - void ProgressBarThread(); - -#ifndef DUCKDB_NO_THREADS - template - bool WaitFor(DURATION duration) { - unique_lock l(m); - return !c.wait_for(l, duration, [this]() { return stop.load(); }); - } -#endif }; } // namespace duckdb @@ -13477,7 +17272,6 @@ class ProgressBar { - //===----------------------------------------------------------------------===// // DuckDB // @@ -13538,8 +17332,93 @@ class TransactionContext { } // namespace duckdb + #include +//===----------------------------------------------------------------------===// +// 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 + + + + +namespace duckdb { +class ClientContext; + +struct ClientConfig { + //! 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 automatically print query profiling information in (default: disabled) + ProfilerPrintFormat profiler_print_format = ProfilerPrintFormat::NONE; + //! The file to save query profiling information to, instead of printing it to the console + //! (empty = print to console) + string profiler_save_location; + + //! 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; + + //! Preserve identifier case while parsing. + //! If false, all unquoted identifiers are lower-cased (e.g. "MyTable" -> "mytable"). + bool preserve_identifier_case = true; + + // Whether or not aggressive query verification is enabled + bool query_verification_enabled = 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; + //! 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; + + //! The explain output type used when none is specified (default: PHYSICAL_ONLY) + ExplainOutputType explain_output_type = ExplainOutputType::PHYSICAL_ONLY; + + //! Generic options + case_insensitive_map_t set_variables; + +public: + static ClientConfig &GetConfig(ClientContext &context); +}; + +} // namespace duckdb + namespace duckdb { class Appender; @@ -13557,17 +17436,22 @@ class QueryProfilerHistory; class ClientContextLock; struct CreateScalarFunctionInfo; class ScalarFunctionCatalogEntry; +struct ActiveQueryContext; +struct ParserOptions; //! 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; public: DUCKDB_API explicit ClientContext(shared_ptr db); DUCKDB_API ~ClientContext(); + //! Query profiler - unique_ptr profiler; + shared_ptr profiler; //! QueryProfiler History unique_ptr query_profiler_history; //! The database that this client is connected to @@ -13576,43 +17460,12 @@ class ClientContext : public std::enable_shared_from_this { TransactionContext transaction; //! Whether or not the query is interrupted atomic interrupted; - //! The current query being executed by the client context - string query; - - //! The query executor - Executor executor; - - //! The Progress Bar - unique_ptr progress_bar; - //! 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; unique_ptr temporary_objects; unordered_map> prepared_statements; - case_insensitive_map_t set_variables; - - // Whether or not aggressive query verification is enabled - bool query_verification_enabled = 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; - //! 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; //! The writer used to log queries (if logging is enabled) unique_ptr log_query_writer; - //! The explain output type used when none is specified (default: PHYSICAL_ONLY) - ExplainOutputType explain_output_type = ExplainOutputType::PHYSICAL_ONLY; //! The random generator used by random(). Its seed value can be set by setseed(). std::mt19937 random_engine; @@ -13620,6 +17473,9 @@ class ClientContext : public std::enable_shared_from_this { unique_ptr file_opener; + //! The client configuration + ClientConfig config; + public: DUCKDB_API Transaction &ActiveTransaction() { return transaction.ActiveTransaction(); @@ -13637,10 +17493,13 @@ class ClientContext : public std::enable_shared_from_this { //! 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); - //! Fetch a query from the current result set (if any) - DUCKDB_API unique_ptr Fetch(); - //! Cleanup the result set (if any). - DUCKDB_API void Cleanup(); + + //! 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); + //! Issues a query to the database and returns a Pending Query Result + DUCKDB_API unique_ptr PendingQuery(unique_ptr statement); + //! Destroy the client context DUCKDB_API void Destroy(); @@ -13660,6 +17519,12 @@ class ClientContext : public std::enable_shared_from_this { //! Directly prepare a SQL statement DUCKDB_API unique_ptr Prepare(unique_ptr statement); + //! 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, vector &values); + //! 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. @@ -13667,16 +17532,17 @@ class ClientContext : public std::enable_shared_from_this { vector &values, bool allow_stream_result = true); //! Gets current percentage of the query's progress, returns 0 in case the progress bar is disabled. - int GetProgress(); + 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); - void HandlePragmaStatements(vector> &statements); + 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. @@ -13689,7 +17555,33 @@ class ClientContext : public std::enable_shared_from_this { //! 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(); + + 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); + + //! Returns the current executor + Executor &GetExecutor(); + + //! Returns the current query string (if any) + const string &GetCurrentQuery(); + + //! Fetch a list of table names that are required for a given query + DUCKDB_API unordered_set GetTableNames(const string &query); + private: + //! Parse statements and resolve pragmas from a query + bool ParseStatements(ClientContextLock &lock, const string &query, vector> &result, + string &error); + //! Issues a query to the database and returns a Pending Query Result + unique_ptr PendingQueryInternal(ClientContextLock &lock, unique_ptr statement, + bool verify = true); + unique_ptr ExecutePendingQueryInternal(ClientContextLock &lock, PendingQueryResult &query, + bool allow_stream_result); + //! 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 @@ -13698,70 +17590,77 @@ class ClientContext : public std::enable_shared_from_this { void InitialCleanup(ClientContextLock &lock); //! Internal clean up, does not lock. Caller must hold the context_lock. - void CleanupInternal(ClientContextLock &lock); + void CleanupInternal(ClientContextLock &lock, BaseQueryResult *result = nullptr, + bool invalidate_transaction = false); string FinalizeQuery(ClientContextLock &lock, bool success); - //! Internal fetch, does not lock. Caller must hold the context_lock. - unique_ptr FetchInternal(ClientContextLock &lock); - //! Internally execute a set of SQL statement. Caller must hold the context_lock. - unique_ptr RunStatements(ClientContextLock &lock, const string &query, - vector> &statements, bool allow_stream_result); - //! Internally prepare and execute a prepared SQL statement. Caller must hold the context_lock. - unique_ptr RunStatement(ClientContextLock &lock, const string &query, - unique_ptr statement, bool allow_stream_result); - unique_ptr RunStatementOrPreparedStatement(ClientContextLock &lock, const string &query, - unique_ptr statement, - shared_ptr &prepared, - vector *values, bool allow_stream_result); + unique_ptr PendingStatementOrPreparedStatement(ClientContextLock &lock, const string &query, + unique_ptr statement, + shared_ptr &prepared, + vector *values); + unique_ptr PendingPreparedStatement(ClientContextLock &lock, + shared_ptr statement_p, + vector bound_values); //! Internally prepare a SQL statement. Caller must hold the context_lock. shared_ptr CreatePreparedStatement(ClientContextLock &lock, const string &query, unique_ptr statement); - //! Internally execute a prepared SQL statement. Caller must hold the context_lock. - unique_ptr ExecutePreparedStatement(ClientContextLock &lock, const string &query, - shared_ptr statement, - vector bound_values, bool allow_stream_result); - //! Call CreatePreparedStatement() and ExecutePreparedStatement() without any bound values + unique_ptr PendingStatementInternal(ClientContextLock &lock, const string &query, + unique_ptr statement); unique_ptr RunStatementInternal(ClientContextLock &lock, const string &query, - unique_ptr statement, bool allow_stream_result); + 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); + unique_ptr FetchResultInternal(ClientContextLock &lock, PendingQueryResult &pending, + bool allow_stream_result); + unique_ptr FetchInternal(ClientContextLock &lock, Executor &executor, BaseQueryResult &result); + unique_ptr LockContext(); bool UpdateFunctionInfoFromEntry(ScalarFunctionCatalogEntry *existing_function, CreateScalarFunctionInfo *new_info); + void BeginTransactionInternal(ClientContextLock &lock, bool requires_valid_transaction); + void BeginQueryInternal(ClientContextLock &lock, const string &query); + string EndQueryInternal(ClientContextLock &lock, bool success, bool invalidate_transaction); + + PendingExecutionResult ExecuteTaskInternal(ClientContextLock &lock, PendingQueryResult &result); + + unique_ptr + PendingStatementOrPreparedStatementInternal(ClientContextLock &lock, const string &query, + unique_ptr statement, + shared_ptr &prepared, vector *values); + + unique_ptr PendingQueryPreparedInternal(ClientContextLock &lock, const string &query, + shared_ptr &prepared, + vector &values); + private: - //! The currently opened StreamQueryResult (if any) - StreamQueryResult *open_result = nullptr; //! 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 -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/parsed_data/create_table_function_info.hpp -// -// -//===----------------------------------------------------------------------===// - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/parsed_data/create_function_info.hpp -// -// -//===----------------------------------------------------------------------===// +class ClientContextLock { +public: + explicit ClientContextLock(mutex &context_lock) : client_guard(context_lock) { + } + ~ClientContextLock() { + } +private: + lock_guard client_guard; +}; +} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/parser/parsed_data/create_info.hpp +// duckdb/parser/parsed_data/create_table_function_info.hpp // // //===----------------------------------------------------------------------===// @@ -13771,7 +17670,7 @@ class ClientContext : public std::enable_shared_from_this { //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/parser/parsed_data/parse_info.hpp +// duckdb/parser/parsed_data/create_function_info.hpp // // //===----------------------------------------------------------------------===// @@ -13780,64 +17679,6 @@ class ClientContext : public std::enable_shared_from_this { -namespace duckdb { - -struct ParseInfo { - virtual ~ParseInfo() { - } -}; - -} // namespace duckdb - - - -namespace duckdb { - -enum class OnCreateConflict : uint8_t { - // Standard: throw error - ERROR_ON_CONFLICT, - // CREATE IF NOT EXISTS, silently do nothing on conflict - IGNORE_ON_CONFLICT, - // CREATE OR REPLACE - REPLACE_ON_CONFLICT -}; - -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) { - } - ~CreateInfo() override { - } - - //! The to-be-created catalog type - CatalogType type; - //! The schema name of the entry - string schema; - //! What to do on create conflict - OnCreateConflict on_conflict; - //! Whether or not the entry is temporary - bool temporary; - //! Whether or not the entry is an internal entry - bool internal; - //! The SQL string of the CREATE statement - string sql; - -public: - virtual unique_ptr Copy() const = 0; - void CopyProperties(CreateInfo &other) const { - other.type = type; - other.schema = schema; - other.on_conflict = on_conflict; - other.temporary = temporary; - other.internal = internal; - other.sql = sql; - } -}; - -} // namespace duckdb - - namespace duckdb { diff --git a/libduckdb-sys/src/lib.rs b/libduckdb-sys/src/lib.rs index 4207be28..b7c9be2a 100644 --- a/libduckdb-sys/src/lib.rs +++ b/libduckdb-sys/src/lib.rs @@ -27,21 +27,22 @@ mod tests { use std::mem; use std::os::raw::{c_char, c_void}; use std::ptr; - use std::slice; use arrow::array::{Array, ArrayData, Int32Array, StructArray}; use arrow::datatypes::DataType; use arrow::ffi::{ArrowArray, FFI_ArrowArray, FFI_ArrowSchema}; unsafe fn print_int_result(mut result: duckdb_result) { - let columns = slice::from_raw_parts(result.columns, result.column_count as usize); - for i in 0..result.column_count { - print!("{} ", CStr::from_ptr(columns[i as usize].name).to_string_lossy()); + for i in 0..duckdb_column_count(&mut result) { + print!( + "{} ", + CStr::from_ptr(duckdb_column_name(&mut result, i)).to_string_lossy() + ); } println!(); // print the data of the result - for row_idx in 0..result.row_count { - for col_idx in 0..result.column_count { + for row_idx in 0..duckdb_row_count(&mut result) { + for col_idx in 0..duckdb_column_count(&mut result) { let val = duckdb_value_int32(&mut result, col_idx, row_idx); print!("{} ", val); } @@ -150,11 +151,11 @@ mod tests { if duckdb_query(con, sql.as_ptr() as *const c_char, &mut result) != duckdb_state_DuckDBSuccess { panic!( "SELECT error: {}", - CStr::from_ptr(result.error_message).to_string_lossy() + CStr::from_ptr(duckdb_result_error(&mut result)).to_string_lossy() ) } - assert_eq!(result.row_count, 3); - assert_eq!(result.column_count, 2); + assert_eq!(duckdb_row_count(&mut result), 3); + assert_eq!(duckdb_column_count(&mut result), 2); print_int_result(result); duckdb_destroy_result(&mut result); @@ -170,8 +171,8 @@ mod tests { if duckdb_execute_prepared(stmt, &mut result) != duckdb_state_DuckDBSuccess { panic!("Execute prepared error"); } - assert_eq!(result.row_count, 2); - assert_eq!(result.column_count, 2); + assert_eq!(duckdb_row_count(&mut result), 2); + assert_eq!(duckdb_column_count(&mut result), 2); print_int_result(result); duckdb_destroy_result(&mut result); @@ -182,8 +183,8 @@ mod tests { if duckdb_execute_prepared(stmt, &mut result) != duckdb_state_DuckDBSuccess { panic!("Execute prepared error"); } - assert_eq!(result.row_count, 1); - assert_eq!(result.column_count, 2); + assert_eq!(duckdb_row_count(&mut result), 1); + assert_eq!(duckdb_column_count(&mut result), 2); print_int_result(result); duckdb_destroy_result(&mut result); duckdb_destroy_prepare(&mut stmt); diff --git a/libduckdb-sys/src/raw_statement.rs b/libduckdb-sys/src/raw_statement.rs new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/libduckdb-sys/src/raw_statement.rs @@ -0,0 +1 @@ + diff --git a/libduckdb-sys/upgrade.sh b/libduckdb-sys/upgrade.sh index 98f9397d..478d9d43 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.3.1 +DUCKDB_VERSION=v0.3.2 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/raw_statement.rs b/src/raw_statement.rs index 1cc8f5cb..c48b7ce8 100644 --- a/src/raw_statement.rs +++ b/src/raw_statement.rs @@ -2,7 +2,6 @@ use std::convert::TryFrom; use std::ffi::CStr; use std::os::raw::c_void; use std::ptr; -use std::slice; use std::sync::Arc; use super::ffi; @@ -125,19 +124,26 @@ impl RawStatement { #[allow(dead_code)] unsafe fn print_result(&self, mut result: ffi::duckdb_result) { - let columns = slice::from_raw_parts(result.columns, result.column_count as usize); - println!("row-count: {}, column-count: {}", result.row_count, result.column_count); - for i in 0..result.column_count { + use ffi::duckdb_column_count; + use ffi::duckdb_column_name; + use ffi::duckdb_row_count; + + println!( + "row-count: {}, column-count: {}", + duckdb_row_count(&mut result), + duckdb_column_count(&mut result) + ); + for i in 0..duckdb_column_count(&mut result) { print!( "column-name:{} ", - CStr::from_ptr(columns[i as usize].name).to_string_lossy() + CStr::from_ptr(duckdb_column_name(&mut result, i)).to_string_lossy() ); } println!(); // print the data of the result - for row_idx in 0..result.row_count { + for row_idx in 0..duckdb_row_count(&mut result) { print!("row-value:"); - for col_idx in 0..result.column_count { + for col_idx in 0..duckdb_column_count(&mut result) { let val = ffi::duckdb_value_varchar(&mut result, col_idx, row_idx); print!("{} ", CStr::from_ptr(val).to_string_lossy()); } diff --git a/upgrade.sh b/upgrade.sh new file mode 100755 index 00000000..05570c88 --- /dev/null +++ b/upgrade.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +## How to run +## `./upgrade.sh from to` +## +## such as: +## `./upgrade.sh 0.3.1 0.3.2` + +if [ "$#" -ne 2 ] +then + echo "Arguments are not equals to 2\n" + echo "./upgrade.sh from to" + exit 1 +fi + +sed -i '' "s/$1/$2/g" Cargo.toml libduckdb-sys/upgrade.sh libduckdb-sys/Cargo.toml .github/workflows/rust.yaml +./libduckdb-sys/upgrade.sh