diff --git a/package.json b/package.json index 0002e59b..0fa00254 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "duckdb", "main": "./lib/duckdb.js", "types": "./lib/duckdb.d.ts", - "version": "0.0.2-dev5.0", + "version": "1.1.3", "description": "DuckDB node.js API", "gypfile": true, "dependencies": { diff --git a/src/duckdb/extension/icu/third_party/icu/common/putil.cpp b/src/duckdb/extension/icu/third_party/icu/common/putil.cpp index 56d25c3b..c7981149 100644 --- a/src/duckdb/extension/icu/third_party/icu/common/putil.cpp +++ b/src/duckdb/extension/icu/third_party/icu/common/putil.cpp @@ -46,11 +46,6 @@ // First, the platform type. Need this for U_PLATFORM. #include "unicode/platform.h" -#if U_PLATFORM == U_PF_MINGW && defined __STRICT_ANSI__ -/* tzset isn't defined in strict ANSI on MinGW. */ -#undef __STRICT_ANSI__ -#endif - /* * Cygwin with GCC requires inclusion of time.h after the above disabling strict asci mode statement. */ diff --git a/src/duckdb/extension/icu/third_party/icu/common/rbbiscan.cpp b/src/duckdb/extension/icu/third_party/icu/common/rbbiscan.cpp index c9e9b2cd..143bb591 100644 --- a/src/duckdb/extension/icu/third_party/icu/common/rbbiscan.cpp +++ b/src/duckdb/extension/icu/third_party/icu/common/rbbiscan.cpp @@ -175,7 +175,7 @@ // // Node Stack. // // Normally has one entry, which is the entire parse tree for the rules. -// // If errors occured, there may be additional subtrees left on the stack. +// // If errors occurred, there may be additional subtrees left on the stack. // while (fNodeStackPtr > 0) { // delete fNodeStack[fNodeStackPtr]; // fNodeStackPtr--; diff --git a/src/duckdb/extension/icu/third_party/icu/common/rbbitblb.cpp b/src/duckdb/extension/icu/third_party/icu/common/rbbitblb.cpp index e5217f23..d3f76262 100644 --- a/src/duckdb/extension/icu/third_party/icu/common/rbbitblb.cpp +++ b/src/duckdb/extension/icu/third_party/icu/common/rbbitblb.cpp @@ -698,7 +698,7 @@ // } // } // return; -// // delete local pointers only if error occured. +// // delete local pointers only if error occurred. // ExitBuildSTdeleteall: // delete initialState; // delete failState; diff --git a/src/duckdb/extension/icu/third_party/icu/common/ucurr.cpp b/src/duckdb/extension/icu/third_party/icu/common/ucurr.cpp index 1d7b6675..0ff3507f 100644 --- a/src/duckdb/extension/icu/third_party/icu/common/ucurr.cpp +++ b/src/duckdb/extension/icu/third_party/icu/common/ucurr.cpp @@ -1515,7 +1515,7 @@ uprv_parseCurrency(const char* locale, int32_t max = 0; int32_t matchIndex = -1; - // case in-sensitive comparision against currency names + // case in-sensitive comparison against currency names searchCurrencyName(currencyNames, total_currency_name_count, upperText, textLen, partialMatchLen, &max, &matchIndex); diff --git a/src/duckdb/extension/icu/third_party/icu/common/uresbund.cpp b/src/duckdb/extension/icu/third_party/icu/common/uresbund.cpp index b03284ed..61b2f433 100644 --- a/src/duckdb/extension/icu/third_party/icu/common/uresbund.cpp +++ b/src/duckdb/extension/icu/third_party/icu/common/uresbund.cpp @@ -3019,7 +3019,7 @@ ures_getKeywordValues(const char *path, const char *keyword, UErrorCode *status) U_INTERNAL UBool U_EXPORT2 ures_equal(const UResourceBundle* res1, const UResourceBundle* res2){ if(res1==NULL || res2==NULL){ - return res1==res2; /* pointer comparision */ + return res1==res2; /* pointer comparison */ } if(res1->fKey==NULL|| res2->fKey==NULL){ return (res1->fKey==res2->fKey); diff --git a/src/duckdb/extension/icu/third_party/icu/common/uresimp.h b/src/duckdb/extension/icu/third_party/icu/common/uresimp.h index f453ddc0..381a0dbe 100644 --- a/src/duckdb/extension/icu/third_party/icu/common/uresimp.h +++ b/src/duckdb/extension/icu/third_party/icu/common/uresimp.h @@ -172,10 +172,10 @@ U_CFUNC UResourceBundle *ures_copyResb(UResourceBundle *r, const UResourceBundle * Returns a resource that can be located using the pathToResource argument. One needs optional package, locale * and path inside the locale, for example: "/myData/en/zoneStrings/3". Keys and indexes are supported. Keys * need to reference data in named structures, while indexes can reference both named and anonymous resources. - * Features a fill-in parameter. - * + * Features a fill-in parameter. + * * Note, this function does NOT have a syntax for specifying items within a tree. May want to consider a - * syntax that delineates between package/tree and resource. + * syntax that delineates between package/tree and resource. * * @param pathToResource a path that will lead to the requested resource * @param fillIn if NULL a new UResourceBundle struct is allocated and must be deleted by the caller. @@ -184,16 +184,16 @@ U_CFUNC UResourceBundle *ures_copyResb(UResourceBundle *r, const UResourceBundle * @return a pointer to a UResourceBundle struct. If fill in param was NULL, caller must delete it */ U_CAPI UResourceBundle* U_EXPORT2 -ures_findResource(const char* pathToResource, - UResourceBundle *fillIn, UErrorCode *status); +ures_findResource(const char* pathToResource, + UResourceBundle *fillIn, UErrorCode *status); /** - * Returns a sub resource that can be located using the pathToResource argument. One needs a path inside + * Returns a sub resource that can be located using the pathToResource argument. One needs a path inside * the supplied resource, for example, if you have "en_US" resource bundle opened, you might ask for * "zoneStrings/3". Keys and indexes are supported. Keys - * need to reference data in named structures, while indexes can reference both + * need to reference data in named structures, while indexes can reference both * named and anonymous resources. - * Features a fill-in parameter. + * Features a fill-in parameter. * * @param resourceBundle a resource * @param pathToResource a path that will lead to the requested resource @@ -203,8 +203,8 @@ ures_findResource(const char* pathToResource, * @return a pointer to a UResourceBundle struct. If fill in param was NULL, caller must delete it */ U_CAPI UResourceBundle* U_EXPORT2 -ures_findSubResource(const UResourceBundle *resB, - char* pathToResource, +ures_findSubResource(const UResourceBundle *resB, + char* pathToResource, UResourceBundle *fillIn, UErrorCode *status); /** @@ -215,23 +215,23 @@ ures_findSubResource(const UResourceBundle *resB, * @param resName top level resource. Example: "collations" * @param keyword locale keyword. Example: "collation" * @param locid The requested locale - * @param isAvailable If non-null, pointer to fillin parameter that indicates whether the - * requested locale was available. The locale is defined as 'available' if it physically + * @param isAvailable If non-null, pointer to fillin parameter that indicates whether the + * requested locale was available. The locale is defined as 'available' if it physically * exists within the specified tree. * @param omitDefault if TRUE, omit keyword and value if default. 'de_DE\@collation=standard' -> 'de_DE' * @param status error code - * @return the actual buffer size needed for the full locale. If it's greater + * @return the actual buffer size needed for the full locale. If it's greater * than resultCapacity, the returned full name will be truncated and an error code will be returned. */ U_CAPI int32_t U_EXPORT2 -ures_getFunctionalEquivalent(char *result, int32_t resultCapacity, +ures_getFunctionalEquivalent(char *result, int32_t resultCapacity, const char *path, const char *resName, const char *keyword, const char *locid, UBool *isAvailable, UBool omitDefault, UErrorCode *status); /** * Given a tree path and keyword, return a string enumeration of all possible values for that keyword. * @param path path to the tree, or NULL for ICU data - * @param keyword a particular keyword to consider, must match a top level resource name + * @param keyword a particular keyword to consider, must match a top level resource name * within the tree. * @param status error code */ @@ -251,14 +251,14 @@ ures_getKeywordValues(const char *path, const char *keyword, UErrorCode *status) * Alternatively, you can supply a struct to be filled by this function. * @param status: fills in the outgoing error code * could be U_MISSING_RESOURCE_ERROR if the key is not found - * could be a non-failing error + * could be a non-failing error * e.g.: U_USING_FALLBACK_WARNING,U_USING_DEFAULT_WARNING * @return a pointer to a UResourceBundle struct. If fill in param was NULL, caller must delete it */ -U_CAPI UResourceBundle* U_EXPORT2 -ures_getByKeyWithFallback(const UResourceBundle *resB, - const char* inKey, - UResourceBundle *fillIn, +U_CAPI UResourceBundle* U_EXPORT2 +ures_getByKeyWithFallback(const UResourceBundle *resB, + const char* inKey, + UResourceBundle *fillIn, UErrorCode *status); @@ -272,13 +272,13 @@ ures_getByKeyWithFallback(const UResourceBundle *resB, * @param inKey a key associated with the requested resource * @param status: fills in the outgoing error code * could be U_MISSING_RESOURCE_ERROR if the key is not found - * could be a non-failing error + * could be a non-failing error * e.g.: U_USING_FALLBACK_WARNING,U_USING_DEFAULT_WARNING * @return a pointer to a UResourceBundle struct. If fill in param was NULL, caller must delete it */ -U_CAPI const UChar* U_EXPORT2 -ures_getStringByKeyWithFallback(const UResourceBundle *resB, - const char* inKey, +U_CAPI const UChar* U_EXPORT2 +ures_getStringByKeyWithFallback(const UResourceBundle *resB, + const char* inKey, int32_t* len, UErrorCode *status); @@ -318,15 +318,15 @@ ures_getVersionByKey(const UResourceBundle *resB, * The caller does not own this string. * @see ures_getVersion */ -U_CAPI const char* U_EXPORT2 +U_CAPI const char* U_EXPORT2 ures_getVersionNumberInternal(const UResourceBundle *resourceBundle); /** * Return the name of the Locale associated with this ResourceBundle. This API allows - * you to query for the real locale of the resource. For example, if you requested - * "en_US_CALIFORNIA" and only "en_US" bundle exists, "en_US" will be returned. + * you to query for the real locale of the resource. For example, if you requested + * "en_US_CALIFORNIA" and only "en_US" bundle exists, "en_US" will be returned. * For subresources, the locale where this resource comes from will be returned. - * If fallback has occured, getLocale will reflect this. + * If fallback has occurred, getLocale will reflect this. * * This internal version avoids deprecated-warnings in ICU code. * @@ -334,13 +334,13 @@ ures_getVersionNumberInternal(const UResourceBundle *resourceBundle); * @param status just for catching illegal arguments * @return A Locale name */ -U_CAPI const char* U_EXPORT2 -ures_getLocaleInternal(const UResourceBundle* resourceBundle, +U_CAPI const char* U_EXPORT2 +ures_getLocaleInternal(const UResourceBundle* resourceBundle, UErrorCode* status); /** * Same as ures_openDirect() but uses the fill-in parameter instead of allocating a new bundle. - * + * * @param r The existing UResourceBundle to fill in. If NULL then status will be * set to U_ILLEGAL_ARGUMENT_ERROR. * @param packageName The packageName and locale together point to an ICU udata object, diff --git a/src/duckdb/extension/icu/third_party/icu/common/ustring.cpp b/src/duckdb/extension/icu/third_party/icu/common/ustring.cpp index f741740e..9df29918 100644 --- a/src/duckdb/extension/icu/third_party/icu/common/ustring.cpp +++ b/src/duckdb/extension/icu/third_party/icu/common/ustring.cpp @@ -755,7 +755,7 @@ uprv_strCompare(const UChar *s1, int32_t length1, length2=u_strlen(s2); } - /* limit1=start1+min(lenght1, length2) */ + /* limit1=start1+min(length1, length2) */ if(length1 @@ -69,9 +69,9 @@ class UVector32; *
 \htmlonly       "æb"-> the first key is key('a'), the second key is key('e'), and
 *        the third key is key('b'). \endhtmlonly 
* The key of a character, is an integer composed of primary order(short), -* secondary order(char), and tertiary order(char). Java strictly defines the +* secondary order(char), and tertiary order(char). Java strictly defines the * size and signedness of its primitive data types. Therefore, the static -* functions primaryOrder(), secondaryOrder(), and tertiaryOrder() return +* functions primaryOrder(), secondaryOrder(), and tertiaryOrder() return * int32_t to ensure the correctness of the key value. *

Example of the iterator usage: (without error checking) *

@@ -97,8 +97,8 @@ class UVector32;
 * the comparison level of the collator. The method previous() returns the
 * collation order of the previous character based on the comparison level of
 * the collator. The Collation Element Iterator moves only in one direction
-* between calls to reset(), setOffset(), or setText(). That is, next() 
-* and previous() can not be inter-used. Whenever previous() is to be called after 
+* between calls to reset(), setOffset(), or setText(). That is, next()
+* and previous() can not be inter-used. Whenever previous() is to be called after
 * next() or vice versa, reset(), setOffset() or setText() has to be called first
 * to reset the status, shifting pointers to either the end or the start of
 * the string (reset() or setText()), or the specified position (setOffset()).
@@ -109,9 +109,9 @@ class UVector32;
 * The result of a forward iterate (next()) and reversed result of the backward
 * iterate (previous()) on the same string are equivalent, if collation orders
 * with the value 0 are ignored.
-* Character based on the comparison level of the collator.  A collation order 
-* consists of primary order, secondary order and tertiary order.  The data 
-* type of the collation order is int32_t. 
+* Character based on the comparison level of the collator.  A collation order
+* consists of primary order, secondary order and tertiary order.  The data
+* type of the collation order is int32_t.
 *
 * Note, CollationElementIterator should not be subclassed.
 * @see     Collator
@@ -119,13 +119,13 @@ class UVector32;
 * @version 1.8 Jan 16 2001
 */
 class U_I18N_API CollationElementIterator U_FINAL : public UObject {
-public: 
+public:
 
     // CollationElementIterator public data member ------------------------------
 
     enum {
         /**
-         * NULLORDER indicates that an error has occured while processing
+         * NULLORDER indicates that an error has occurred while processing
          * @stable ICU 2.0
          */
         NULLORDER = (int32_t)0xffffffff
@@ -141,7 +141,7 @@ class U_I18N_API CollationElementIterator U_FINAL : public UObject {
     */
     CollationElementIterator(const CollationElementIterator& other);
 
-    /** 
+    /**
     * Destructor
     * @stable ICU 2.0
     */
@@ -176,8 +176,8 @@ class U_I18N_API CollationElementIterator U_FINAL : public UObject {
     /**
     * Gets the ordering priority of the next character in the string.
     * @param status the error code status.
-    * @return the next character's ordering. otherwise returns NULLORDER if an 
-    *         error has occured or if the end of string has been reached
+    * @return the next character's ordering. otherwise returns NULLORDER if an
+    *         error has occurred or if the end of string has been reached
     * @stable ICU 2.0
     */
     int32_t next(UErrorCode& status);
@@ -185,8 +185,8 @@ class U_I18N_API CollationElementIterator U_FINAL : public UObject {
     /**
     * Get the ordering priority of the previous collation element in the string.
     * @param status the error code status.
-    * @return the previous element's ordering. otherwise returns NULLORDER if an 
-    *         error has occured or if the start of string has been reached
+    * @return the previous element's ordering. otherwise returns NULLORDER if an
+    *         error has occurred or if the start of string has been reached
     * @stable ICU 2.0
     */
     int32_t previous(UErrorCode& status);
@@ -216,11 +216,11 @@ class U_I18N_API CollationElementIterator U_FINAL : public UObject {
     static inline int32_t tertiaryOrder(int32_t order);
 
     /**
-    * Return the maximum length of any expansion sequences that end with the 
+    * Return the maximum length of any expansion sequences that end with the
     * specified comparison order.
     * @param order a collation order returned by previous or next.
-    * @return maximum size of the expansion sequences ending with the collation 
-    *         element or 1 if collation element does not occur at the end of any 
+    * @return maximum size of the expansion sequences ending with the collation
+    *         element or 1 if collation element does not occur at the end of any
     *         expansion sequence
     * @stable ICU 2.0
     */
@@ -312,9 +312,9 @@ class U_I18N_API CollationElementIterator U_FINAL : public UObject {
     friend class UCollationPCE;
 
     /**
-    * CollationElementIterator constructor. This takes the source string and the 
-    * collation object. The cursor will walk thru the source string based on the 
-    * predefined collation rules. If the source string is empty, NULLORDER will 
+    * CollationElementIterator constructor. This takes the source string and the
+    * collation object. The cursor will walk thru the source string based on the
+    * predefined collation rules. If the source string is empty, NULLORDER will
     * be returned on the calls to next().
     * @param sourceText    the source string.
     * @param order         the collation object.
@@ -332,9 +332,9 @@ class U_I18N_API CollationElementIterator U_FINAL : public UObject {
     // but only contain the part of RBC== related to data and rules.
 
     /**
-    * CollationElementIterator constructor. This takes the source string and the 
-    * collation object.  The cursor will walk thru the source string based on the 
-    * predefined collation rules.  If the source string is empty, NULLORDER will 
+    * CollationElementIterator constructor. This takes the source string and the
+    * collation object.  The cursor will walk thru the source string based on the
+    * predefined collation rules.  If the source string is empty, NULLORDER will
     * be returned on the calls to next().
     * @param sourceText    the source string.
     * @param order         the collation object.
diff --git a/src/duckdb/extension/icu/third_party/icu/i18n/unicode/format.h b/src/duckdb/extension/icu/third_party/icu/i18n/unicode/format.h
index 96883a81..8788f77e 100644
--- a/src/duckdb/extension/icu/third_party/icu/i18n/unicode/format.h
+++ b/src/duckdb/extension/icu/third_party/icu/i18n/unicode/format.h
@@ -29,8 +29,8 @@
 #if U_SHOW_CPLUSPLUS_API
 
 /**
- * \file 
- * \brief C++ API: Base class for all formats. 
+ * \file
+ * \brief C++ API: Base class for all formats.
  */
 
 #if !UCONFIG_NO_FORMATTING
@@ -40,7 +40,7 @@
 #include "unicode/fieldpos.h"
 #include "unicode/fpositer.h"
 #include "unicode/parsepos.h"
-#include "unicode/parseerr.h" 
+#include "unicode/parseerr.h"
 #include "unicode/locid.h"
 
 U_NAMESPACE_BEGIN
@@ -245,7 +245,7 @@ class U_I18N_API Format : public UObject {
                      UErrorCode& status) const;
 
     /** Get the locale for this format object. You can choose between valid and actual locale.
-     *  @param type type of the locale we're looking for (valid or actual) 
+     *  @param type type of the locale we're looking for (valid or actual)
      *  @param status error code for the operation
      *  @return the locale
      *  @stable ICU 2.8
@@ -254,7 +254,7 @@ class U_I18N_API Format : public UObject {
 
 #ifndef U_HIDE_INTERNAL_API
     /** Get the locale for this format object. You can choose between valid and actual locale.
-     *  @param type type of the locale we're looking for (valid or actual) 
+     *  @param type type of the locale we're looking for (valid or actual)
      *  @param status error code for the operation
      *  @return the locale
      *  @internal
@@ -283,12 +283,12 @@ class U_I18N_API Format : public UObject {
      */
     Format& operator=(const Format&); // Does nothing; for subclasses
 
-       
+
     /**
      * Simple function for initializing a UParseError from a UnicodeString.
      *
      * @param pattern The pattern to copy into the parseError
-     * @param pos The position in pattern where the error occured
+     * @param pos The position in pattern where the error occurred
      * @param parseError The UParseError object to fill in
      * @stable ICU 2.4
      */
diff --git a/src/duckdb/extension/icu/third_party/icu/i18n/unicode/ucol.h b/src/duckdb/extension/icu/third_party/icu/i18n/unicode/ucol.h
index c52f0b1d..cd6d4619 100644
--- a/src/duckdb/extension/icu/third_party/icu/i18n/unicode/ucol.h
+++ b/src/duckdb/extension/icu/third_party/icu/i18n/unicode/ucol.h
@@ -459,7 +459,7 @@ ucol_openRules( const UChar        *rules,
  *                   instantiating collators (like out of memory or similar), this
  *                   API will return an error if an invalid attribute or attribute/value
  *                   combination is specified.
- * @return           A pointer to a UCollator or 0 if an error occured (including an
+ * @return           A pointer to a UCollator or 0 if an error occurred (including an
  *                   invalid attribute).
  * @see ucol_open
  * @see ucol_setAttribute
diff --git a/src/duckdb/extension/icu/third_party/icu/i18n/unicode/ucoleitr.h b/src/duckdb/extension/icu/third_party/icu/i18n/unicode/ucoleitr.h
index 85ec8383..0a2929d4 100644
--- a/src/duckdb/extension/icu/third_party/icu/i18n/unicode/ucoleitr.h
+++ b/src/duckdb/extension/icu/third_party/icu/i18n/unicode/ucoleitr.h
@@ -11,7 +11,7 @@
 * Modification History:
 *
 * Date        Name        Description
-* 02/15/2001  synwee      Modified all methods to process its own function 
+* 02/15/2001  synwee      Modified all methods to process its own function
 *                         instead of calling the equivalent c++ api (coleitr.h)
 *******************************************************************************/
 
@@ -22,8 +22,8 @@
 
 #if !UCONFIG_NO_COLLATION
 
-/**  
- * This indicates an error has occured during processing or if no more CEs is 
+/**
+ * This indicates an error has occurred during processing or if no more CEs is
  * to be returned.
  * @stable ICU 2.0
  */
@@ -31,7 +31,7 @@
 
 #include "unicode/ucol.h"
 
-/** 
+/**
  * The UCollationElements struct.
  * For usage in C programs.
  * @stable ICU 2.0
@@ -42,10 +42,10 @@ typedef struct UCollationElements UCollationElements;
  * \file
  * \brief C API: UCollationElements
  *
- * The UCollationElements API is used as an iterator to walk through each 
+ * The UCollationElements API is used as an iterator to walk through each
  * character of an international string. Use the iterator to return the
- * ordering priority of the positioned character. The ordering priority of a 
- * character, which we refer to as a key, defines how a character is collated 
+ * ordering priority of the positioned character. The ordering priority of a
+ * character, which we refer to as a key, defines how a character is collated
  * in the given collation object.
  * For example, consider the following in Slovak and in traditional Spanish collation:
  * 
@@ -82,19 +82,19 @@ typedef struct UCollationElements UCollationElements;
  * ucol_next() returns the collation order of the next.
  * ucol_prev() returns the collation order of the previous character.
  * The Collation Element Iterator moves only in one direction between calls to
- * ucol_reset. That is, ucol_next() and ucol_prev can not be inter-used. 
- * Whenever ucol_prev is to be called after ucol_next() or vice versa, 
- * ucol_reset has to be called first to reset the status, shifting pointers to 
- * either the end or the start of the string. Hence at the next call of 
- * ucol_prev or ucol_next, the first or last collation order will be returned. 
- * If a change of direction is done without a ucol_reset, the result is 
+ * ucol_reset. That is, ucol_next() and ucol_prev can not be inter-used.
+ * Whenever ucol_prev is to be called after ucol_next() or vice versa,
+ * ucol_reset has to be called first to reset the status, shifting pointers to
+ * either the end or the start of the string. Hence at the next call of
+ * ucol_prev or ucol_next, the first or last collation order will be returned.
+ * If a change of direction is done without a ucol_reset, the result is
  * undefined.
- * The result of a forward iterate (ucol_next) and reversed result of the  
- * backward iterate (ucol_prev) on the same string are equivalent, if 
+ * The result of a forward iterate (ucol_next) and reversed result of the
+ * backward iterate (ucol_prev) on the same string are equivalent, if
  * collation orders with the value 0 are ignored.
- * Character based on the comparison level of the collator.  A collation order 
- * consists of primary order, secondary order and tertiary order.  The data 
- * type of the collation order is int32_t. 
+ * Character based on the comparison level of the collator.  A collation order
+ * consists of primary order, secondary order and tertiary order.  The data
+ * type of the collation order is int32_t.
  *
  * @see UCollator
  */
@@ -109,7 +109,7 @@ typedef struct UCollationElements UCollationElements;
  * @return a struct containing collation element information
  * @stable ICU 2.0
  */
-U_STABLE UCollationElements* U_EXPORT2 
+U_STABLE UCollationElements* U_EXPORT2
 ucol_openElements(const UCollator  *coll,
                   const UChar      *text,
                         int32_t    textLength,
@@ -123,7 +123,7 @@ ucol_openElements(const UCollator  *coll,
  * @return       the hash code.
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2 
+U_STABLE int32_t U_EXPORT2
 ucol_keyHashCode(const uint8_t* key, int32_t length);
 
 /**
@@ -132,7 +132,7 @@ ucol_keyHashCode(const uint8_t* key, int32_t length);
  * @param elems The UCollationElements to close.
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2 
+U_STABLE void U_EXPORT2
 ucol_closeElements(UCollationElements *elems);
 
 /**
@@ -144,7 +144,7 @@ ucol_closeElements(UCollationElements *elems);
  * @see ucol_previous
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2 
+U_STABLE void U_EXPORT2
 ucol_reset(UCollationElements *elems);
 
 /**
@@ -152,41 +152,41 @@ ucol_reset(UCollationElements *elems);
  * A single character may contain more than one collation element.
  * @param elems The UCollationElements containing the text.
  * @param status A pointer to a UErrorCode to receive any errors.
- * @return The next collation elements ordering, otherwise returns UCOL_NULLORDER 
- *         if an error has occured or if the end of string has been reached
+ * @return The next collation elements ordering, otherwise returns UCOL_NULLORDER
+ *         if an error has occurred or if the end of string has been reached
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2 
+U_STABLE int32_t U_EXPORT2
 ucol_next(UCollationElements *elems, UErrorCode *status);
 
 /**
  * Get the ordering priority of the previous collation element in the text.
  * A single character may contain more than one collation element.
- * Note that internally a stack is used to store buffered collation elements. 
+ * Note that internally a stack is used to store buffered collation elements.
  * @param elems The UCollationElements containing the text.
- * @param status A pointer to a UErrorCode to receive any errors. Noteably 
+ * @param status A pointer to a UErrorCode to receive any errors. Noteably
  *               a U_BUFFER_OVERFLOW_ERROR is returned if the internal stack
  *               buffer has been exhausted.
- * @return The previous collation elements ordering, otherwise returns 
- *         UCOL_NULLORDER if an error has occured or if the start of string has 
+ * @return The previous collation elements ordering, otherwise returns
+ *         UCOL_NULLORDER if an error has occurred or if the start of string has
  *         been reached.
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2 
+U_STABLE int32_t U_EXPORT2
 ucol_previous(UCollationElements *elems, UErrorCode *status);
 
 /**
- * Get the maximum length of any expansion sequences that end with the 
+ * Get the maximum length of any expansion sequences that end with the
  * specified comparison order.
  * This is useful for .... ?
  * @param elems The UCollationElements containing the text.
  * @param order A collation order returned by previous or next.
- * @return maximum size of the expansion sequences ending with the collation 
- *         element or 1 if collation element does not occur at the end of any 
+ * @return maximum size of the expansion sequences ending with the collation
+ *         element or 1 if collation element does not occur at the end of any
  *         expansion sequence
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2 
+U_STABLE int32_t U_EXPORT2
 ucol_getMaxExpansion(const UCollationElements *elems, int32_t order);
 
 /**
@@ -201,8 +201,8 @@ ucol_getMaxExpansion(const UCollationElements *elems, int32_t order);
  * @see ucol_getText
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2 
-ucol_setText(      UCollationElements *elems, 
+U_STABLE void U_EXPORT2
+ucol_setText(      UCollationElements *elems,
              const UChar              *text,
                    int32_t            textLength,
                    UErrorCode         *status);
@@ -216,7 +216,7 @@ ucol_setText(      UCollationElements *elems,
  * @see ucol_setOffset
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2 
+U_STABLE int32_t U_EXPORT2
 ucol_getOffset(const UCollationElements *elems);
 
 /**
@@ -231,7 +231,7 @@ ucol_getOffset(const UCollationElements *elems);
  * @see ucol_getOffset
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2 
+U_STABLE void U_EXPORT2
 ucol_setOffset(UCollationElements *elems,
                int32_t        offset,
                UErrorCode         *status);
@@ -243,7 +243,7 @@ ucol_setOffset(UCollationElements *elems,
 * @stable ICU 2.6
 */
 U_STABLE int32_t U_EXPORT2
-ucol_primaryOrder (int32_t order); 
+ucol_primaryOrder (int32_t order);
 
 /**
 * Get the secondary order of a collation order.
@@ -252,7 +252,7 @@ ucol_primaryOrder (int32_t order);
 * @stable ICU 2.6
 */
 U_STABLE int32_t U_EXPORT2
-ucol_secondaryOrder (int32_t order); 
+ucol_secondaryOrder (int32_t order);
 
 /**
 * Get the tertiary order of a collation order.
@@ -261,7 +261,7 @@ ucol_secondaryOrder (int32_t order);
 * @stable ICU 2.6
 */
 U_STABLE int32_t U_EXPORT2
-ucol_tertiaryOrder (int32_t order); 
+ucol_tertiaryOrder (int32_t order);
 
 #endif /* #if !UCONFIG_NO_COLLATION */
 
diff --git a/src/duckdb/extension/icu/third_party/icu/i18n/unicode/umsg.h b/src/duckdb/extension/icu/third_party/icu/i18n/unicode/umsg.h
index 5d235e42..18765b0f 100644
--- a/src/duckdb/extension/icu/third_party/icu/i18n/unicode/umsg.h
+++ b/src/duckdb/extension/icu/third_party/icu/i18n/unicode/umsg.h
@@ -1,10 +1,10 @@
 // © 2016 and later: Unicode, Inc. and others.
 // License & terms of use: http://www.unicode.org/copyright.html
 /********************************************************************
- * COPYRIGHT: 
+ * COPYRIGHT:
  * Copyright (c) 1997-2011, International Business Machines Corporation and
  * others. All Rights Reserved.
- * Copyright (C) 2010 , Yahoo! Inc. 
+ * Copyright (C) 2010 , Yahoo! Inc.
  ********************************************************************
  *
  *   file name:  umsg.h
@@ -100,8 +100,8 @@
  *     u_uastrcpy(str, "MyDisk");
  *     u_uastrcpy(pattern, "The disk {1} contains {0,choice,0#no files|1#one file|1<{0,number,integer} files}");
  *     for(i=0; i<3; i++){
- *       resultlength=0; 
- *       resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), NULL, resultlength, &status, testArgs[i], str); 
+ *       resultlength=0;
+ *       resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), NULL, resultlength, &status, testArgs[i], str);
  *       if(status==U_BUFFER_OVERFLOW_ERROR){
  *         status=U_ZERO_ERROR;
  *         resultlength=resultLengthOut+1;
@@ -175,7 +175,7 @@
  * @see u_parseMessage
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2 
+U_STABLE int32_t U_EXPORT2
 u_formatMessage(const char  *locale,
                  const UChar *pattern,
                 int32_t     patternLength,
@@ -202,7 +202,7 @@ u_formatMessage(const char  *locale,
  * @see u_parseMessage
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2 
+U_STABLE int32_t U_EXPORT2
 u_vformatMessage(   const char  *locale,
                     const UChar *pattern,
                     int32_t     patternLength,
@@ -227,7 +227,7 @@ u_vformatMessage(   const char  *locale,
  * @see u_formatMessage
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2 
+U_STABLE void U_EXPORT2
 u_parseMessage( const char   *locale,
                 const UChar  *pattern,
                 int32_t      patternLength,
@@ -252,7 +252,7 @@ u_parseMessage( const char   *locale,
  * @see u_formatMessage
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2 
+U_STABLE void U_EXPORT2
 u_vparseMessage(const char  *locale,
                 const UChar *pattern,
                 int32_t     patternLength,
@@ -281,7 +281,7 @@ u_vparseMessage(const char  *locale,
  * @see u_parseMessage
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2 
+U_STABLE int32_t U_EXPORT2
 u_formatMessageWithError(   const char    *locale,
                             const UChar   *pattern,
                             int32_t       patternLength,
@@ -310,7 +310,7 @@ u_formatMessageWithError(   const char    *locale,
  * output was truncated.
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2 
+U_STABLE int32_t U_EXPORT2
 u_vformatMessageWithError(  const char   *locale,
                             const UChar  *pattern,
                             int32_t      patternLength,
@@ -338,7 +338,7 @@ u_vformatMessageWithError(  const char   *locale,
  * @see u_formatMessage
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2 
+U_STABLE void U_EXPORT2
 u_parseMessageWithError(const char  *locale,
                         const UChar *pattern,
                         int32_t     patternLength,
@@ -366,7 +366,7 @@ u_parseMessageWithError(const char  *locale,
  * @see u_formatMessage
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2 
+U_STABLE void U_EXPORT2
 u_vparseMessageWithError(const char  *locale,
                          const UChar *pattern,
                          int32_t     patternLength,
@@ -377,7 +377,7 @@ u_vparseMessageWithError(const char  *locale,
                          UErrorCode* status);
 
 /*----------------------- New experimental API --------------------------- */
-/** 
+/**
  * The message format object
  * @stable ICU 2.0
  */
@@ -389,14 +389,14 @@ typedef void* UMessageFormat;
  * @param pattern       A pattern specifying the format to use.
  * @param patternLength Length of the pattern to use
  * @param locale        The locale for which the messages are formatted.
- * @param parseError    A pointer to UParseError struct to receive any errors 
- *                      occured during parsing. Can be NULL.
+ * @param parseError    A pointer to UParseError struct to receive any errors
+ *                      occurred during parsing. Can be NULL.
  * @param status        A pointer to an UErrorCode to receive any errors.
- * @return              A pointer to a UMessageFormat to use for formatting 
- *                      messages, or 0 if an error occurred. 
+ * @return              A pointer to a UMessageFormat to use for formatting
+ *                      messages, or 0 if an error occurred.
  * @stable ICU 2.0
  */
-U_STABLE UMessageFormat* U_EXPORT2 
+U_STABLE UMessageFormat* U_EXPORT2
 umsg_open(  const UChar     *pattern,
             int32_t         patternLength,
             const  char     *locale,
@@ -409,7 +409,7 @@ umsg_open(  const UChar     *pattern,
  * @param format The formatter to close.
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2 
+U_STABLE void U_EXPORT2
 umsg_close(UMessageFormat* format);
 
 #if U_SHOW_CPLUSPLUS_API
@@ -439,7 +439,7 @@ U_NAMESPACE_END
  * @return A pointer to a UDateFormat identical to fmt.
  * @stable ICU 2.0
  */
-U_STABLE UMessageFormat U_EXPORT2 
+U_STABLE UMessageFormat U_EXPORT2
 umsg_clone(const UMessageFormat *fmt,
            UErrorCode *status);
 
@@ -450,7 +450,7 @@ umsg_clone(const UMessageFormat *fmt,
  * @param locale The locale the formatter should use.
  * @stable ICU 2.0
  */
-U_STABLE void  U_EXPORT2 
+U_STABLE void  U_EXPORT2
 umsg_setLocale(UMessageFormat *fmt,
                const char* locale);
 
@@ -461,7 +461,7 @@ umsg_setLocale(UMessageFormat *fmt,
  * @return the locale.
  * @stable ICU 2.0
  */
-U_STABLE const char*  U_EXPORT2 
+U_STABLE const char*  U_EXPORT2
 umsg_getLocale(const UMessageFormat *fmt);
 
 /**
@@ -469,14 +469,14 @@ umsg_getLocale(const UMessageFormat *fmt);
  * @param fmt           The formatter to use
  * @param pattern       The pattern to be applied.
  * @param patternLength Length of the pattern to use
- * @param parseError    Struct to receive information on position 
+ * @param parseError    Struct to receive information on position
  *                      of error if an error is encountered.Can be NULL.
  * @param status        Output param set to success/failure code on
  *                      exit. If the pattern is invalid, this will be
  *                      set to a failure result.
  * @stable ICU 2.0
  */
-U_STABLE void  U_EXPORT2 
+U_STABLE void  U_EXPORT2
 umsg_applyPattern( UMessageFormat *fmt,
                    const UChar* pattern,
                    int32_t patternLength,
@@ -490,13 +490,13 @@ umsg_applyPattern( UMessageFormat *fmt,
  * @param resultLength The maximum size of result.
  * @param status       Output param set to success/failure code on
  *                     exit. If the pattern is invalid, this will be
- *                     set to a failure result.  
+ *                     set to a failure result.
  * @return the pattern of the format
  * @stable ICU 2.0
  */
-U_STABLE int32_t  U_EXPORT2 
+U_STABLE int32_t  U_EXPORT2
 umsg_toPattern(const UMessageFormat *fmt,
-               UChar* result, 
+               UChar* result,
                int32_t resultLength,
                UErrorCode* status);
 
@@ -509,13 +509,13 @@ umsg_toPattern(const UMessageFormat *fmt,
  * @param result        A pointer to a buffer to receive the formatted message.
  * @param resultLength  The maximum size of result.
  * @param status        A pointer to an UErrorCode to receive any errors
- * @param ...           A variable-length argument list containing the arguments 
+ * @param ...           A variable-length argument list containing the arguments
  *                      specified in pattern.
- * @return              The total buffer size needed; if greater than resultLength, 
+ * @return              The total buffer size needed; if greater than resultLength,
  *                      the output was truncated.
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2 
+U_STABLE int32_t U_EXPORT2
 umsg_format(    const UMessageFormat *fmt,
                 UChar          *result,
                 int32_t        resultLength,
@@ -527,17 +527,17 @@ umsg_format(    const UMessageFormat *fmt,
  * This function may perform re-ordering of the arguments depending on the
  * locale. For all numeric arguments, double is assumed unless the type is
  * explicitly integer.  All choice format arguments must be of type double.
- * @param fmt          The formatter to use 
+ * @param fmt          The formatter to use
  * @param result       A pointer to a buffer to receive the formatted message.
  * @param resultLength The maximum size of result.
- * @param ap           A variable-length argument list containing the arguments 
+ * @param ap           A variable-length argument list containing the arguments
  * @param status       A pointer to an UErrorCode to receive any errors
  *                     specified in pattern.
- * @return             The total buffer size needed; if greater than resultLength, 
+ * @return             The total buffer size needed; if greater than resultLength,
  *                     the output was truncated.
  * @stable ICU 2.0
  */
-U_STABLE int32_t U_EXPORT2 
+U_STABLE int32_t U_EXPORT2
 umsg_vformat(   const UMessageFormat *fmt,
                 UChar          *result,
                 int32_t        resultLength,
@@ -549,7 +549,7 @@ umsg_vformat(   const UMessageFormat *fmt,
  * For numeric arguments, this function will always use doubles.  Integer types
  * should not be passed.
  * This function is not able to parse all output from {@link #umsg_format }.
- * @param fmt           The formatter to use 
+ * @param fmt           The formatter to use
  * @param source        The text to parse.
  * @param sourceLength  The length of source, or -1 if null-terminated.
  * @param count         Output param to receive number of elements returned.
@@ -558,7 +558,7 @@ umsg_vformat(   const UMessageFormat *fmt,
  *                      specified in pattern.
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2 
+U_STABLE void U_EXPORT2
 umsg_parse( const UMessageFormat *fmt,
             const UChar    *source,
             int32_t        sourceLength,
@@ -571,7 +571,7 @@ umsg_parse( const UMessageFormat *fmt,
  * For numeric arguments, this function will always use doubles.  Integer types
  * should not be passed.
  * This function is not able to parse all output from {@link #umsg_format }.
- * @param fmt           The formatter to use 
+ * @param fmt           The formatter to use
  * @param source        The text to parse.
  * @param sourceLength  The length of source, or -1 if null-terminated.
  * @param count         Output param to receive number of elements returned.
@@ -581,7 +581,7 @@ umsg_parse( const UMessageFormat *fmt,
  * @see u_formatMessage
  * @stable ICU 2.0
  */
-U_STABLE void U_EXPORT2 
+U_STABLE void U_EXPORT2
 umsg_vparse(const UMessageFormat *fmt,
             const UChar    *source,
             int32_t        sourceLength,
@@ -593,7 +593,7 @@ umsg_vparse(const UMessageFormat *fmt,
 /**
  * Convert an 'apostrophe-friendly' pattern into a standard
  * pattern.  Standard patterns treat all apostrophes as
- * quotes, which is problematic in some languages, e.g. 
+ * quotes, which is problematic in some languages, e.g.
  * French, where apostrophe is commonly used.  This utility
  * assumes that only an unpaired apostrophe immediately before
  * a brace is a true quote.  Other unpaired apostrophes are paired,
@@ -613,8 +613,8 @@ umsg_vparse(const UMessageFormat *fmt,
  *        not
  * @stable ICU 3.4
  */
-U_STABLE int32_t U_EXPORT2 
-umsg_autoQuoteApostrophe(const UChar* pattern, 
+U_STABLE int32_t U_EXPORT2
+umsg_autoQuoteApostrophe(const UChar* pattern,
                          int32_t patternLength,
                          UChar* dest,
                          int32_t destCapacity,
diff --git a/src/duckdb/extension/icu/third_party/icu/i18n/usrchimp.h b/src/duckdb/extension/icu/third_party/icu/i18n/usrchimp.h
index 5438417e..cd3c5a7c 100644
--- a/src/duckdb/extension/icu/third_party/icu/i18n/usrchimp.h
+++ b/src/duckdb/extension/icu/third_party/icu/i18n/usrchimp.h
@@ -43,7 +43,7 @@
 #define isContinuation(CE) (((CE) & UCOL_CONTINUATION_MARKER) == UCOL_CONTINUATION_MARKER)
 
 /**
- * This indicates an error has occured during processing or there are no more CEs
+ * This indicates an error has occurred during processing or there are no more CEs
  * to be returned.
  */
 #define UCOL_PROCESSED_NULLORDER        ((int64_t)U_INT64_MAX)
@@ -101,7 +101,7 @@ class UCollationPCE : public UMemory {
      * @param ixHigh a pointer to an int32_t to receive the iterator index after fetching the CE.
      * @param status A pointer to an UErrorCode to receive any errors.
      * @return The next collation elements ordering, otherwise returns UCOL_PROCESSED_NULLORDER
-     *         if an error has occured or if the end of string has been reached
+     *         if an error has occurred or if the end of string has been reached
      */
     int64_t nextProcessed(int32_t *ixLow, int32_t *ixHigh, UErrorCode *status);
     /**
@@ -114,7 +114,7 @@ class UCollationPCE : public UMemory {
      *               a U_BUFFER_OVERFLOW_ERROR is returned if the internal stack
      *               buffer has been exhausted.
      * @return The previous collation elements ordering, otherwise returns
-     *         UCOL_PROCESSED_NULLORDER if an error has occured or if the start of
+     *         UCOL_PROCESSED_NULLORDER if an error has occurred or if the start of
      *         string has been reached.
      */
     int64_t previousProcessed(int32_t *ixLow, int32_t *ixHigh, UErrorCode *status);
diff --git a/src/duckdb/extension/json/include/json_common.hpp b/src/duckdb/extension/json/include/json_common.hpp
index 87205802..ca29cde9 100644
--- a/src/duckdb/extension/json/include/json_common.hpp
+++ b/src/duckdb/extension/json/include/json_common.hpp
@@ -301,7 +301,7 @@ struct JSONCommon {
 	//! Get JSON pointer (/field/index/... syntax)
 	static inline yyjson_val *GetPointer(yyjson_val *val, const char *ptr, const idx_t &len) {
 		yyjson_ptr_err err;
-		return len == 1 ? val : unsafe_yyjson_ptr_getx(val, ptr, len, &err);
+		return unsafe_yyjson_ptr_getx(val, ptr, len, &err);
 	}
 	//! Get JSON path ($.field[index]... syntax)
 	static yyjson_val *GetPath(yyjson_val *val, const char *ptr, const idx_t &len);
diff --git a/src/duckdb/extension/json/json_functions/json_structure.cpp b/src/duckdb/extension/json/json_functions/json_structure.cpp
index 04800572..7982003f 100644
--- a/src/duckdb/extension/json/json_functions/json_structure.cpp
+++ b/src/duckdb/extension/json/json_functions/json_structure.cpp
@@ -214,8 +214,8 @@ void JSONStructureNode::RefineCandidateTypesObject(yyjson_val *vals[], const idx
 				D_ASSERT(it != key_map.end());
 				const auto child_idx = it->second;
 				child_vals[child_idx][i] = child_val;
+				found_key_count += !found_keys[child_idx];
 				found_keys[child_idx] = true;
-				found_key_count++;
 			}
 
 			if (found_key_count != child_count) {
@@ -562,10 +562,12 @@ static void MergeNodeVal(JSONStructureNode &merged, const JSONStructureDescripti
 	}
 	if (!merged.initialized) {
 		merged_desc.candidate_types = child_desc.candidate_types;
-	} else if (!merged_desc.candidate_types.empty() && !child_desc.candidate_types.empty() &&
-	           merged_desc.candidate_types.back() != child_desc.candidate_types.back()) {
+	} else if (merged_desc.candidate_types.empty() != child_desc.candidate_types.empty() // both empty or neither empty
+	           || (!merged_desc.candidate_types.empty() &&
+	               merged_desc.candidate_types.back() != child_desc.candidate_types.back())) { // non-empty: check type
 		merged_desc.candidate_types.clear(); // Not the same, default to VARCHAR
 	}
+
 	merged.initialized = true;
 }
 
@@ -704,14 +706,18 @@ static LogicalType StructureToTypeObject(ClientContext &context, const JSONStruc
 	D_ASSERT(node.descriptions.size() == 1 && node.descriptions[0].type == LogicalTypeId::STRUCT);
 	auto &desc = node.descriptions[0];
 
-	// If it's an empty struct we do MAP of JSON instead
 	if (desc.children.empty()) {
-		// Empty struct - let's do MAP of JSON instead
-		return LogicalType::MAP(LogicalType::VARCHAR, null_type);
+		if (map_inference_threshold != DConstants::INVALID_INDEX) {
+			// Empty struct - let's do MAP of JSON instead
+			return LogicalType::MAP(LogicalType::VARCHAR, null_type);
+		} else {
+			return LogicalType::JSON();
+		}
 	}
 
 	// If it's an inconsistent object we also just do MAP with the best-possible, recursively-merged value type
-	if (IsStructureInconsistent(desc, node.count, node.null_count, field_appearance_threshold)) {
+	if (map_inference_threshold != DConstants::INVALID_INDEX &&
+	    IsStructureInconsistent(desc, node.count, node.null_count, field_appearance_threshold)) {
 		return LogicalType::MAP(LogicalType::VARCHAR,
 		                        GetMergedType(context, node, max_depth, field_appearance_threshold,
 		                                      map_inference_threshold, depth + 1, null_type));
diff --git a/src/duckdb/extension/parquet/column_writer.cpp b/src/duckdb/extension/parquet/column_writer.cpp
index 1d42da05..0b1d867c 100644
--- a/src/duckdb/extension/parquet/column_writer.cpp
+++ b/src/duckdb/extension/parquet/column_writer.cpp
@@ -2244,7 +2244,8 @@ unique_ptr ColumnWriter::CreateWriterRecursive(ClientContext &cont
 	schemas.push_back(std::move(schema_element));
 	schema_path.push_back(name);
 
-	if (type.id() == LogicalTypeId::BLOB && type.GetAlias() == "WKB_BLOB") {
+	if (type.id() == LogicalTypeId::BLOB && type.GetAlias() == "WKB_BLOB" &&
+	    GeoParquetFileMetadata::IsGeoParquetConversionEnabled(context)) {
 		return make_uniq(context, writer, schema_idx, std::move(schema_path), max_repeat, max_define,
 		                                  can_have_nulls, name);
 	}
diff --git a/src/duckdb/extension/parquet/geo_parquet.cpp b/src/duckdb/extension/parquet/geo_parquet.cpp
index 28c56991..b82cd502 100644
--- a/src/duckdb/extension/parquet/geo_parquet.cpp
+++ b/src/duckdb/extension/parquet/geo_parquet.cpp
@@ -177,7 +177,14 @@ void GeoParquetColumnMetadataWriter::Update(GeoParquetColumnMetadata &meta, Vect
 //------------------------------------------------------------------------------
 
 unique_ptr
-GeoParquetFileMetadata::TryRead(const duckdb_parquet::format::FileMetaData &file_meta_data, ClientContext &context) {
+GeoParquetFileMetadata::TryRead(const duckdb_parquet::format::FileMetaData &file_meta_data,
+                                const ClientContext &context) {
+
+	// Conversion not enabled, or spatial is not loaded!
+	if (!IsGeoParquetConversionEnabled(context)) {
+		return nullptr;
+	}
+
 	for (auto &kv : file_meta_data.key_value_metadata) {
 		if (kv.key == "geo") {
 			const auto geo_metadata = yyjson_read(kv.value.c_str(), kv.value.size(), 0);
@@ -186,14 +193,6 @@ GeoParquetFileMetadata::TryRead(const duckdb_parquet::format::FileMetaData &file
 				return nullptr;
 			}
 
-			// Check if the spatial extension is loaded, or try to autoload it.
-			const auto is_loaded = ExtensionHelper::TryAutoLoadExtension(context, "spatial");
-			if (!is_loaded) {
-				// Spatial extension is not available, we can't make use of the metadata anyway.
-				yyjson_doc_free(geo_metadata);
-				return nullptr;
-			}
-
 			try {
 				// Check the root object
 				const auto root = yyjson_doc_get_root(geo_metadata);
@@ -368,6 +367,22 @@ void GeoParquetFileMetadata::RegisterGeometryColumn(const string &column_name) {
 	geometry_columns[column_name] = GeoParquetColumnMetadata();
 }
 
+bool GeoParquetFileMetadata::IsGeoParquetConversionEnabled(const ClientContext &context) {
+	Value geoparquet_enabled;
+	if (!context.TryGetCurrentSetting("enable_geoparquet_conversion", geoparquet_enabled)) {
+		return false;
+	}
+	if (!geoparquet_enabled.GetValue()) {
+		// Disabled by setting
+		return false;
+	}
+	if (!context.db->ExtensionIsLoaded("spatial")) {
+		// Spatial extension is not loaded, we cant convert anyway
+		return false;
+	}
+	return true;
+}
+
 unique_ptr GeoParquetFileMetadata::CreateColumnReader(ParquetReader &reader,
                                                                     const LogicalType &logical_type,
                                                                     const SchemaElement &s_ele, idx_t schema_idx_p,
diff --git a/src/duckdb/extension/parquet/include/geo_parquet.hpp b/src/duckdb/extension/parquet/include/geo_parquet.hpp
index ab04dcdf..e9b7ce48 100644
--- a/src/duckdb/extension/parquet/include/geo_parquet.hpp
+++ b/src/duckdb/extension/parquet/include/geo_parquet.hpp
@@ -120,7 +120,7 @@ class GeoParquetFileMetadata {
 	// Try to read GeoParquet metadata. Returns nullptr if not found, invalid or the required spatial extension is not
 	// available.
 	static unique_ptr TryRead(const duckdb_parquet::format::FileMetaData &file_meta_data,
-	                                                  ClientContext &context);
+	                                                  const ClientContext &context);
 	void Write(duckdb_parquet::format::FileMetaData &file_meta_data) const;
 
 	void FlushColumnMeta(const string &column_name, const GeoParquetColumnMetadata &meta);
@@ -133,6 +133,8 @@ class GeoParquetFileMetadata {
 	bool IsGeometryColumn(const string &column_name) const;
 	void RegisterGeometryColumn(const string &column_name);
 
+	static bool IsGeoParquetConversionEnabled(const ClientContext &context);
+
 private:
 	mutex write_lock;
 	string version = "1.1.0";
diff --git a/src/duckdb/extension/parquet/include/parquet_reader.hpp b/src/duckdb/extension/parquet/include/parquet_reader.hpp
index ef8dcaf8..6b536bbd 100644
--- a/src/duckdb/extension/parquet/include/parquet_reader.hpp
+++ b/src/duckdb/extension/parquet/include/parquet_reader.hpp
@@ -93,6 +93,7 @@ struct ParquetOptions {
 
 	MultiFileReaderOptions file_options;
 	vector schema;
+	idx_t explicit_cardinality = 0;
 
 public:
 	void Serialize(Serializer &serializer) const;
diff --git a/src/duckdb/extension/parquet/include/parquet_rle_bp_decoder.hpp b/src/duckdb/extension/parquet/include/parquet_rle_bp_decoder.hpp
index 27093388..49583f71 100644
--- a/src/duckdb/extension/parquet/include/parquet_rle_bp_decoder.hpp
+++ b/src/duckdb/extension/parquet/include/parquet_rle_bp_decoder.hpp
@@ -66,7 +66,7 @@ class RleBpDecoder {
 			return 0;
 		}
 		uint8_t ret = 1;
-		while (((idx_t)(1u << ret) - 1) < val) {
+		while ((((idx_t)1u << (idx_t)ret) - 1) < val) {
 			ret++;
 		}
 		return ret;
diff --git a/src/duckdb/extension/parquet/include/templated_column_reader.hpp b/src/duckdb/extension/parquet/include/templated_column_reader.hpp
index 3ebddfee..f9311524 100644
--- a/src/duckdb/extension/parquet/include/templated_column_reader.hpp
+++ b/src/duckdb/extension/parquet/include/templated_column_reader.hpp
@@ -68,10 +68,6 @@ class TemplatedColumnReader : public ColumnReader {
 
 	void Offsets(uint32_t *offsets, uint8_t *defines, uint64_t num_values, parquet_filter_t &filter,
 	             idx_t result_offset, Vector &result) override {
-		if (!dict || dict->len == 0) {
-			throw IOException("Parquet file is likely corrupted, cannot have dictionary offsets without seeing a "
-			                  "non-empty dictionary first.");
-		}
 		if (HasDefines()) {
 			OffsetsInternal(*dict, offsets, defines, num_values, filter, result_offset, result);
 		} else {
diff --git a/src/duckdb/extension/parquet/parquet_extension.cpp b/src/duckdb/extension/parquet/parquet_extension.cpp
index 596fed87..617dc3ca 100644
--- a/src/duckdb/extension/parquet/parquet_extension.cpp
+++ b/src/duckdb/extension/parquet/parquet_extension.cpp
@@ -70,8 +70,8 @@ struct ParquetReadBindData : public TableFunctionData {
 	// These come from the initial_reader, but need to be stored in case the initial_reader is removed by a filter
 	idx_t initial_file_cardinality;
 	idx_t initial_file_row_groups;
+	idx_t explicit_cardinality = 0; // can be set to inject exterior cardinality knowledge (e.g. from a data lake)
 	ParquetOptions parquet_options;
-
 	MultiFileReaderBindData reader_bind;
 
 	void Initialize(shared_ptr reader) {
@@ -395,6 +395,7 @@ class ParquetScanFunction {
 		table_function.named_parameters["file_row_number"] = LogicalType::BOOLEAN;
 		table_function.named_parameters["debug_use_openssl"] = LogicalType::BOOLEAN;
 		table_function.named_parameters["compression"] = LogicalType::VARCHAR;
+		table_function.named_parameters["explicit_cardinality"] = LogicalType::UBIGINT;
 		table_function.named_parameters["schema"] =
 		    LogicalType::MAP(LogicalType::INTEGER, LogicalType::STRUCT({{{"name", LogicalType::VARCHAR},
 		                                                                 {"type", LogicalType::VARCHAR},
@@ -545,7 +546,11 @@ class ParquetScanFunction {
 			result->reader_bind = result->multi_file_reader->BindReader(
 			    context, result->types, result->names, *result->file_list, *result, parquet_options);
 		}
-
+		if (parquet_options.explicit_cardinality) {
+			auto file_count = result->file_list->GetTotalFileCount();
+			result->explicit_cardinality = parquet_options.explicit_cardinality;
+			result->initial_file_cardinality = result->explicit_cardinality / (file_count ? file_count : 1);
+		}
 		if (return_types.empty()) {
 			// no expected types - just copy the types
 			return_types = result->types;
@@ -618,6 +623,8 @@ class ParquetScanFunction {
 
 				// cannot be combined with hive_partitioning=true, so we disable auto-detection
 				parquet_options.file_options.auto_detect_hive_partitioning = false;
+			} else if (loption == "explicit_cardinality") {
+				parquet_options.explicit_cardinality = UBigIntValue::Get(kv.second);
 			} else if (loption == "encryption_config") {
 				parquet_options.encryption_config = ParquetEncryptionConfig::Create(context, kv.second);
 			}
@@ -847,13 +854,15 @@ class ParquetScanFunction {
 
 	static unique_ptr ParquetCardinality(ClientContext &context, const FunctionData *bind_data) {
 		auto &data = bind_data->Cast();
-
+		if (data.explicit_cardinality) {
+			return make_uniq(data.explicit_cardinality);
+		}
 		auto file_list_cardinality_estimate = data.file_list->GetCardinality(context);
 		if (file_list_cardinality_estimate) {
 			return file_list_cardinality_estimate;
 		}
-
-		return make_uniq(data.initial_file_cardinality * data.file_list->GetTotalFileCount());
+		return make_uniq(MaxValue(data.initial_file_cardinality, (idx_t)1) *
+		                                 data.file_list->GetTotalFileCount());
 	}
 
 	static idx_t ParquetScanMaxThreads(ClientContext &context, const FunctionData *bind_data) {
@@ -1573,7 +1582,7 @@ static vector> ParquetWriteSelect(CopyToSelectInput &inpu
 		// Spatial types need to be encoded into WKB when writing GeoParquet.
 		// But dont perform this conversion if this is a EXPORT DATABASE statement
 		if (input.copy_to_type == CopyToType::COPY_TO_FILE && type.id() == LogicalTypeId::BLOB && type.HasAlias() &&
-		    type.GetAlias() == "GEOMETRY") {
+		    type.GetAlias() == "GEOMETRY" && GeoParquetFileMetadata::IsGeoParquetConversionEnabled(context)) {
 
 			LogicalType wkb_blob_type(LogicalTypeId::BLOB);
 			wkb_blob_type.SetAlias("WKB_BLOB");
@@ -1680,6 +1689,11 @@ void ParquetExtension::Load(DuckDB &db) {
 	config.replacement_scans.emplace_back(ParquetScanReplacement);
 	config.AddExtensionOption("binary_as_string", "In Parquet files, interpret binary data as a string.",
 	                          LogicalType::BOOLEAN);
+
+	config.AddExtensionOption(
+	    "enable_geoparquet_conversion",
+	    "Attempt to decode/encode geometry data in/as GeoParquet files if the spatial extension is present.",
+	    LogicalType::BOOLEAN, Value::BOOLEAN(true));
 }
 
 std::string ParquetExtension::Name() {
diff --git a/src/duckdb/extension/parquet/parquet_reader.cpp b/src/duckdb/extension/parquet/parquet_reader.cpp
index 0508d254..7357767b 100644
--- a/src/duckdb/extension/parquet/parquet_reader.cpp
+++ b/src/duckdb/extension/parquet/parquet_reader.cpp
@@ -637,8 +637,7 @@ uint32_t ParquetReader::ReadData(duckdb_apache::thrift::protocol::TProtocol &ipr
 const ParquetRowGroup &ParquetReader::GetGroup(ParquetReaderScanState &state) {
 	auto file_meta_data = GetFileMetadata();
 	D_ASSERT(state.current_group >= 0 && (idx_t)state.current_group < state.group_idx_list.size());
-	D_ASSERT(state.group_idx_list[state.current_group] >= 0 &&
-	         state.group_idx_list[state.current_group] < file_meta_data->row_groups.size());
+	D_ASSERT(state.group_idx_list[state.current_group] < file_meta_data->row_groups.size());
 	return file_meta_data->row_groups[state.group_idx_list[state.current_group]];
 }
 
diff --git a/src/duckdb/extension/parquet/parquet_writer.cpp b/src/duckdb/extension/parquet/parquet_writer.cpp
index f9b864ef..a7a847af 100644
--- a/src/duckdb/extension/parquet/parquet_writer.cpp
+++ b/src/duckdb/extension/parquet/parquet_writer.cpp
@@ -466,7 +466,7 @@ void ParquetWriter::PrepareRowGroup(ColumnDataCollection &buffer, PreparedRowGro
 // Validation code adapted from Impala
 static void ValidateOffsetInFile(const string &filename, idx_t col_idx, idx_t file_length, idx_t offset,
                                  const string &offset_name) {
-	if (offset < 0 || offset >= file_length) {
+	if (offset >= file_length) {
 		throw IOException("File '%s': metadata is corrupt. Column %d has invalid "
 		                  "%s (offset=%llu file_size=%llu).",
 		                  filename, col_idx, offset_name, offset, file_length);
diff --git a/src/duckdb/extension/parquet/serialize_parquet.cpp b/src/duckdb/extension/parquet/serialize_parquet.cpp
index e6aeac02..b72a78be 100644
--- a/src/duckdb/extension/parquet/serialize_parquet.cpp
+++ b/src/duckdb/extension/parquet/serialize_parquet.cpp
@@ -7,8 +7,6 @@
 #include "duckdb/common/serializer/deserializer.hpp"
 #include "parquet_reader.hpp"
 #include "parquet_crypto.hpp"
-#include "parquet_reader.hpp"
-#include "parquet_writer.hpp"
 #include "parquet_writer.hpp"
 
 namespace duckdb {
diff --git a/src/duckdb/src/catalog/catalog_entry/duck_schema_entry.cpp b/src/duckdb/src/catalog/catalog_entry/duck_schema_entry.cpp
index 42dea06f..f3c8684f 100644
--- a/src/duckdb/src/catalog/catalog_entry/duck_schema_entry.cpp
+++ b/src/duckdb/src/catalog/catalog_entry/duck_schema_entry.cpp
@@ -119,6 +119,13 @@ optional_ptr DuckSchemaEntry::AddEntryInternal(CatalogTransaction
 	// first find the set for this entry
 	auto &set = GetCatalogSet(entry_type);
 	dependencies.AddDependency(*this);
+	if (on_conflict == OnCreateConflict::IGNORE_ON_CONFLICT) {
+		auto old_entry = set.GetEntry(transaction, entry_name);
+		if (old_entry) {
+			return nullptr;
+		}
+	}
+
 	if (on_conflict == OnCreateConflict::REPLACE_ON_CONFLICT) {
 		// CREATE OR REPLACE: first try to drop the entry
 		auto old_entry = set.GetEntry(transaction, entry_name);
@@ -315,7 +322,7 @@ void DuckSchemaEntry::DropEntry(ClientContext &context, DropInfo &info) {
 		throw InternalException("Failed to drop entry \"%s\" - entry could not be found", info.name);
 	}
 	if (existing_entry->type != info.type) {
-		throw CatalogException("Existing object %s is of type %s, trying to replace with type %s", info.name,
+		throw CatalogException("Existing object %s is of type %s, trying to drop type %s", info.name,
 		                       CatalogTypeToString(existing_entry->type), CatalogTypeToString(info.type));
 	}
 
diff --git a/src/duckdb/src/catalog/default/default_functions.cpp b/src/duckdb/src/catalog/default/default_functions.cpp
index b4f7deca..f7f4634b 100644
--- a/src/duckdb/src/catalog/default/default_functions.cpp
+++ b/src/duckdb/src/catalog/default/default_functions.cpp
@@ -12,7 +12,7 @@ namespace duckdb {
 static const DefaultMacro internal_macros[] = {
 	{DEFAULT_SCHEMA, "current_role", {nullptr}, {{nullptr, nullptr}}, "'duckdb'"},                       // user name of current execution context
 	{DEFAULT_SCHEMA, "current_user", {nullptr}, {{nullptr, nullptr}}, "'duckdb'"},                       // user name of current execution context
-	{DEFAULT_SCHEMA, "current_catalog", {nullptr}, {{nullptr, nullptr}}, "current_database()"},          // name of current database (called "catalog" in the SQL standard)
+	{DEFAULT_SCHEMA, "current_catalog", {nullptr}, {{nullptr, nullptr}}, "main.current_database()"},          // name of current database (called "catalog" in the SQL standard)
 	{DEFAULT_SCHEMA, "user", {nullptr}, {{nullptr, nullptr}}, "current_user"},                           // equivalent to current_user
 	{DEFAULT_SCHEMA, "session_user", {nullptr}, {{nullptr, nullptr}}, "'duckdb'"},                       // session user name
 	{"pg_catalog", "inet_client_addr", {nullptr}, {{nullptr, nullptr}}, "NULL"},                       // address of the remote connection
@@ -27,10 +27,10 @@ static const DefaultMacro internal_macros[] = {
 
 	{"pg_catalog", "pg_typeof", {"expression", nullptr}, {{nullptr, nullptr}}, "lower(typeof(expression))"},  // get the data type of any value
 
-	{"pg_catalog", "current_database", {nullptr}, {{nullptr, nullptr}}, "current_database()"},  	    // name of current database (called "catalog" in the SQL standard)
-	{"pg_catalog", "current_query", {nullptr}, {{nullptr, nullptr}}, "current_query()"},  	        // the currently executing query (NULL if not inside a plpgsql function)
-	{"pg_catalog", "current_schema", {nullptr}, {{nullptr, nullptr}}, "current_schema()"},  	        // name of current schema
-	{"pg_catalog", "current_schemas", {"include_implicit"}, {{nullptr, nullptr}}, "current_schemas(include_implicit)"},  	// names of schemas in search path
+	{"pg_catalog", "current_database", {nullptr}, {{nullptr, nullptr}}, "main.current_database()"},  	    // name of current database (called "catalog" in the SQL standard)
+	{"pg_catalog", "current_query", {nullptr}, {{nullptr, nullptr}}, "main.current_query()"},  	        // the currently executing query (NULL if not inside a plpgsql function)
+	{"pg_catalog", "current_schema", {nullptr}, {{nullptr, nullptr}}, "main.current_schema()"},  	        // name of current schema
+	{"pg_catalog", "current_schemas", {"include_implicit"}, {{nullptr, nullptr}}, "main.current_schemas(include_implicit)"},  	// names of schemas in search path
 
 	// privilege functions
 	{"pg_catalog", "has_any_column_privilege", {"table", "privilege", nullptr}, {{nullptr, nullptr}}, "true"},  //boolean  //does current user have privilege for any column of table
diff --git a/src/duckdb/src/common/allocator.cpp b/src/duckdb/src/common/allocator.cpp
index d3ef18bb..c1338715 100644
--- a/src/duckdb/src/common/allocator.cpp
+++ b/src/duckdb/src/common/allocator.cpp
@@ -242,12 +242,13 @@ static void MallocTrim(idx_t pad) {
 	static atomic LAST_TRIM_TIMESTAMP_MS {0};
 
 	int64_t last_trim_timestamp_ms = LAST_TRIM_TIMESTAMP_MS.load();
-	const int64_t current_timestamp_ms = Timestamp::GetEpochMs(Timestamp::GetCurrentTimestamp());
+	int64_t current_timestamp_ms = Timestamp::GetEpochMs(Timestamp::GetCurrentTimestamp());
 
 	if (current_timestamp_ms - last_trim_timestamp_ms < TRIM_INTERVAL_MS) {
 		return; // We trimmed less than TRIM_INTERVAL_MS ago
 	}
-	if (!std::atomic_compare_exchange_weak(&LAST_TRIM_TIMESTAMP_MS, &last_trim_timestamp_ms, current_timestamp_ms)) {
+	if (!LAST_TRIM_TIMESTAMP_MS.compare_exchange_strong(last_trim_timestamp_ms, current_timestamp_ms,
+	                                                    std::memory_order_acquire, std::memory_order_relaxed)) {
 		return; // Another thread has updated LAST_TRIM_TIMESTAMP_MS since we loaded it
 	}
 
diff --git a/src/duckdb/src/common/arrow/arrow_appender.cpp b/src/duckdb/src/common/arrow/arrow_appender.cpp
index b478fdb3..632bffc6 100644
--- a/src/duckdb/src/common/arrow/arrow_appender.cpp
+++ b/src/duckdb/src/common/arrow/arrow_appender.cpp
@@ -225,6 +225,7 @@ static void InitializeFunctionPointers(ArrowAppendData &append_data, const Logic
 		break;
 	case LogicalTypeId::BLOB:
 	case LogicalTypeId::BIT:
+	case LogicalTypeId::VARINT:
 		if (append_data.options.arrow_offset_size == ArrowOffsetSize::LARGE) {
 			InitializeAppenderForType>(append_data);
 		} else {
diff --git a/src/duckdb/src/common/arrow/arrow_converter.cpp b/src/duckdb/src/common/arrow/arrow_converter.cpp
index 851d45b5..9c674cd7 100644
--- a/src/duckdb/src/common/arrow/arrow_converter.cpp
+++ b/src/duckdb/src/common/arrow/arrow_converter.cpp
@@ -142,6 +142,17 @@ void SetArrowFormat(DuckDBArrowSchemaHolder &root_holder, ArrowSchema &child, co
 		child.metadata = root_holder.metadata_info.back().get();
 		break;
 	}
+	case LogicalTypeId::VARINT: {
+		if (options.arrow_offset_size == ArrowOffsetSize::LARGE) {
+			child.format = "Z";
+		} else {
+			child.format = "z";
+		}
+		auto schema_metadata = ArrowSchemaMetadata::MetadataFromName("duckdb.varint");
+		root_holder.metadata_info.emplace_back(schema_metadata.SerializeMetadata());
+		child.metadata = root_holder.metadata_info.back().get();
+		break;
+	}
 	case LogicalTypeId::DOUBLE:
 		child.format = "g";
 		break;
diff --git a/src/duckdb/src/common/arrow/schema_metadata.cpp b/src/duckdb/src/common/arrow/schema_metadata.cpp
index acbf75c5..7240d40f 100644
--- a/src/duckdb/src/common/arrow/schema_metadata.cpp
+++ b/src/duckdb/src/common/arrow/schema_metadata.cpp
@@ -36,7 +36,12 @@ void ArrowSchemaMetadata::AddOption(const string &key, const string &value) {
 	metadata_map[key] = value;
 }
 string ArrowSchemaMetadata::GetOption(const string &key) const {
-	return metadata_map.at(key);
+	auto it = metadata_map.find(key);
+	if (it != metadata_map.end()) {
+		return it->second;
+	} else {
+		return "";
+	}
 }
 
 string ArrowSchemaMetadata::GetExtensionName() const {
@@ -51,9 +56,6 @@ ArrowSchemaMetadata ArrowSchemaMetadata::MetadataFromName(const string &extensio
 }
 
 bool ArrowSchemaMetadata::HasExtension() {
-	if (metadata_map.find(ARROW_EXTENSION_NAME) == metadata_map.end()) {
-		return false;
-	}
 	auto arrow_extension = GetOption(ArrowSchemaMetadata::ARROW_EXTENSION_NAME);
 	// FIXME: We are currently ignoring the ogc extensions
 	return !arrow_extension.empty() && !StringUtil::StartsWith(arrow_extension, "ogc");
diff --git a/src/duckdb/src/common/enum_util.cpp b/src/duckdb/src/common/enum_util.cpp
index c4185af9..9a0db08f 100644
--- a/src/duckdb/src/common/enum_util.cpp
+++ b/src/duckdb/src/common/enum_util.cpp
@@ -4394,6 +4394,10 @@ const char* EnumUtil::ToChars(MetricsType value) {
 		return "OPERATOR_ROWS_SCANNED";
 	case MetricsType::OPERATOR_TIMING:
 		return "OPERATOR_TIMING";
+	case MetricsType::LATENCY:
+		return "LATENCY";
+	case MetricsType::ROWS_RETURNED:
+		return "ROWS_RETURNED";
 	case MetricsType::RESULT_SET_SIZE:
 		return "RESULT_SET_SIZE";
 	case MetricsType::ALL_OPTIMIZERS:
@@ -4495,6 +4499,12 @@ MetricsType EnumUtil::FromString(const char *value) {
 	if (StringUtil::Equals(value, "OPERATOR_TIMING")) {
 		return MetricsType::OPERATOR_TIMING;
 	}
+	if (StringUtil::Equals(value, "LATENCY")) {
+		return MetricsType::LATENCY;
+	}
+	if (StringUtil::Equals(value, "ROWS_RETURNED")) {
+		return MetricsType::ROWS_RETURNED;
+	}
 	if (StringUtil::Equals(value, "RESULT_SET_SIZE")) {
 		return MetricsType::RESULT_SET_SIZE;
 	}
@@ -6457,6 +6467,29 @@ SecretPersistType EnumUtil::FromString(const char *value) {
 	throw NotImplementedException(StringUtil::Format("Enum value: '%s' not implemented in FromString", value));
 }
 
+template<>
+const char* EnumUtil::ToChars(SecretSerializationType value) {
+	switch(value) {
+	case SecretSerializationType::CUSTOM:
+		return "CUSTOM";
+	case SecretSerializationType::KEY_VALUE_SECRET:
+		return "KEY_VALUE_SECRET";
+	default:
+		throw NotImplementedException(StringUtil::Format("Enum value: '%d' not implemented in ToChars", value));
+	}
+}
+
+template<>
+SecretSerializationType EnumUtil::FromString(const char *value) {
+	if (StringUtil::Equals(value, "CUSTOM")) {
+		return SecretSerializationType::CUSTOM;
+	}
+	if (StringUtil::Equals(value, "KEY_VALUE_SECRET")) {
+		return SecretSerializationType::KEY_VALUE_SECRET;
+	}
+	throw NotImplementedException(StringUtil::Format("Enum value: '%s' not implemented in FromString", value));
+}
+
 template<>
 const char* EnumUtil::ToChars(SequenceInfo value) {
 	switch(value) {
diff --git a/src/duckdb/src/common/exception.cpp b/src/duckdb/src/common/exception.cpp
index b8aac720..4527f3ff 100644
--- a/src/duckdb/src/common/exception.cpp
+++ b/src/duckdb/src/common/exception.cpp
@@ -292,6 +292,9 @@ PermissionException::PermissionException(const string &msg) : Exception(Exceptio
 SyntaxException::SyntaxException(const string &msg) : Exception(ExceptionType::SYNTAX, msg) {
 }
 
+ExecutorException::ExecutorException(const string &msg) : Exception(ExceptionType::EXECUTOR, msg) {
+}
+
 ConstraintException::ConstraintException(const string &msg) : Exception(ExceptionType::CONSTRAINT, msg) {
 }
 
diff --git a/src/duckdb/src/common/extra_type_info.cpp b/src/duckdb/src/common/extra_type_info.cpp
index 6c09480c..54f03447 100644
--- a/src/duckdb/src/common/extra_type_info.cpp
+++ b/src/duckdb/src/common/extra_type_info.cpp
@@ -1,4 +1,5 @@
 #include "duckdb/common/extra_type_info.hpp"
+#include "duckdb/common/extra_type_info/enum_type_info.hpp"
 #include "duckdb/common/serializer/deserializer.hpp"
 #include "duckdb/common/enum_util.hpp"
 #include "duckdb/common/numeric_utils.hpp"
@@ -220,50 +221,6 @@ PhysicalType EnumTypeInfo::DictType(idx_t size) {
 	}
 }
 
-template 
-struct EnumTypeInfoTemplated : public EnumTypeInfo {
-	explicit EnumTypeInfoTemplated(Vector &values_insert_order_p, idx_t size_p)
-	    : EnumTypeInfo(values_insert_order_p, size_p) {
-		D_ASSERT(values_insert_order_p.GetType().InternalType() == PhysicalType::VARCHAR);
-
-		UnifiedVectorFormat vdata;
-		values_insert_order.ToUnifiedFormat(size_p, vdata);
-
-		auto data = UnifiedVectorFormat::GetData(vdata);
-		for (idx_t i = 0; i < size_p; i++) {
-			auto idx = vdata.sel->get_index(i);
-			if (!vdata.validity.RowIsValid(idx)) {
-				throw InternalException("Attempted to create ENUM type with NULL value");
-			}
-			if (values.count(data[idx]) > 0) {
-				throw InvalidInputException("Attempted to create ENUM type with duplicate value %s",
-				                            data[idx].GetString());
-			}
-			values[data[idx]] = UnsafeNumericCast(i);
-		}
-	}
-
-	static shared_ptr Deserialize(Deserializer &deserializer, uint32_t size) {
-		Vector values_insert_order(LogicalType::VARCHAR, size);
-		auto strings = FlatVector::GetData(values_insert_order);
-
-		deserializer.ReadList(201, "values", [&](Deserializer::List &list, idx_t i) {
-			strings[i] = StringVector::AddStringOrBlob(values_insert_order, list.ReadElement());
-		});
-		return make_shared_ptr(values_insert_order, size);
-	}
-
-	const string_map_t &GetValues() const {
-		return values;
-	}
-
-	EnumTypeInfoTemplated(const EnumTypeInfoTemplated &) = delete;
-	EnumTypeInfoTemplated &operator=(const EnumTypeInfoTemplated &) = delete;
-
-private:
-	string_map_t values;
-};
-
 EnumTypeInfo::EnumTypeInfo(Vector &values_insert_order_p, idx_t dict_size_p)
     : ExtraTypeInfo(ExtraTypeInfoType::ENUM_TYPE_INFO), values_insert_order(values_insert_order_p),
       dict_type(EnumDictType::VECTOR_DICT), dict_size(dict_size_p) {
diff --git a/src/duckdb/src/common/field_writer.cpp b/src/duckdb/src/common/field_writer.cpp
new file mode 100644
index 00000000..af899ca3
--- /dev/null
+++ b/src/duckdb/src/common/field_writer.cpp
@@ -0,0 +1,97 @@
+#include "duckdb/common/field_writer.hpp"
+
+namespace duckdb {
+
+//===--------------------------------------------------------------------===//
+// Field Writer
+//===--------------------------------------------------------------------===//
+FieldWriter::FieldWriter(Serializer &serializer_p)
+    : serializer(serializer_p), buffer(make_uniq()), field_count(0), finalized(false) {
+	buffer->SetVersion(serializer.GetVersion());
+}
+
+FieldWriter::~FieldWriter() {
+	if (Exception::UncaughtException()) {
+		return;
+	}
+	D_ASSERT(finalized);
+	// 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_cast(val.c_str()), val.size());
+	}
+}
+
+void FieldWriter::Finalize() {
+	D_ASSERT(buffer);
+	D_ASSERT(!finalized);
+	finalized = true;
+	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)) {
+	SetVersion(root.GetVersion());
+}
+
+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), finalized(false) {
+	max_field_count = source_p.Read();
+	total_size = source_p.Read();
+	D_ASSERT(max_field_count > 0);
+	D_ASSERT(total_size > 0);
+	source.SetRemainingData(total_size);
+}
+
+FieldReader::~FieldReader() {
+	if (Exception::UncaughtException()) {
+		return;
+	}
+	D_ASSERT(finalized);
+}
+
+void FieldReader::Finalize() {
+	D_ASSERT(!finalized);
+	finalized = true;
+	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
diff --git a/src/duckdb/src/common/render_tree.cpp b/src/duckdb/src/common/render_tree.cpp
index 9c7dca21..6942d6fc 100644
--- a/src/duckdb/src/common/render_tree.cpp
+++ b/src/duckdb/src/common/render_tree.cpp
@@ -118,7 +118,7 @@ static unique_ptr CreateNode(const PipelineRenderNode &op) {
 static unique_ptr CreateNode(const ProfilingNode &op) {
 	auto &info = op.GetProfilingInfo();
 	InsertionOrderPreservingMap extra_info;
-	if (info.Enabled(MetricsType::EXTRA_INFO)) {
+	if (info.Enabled(info.settings, MetricsType::EXTRA_INFO)) {
 		extra_info = op.GetProfilingInfo().extra_info;
 	}
 
@@ -128,11 +128,13 @@ static unique_ptr CreateNode(const ProfilingNode &op) {
 	}
 
 	auto result = make_uniq(node_name, extra_info);
-	if (info.Enabled(MetricsType::OPERATOR_CARDINALITY)) {
-		result->extra_text[RenderTreeNode::CARDINALITY] = info.GetMetricAsString(MetricsType::OPERATOR_CARDINALITY);
+	if (info.Enabled(info.settings, MetricsType::OPERATOR_CARDINALITY)) {
+		auto cardinality = info.GetMetricAsString(MetricsType::OPERATOR_CARDINALITY);
+		result->extra_text[RenderTreeNode::CARDINALITY] = cardinality;
 	}
-	if (info.Enabled(MetricsType::OPERATOR_TIMING)) {
-		string timing = StringUtil::Format("%.2f", info.metrics.at(MetricsType::OPERATOR_TIMING).GetValue());
+	if (info.Enabled(info.settings, MetricsType::OPERATOR_TIMING)) {
+		auto value = info.metrics.at(MetricsType::OPERATOR_TIMING).GetValue();
+		string timing = StringUtil::Format("%.2f", value);
 		result->extra_text[RenderTreeNode::TIMING] = timing + "s";
 	}
 	return result;
diff --git a/src/duckdb/src/common/row_operations/row_match.cpp b/src/duckdb/src/common/row_operations/row_match.cpp
new file mode 100644
index 00000000..b7727e79
--- /dev/null
+++ b/src/duckdb/src/common/row_operations/row_match.cpp
@@ -0,0 +1,359 @@
+//===--------------------------------------------------------------------===//
+// row_match.cpp
+// Description: This file contains the implementation of the match operators
+//===--------------------------------------------------------------------===//
+
+#include "duckdb/common/exception.hpp"
+#include "duckdb/common/operator/comparison_operators.hpp"
+#include "duckdb/common/operator/constant_operators.hpp"
+#include "duckdb/common/row_operations/row_operations.hpp"
+#include "duckdb/common/types/row/tuple_data_collection.hpp"
+
+namespace duckdb {
+
+using ValidityBytes = RowLayout::ValidityBytes;
+using Predicates = RowOperations::Predicates;
+
+template 
+static idx_t SelectComparison(Vector &left, Vector &right, const SelectionVector &sel, idx_t count,
+                              SelectionVector *true_sel, SelectionVector *false_sel) {
+	throw NotImplementedException("Unsupported nested comparison operand for RowOperations::Match");
+}
+
+template <>
+idx_t SelectComparison(Vector &left, Vector &right, const SelectionVector &sel, idx_t count,
+                               SelectionVector *true_sel, SelectionVector *false_sel) {
+	return VectorOperations::NestedEquals(left, right, sel, count, true_sel, false_sel);
+}
+
+template <>
+idx_t SelectComparison(Vector &left, Vector &right, const SelectionVector &sel, idx_t count,
+                                  SelectionVector *true_sel, SelectionVector *false_sel) {
+	return VectorOperations::NestedNotEquals(left, right, sel, count, true_sel, false_sel);
+}
+
+template <>
+idx_t SelectComparison(Vector &left, Vector &right, const SelectionVector &sel, idx_t count,
+                                    SelectionVector *true_sel, SelectionVector *false_sel) {
+	return VectorOperations::DistinctGreaterThan(left, right, &sel, count, true_sel, false_sel);
+}
+
+template <>
+idx_t SelectComparison(Vector &left, Vector &right, const SelectionVector &sel, idx_t count,
+                                          SelectionVector *true_sel, SelectionVector *false_sel) {
+	return VectorOperations::DistinctGreaterThanEquals(left, right, &sel, count, true_sel, false_sel);
+}
+
+template <>
+idx_t SelectComparison(Vector &left, Vector &right, const SelectionVector &sel, idx_t count,
+                                 SelectionVector *true_sel, SelectionVector *false_sel) {
+	return VectorOperations::DistinctLessThan(left, right, &sel, count, true_sel, false_sel);
+}
+
+template <>
+idx_t SelectComparison(Vector &left, Vector &right, const SelectionVector &sel, idx_t count,
+                                       SelectionVector *true_sel, SelectionVector *false_sel) {
+	return VectorOperations::DistinctLessThanEquals(left, right, &sel, count, true_sel, false_sel);
+}
+
+template 
+static void TemplatedMatchType(UnifiedVectorFormat &col, Vector &rows, SelectionVector &sel, idx_t &count,
+                               idx_t col_offset, idx_t col_no, SelectionVector *no_match, idx_t &no_match_count) {
+	// Precompute row_mask indexes
+	idx_t entry_idx;
+	idx_t idx_in_entry;
+	ValidityBytes::GetEntryIndex(col_no, entry_idx, idx_in_entry);
+
+	auto data = UnifiedVectorFormat::GetData(col);
+	auto ptrs = FlatVector::GetData(rows);
+	idx_t match_count = 0;
+	if (!col.validity.AllValid()) {
+		for (idx_t i = 0; i < count; i++) {
+			auto idx = sel.get_index(i);
+
+			auto row = ptrs[idx];
+			ValidityBytes row_mask(row);
+			auto isnull = !row_mask.RowIsValid(row_mask.GetValidityEntry(entry_idx), idx_in_entry);
+
+			auto col_idx = col.sel->get_index(idx);
+			if (!col.validity.RowIsValid(col_idx)) {
+				if (isnull) {
+					// match: move to next value to compare
+					sel.set_index(match_count++, idx);
+				} else {
+					if (NO_MATCH_SEL) {
+						no_match->set_index(no_match_count++, idx);
+					}
+				}
+			} else {
+				auto value = Load(row + col_offset);
+				if (!isnull && OP::template Operation(data[col_idx], value)) {
+					sel.set_index(match_count++, idx);
+				} else {
+					if (NO_MATCH_SEL) {
+						no_match->set_index(no_match_count++, idx);
+					}
+				}
+			}
+		}
+	} else {
+		for (idx_t i = 0; i < count; i++) {
+			auto idx = sel.get_index(i);
+
+			auto row = ptrs[idx];
+			ValidityBytes row_mask(row);
+			auto isnull = !row_mask.RowIsValid(row_mask.GetValidityEntry(entry_idx), idx_in_entry);
+
+			auto col_idx = col.sel->get_index(idx);
+			auto value = Load(row + col_offset);
+			if (!isnull && OP::template Operation(data[col_idx], value)) {
+				sel.set_index(match_count++, idx);
+			} else {
+				if (NO_MATCH_SEL) {
+					no_match->set_index(no_match_count++, idx);
+				}
+			}
+		}
+	}
+	count = match_count;
+}
+
+//! Forward declaration for recursion
+template 
+static void TemplatedMatchOp(Vector &vec, UnifiedVectorFormat &col, const TupleDataLayout &layout, Vector &rows,
+                             SelectionVector &sel, idx_t &count, idx_t col_no, SelectionVector *no_match,
+                             idx_t &no_match_count, const idx_t original_count);
+
+template 
+static void TemplatedMatchStruct(Vector &vec, UnifiedVectorFormat &col, const TupleDataLayout &layout, Vector &rows,
+                                 SelectionVector &sel, idx_t &count, const idx_t col_no, SelectionVector *no_match,
+                                 idx_t &no_match_count, const idx_t original_count) {
+	// Precompute row_mask indexes
+	idx_t entry_idx;
+	idx_t idx_in_entry;
+	ValidityBytes::GetEntryIndex(col_no, entry_idx, idx_in_entry);
+
+	// Work our way through the validity of the whole struct
+	auto ptrs = FlatVector::GetData(rows);
+	idx_t match_count = 0;
+	if (!col.validity.AllValid()) {
+		for (idx_t i = 0; i < count; i++) {
+			auto idx = sel.get_index(i);
+
+			auto row = ptrs[idx];
+			ValidityBytes row_mask(row);
+			auto isnull = !row_mask.RowIsValid(row_mask.GetValidityEntry(entry_idx), idx_in_entry);
+
+			auto col_idx = col.sel->get_index(idx);
+			if (!col.validity.RowIsValid(col_idx)) {
+				if (isnull) {
+					// match: move to next value to compare
+					sel.set_index(match_count++, idx);
+				} else {
+					if (NO_MATCH_SEL) {
+						no_match->set_index(no_match_count++, idx);
+					}
+				}
+			} else {
+				if (!isnull) {
+					sel.set_index(match_count++, idx);
+				} else {
+					if (NO_MATCH_SEL) {
+						no_match->set_index(no_match_count++, idx);
+					}
+				}
+			}
+		}
+	} else {
+		for (idx_t i = 0; i < count; i++) {
+			auto idx = sel.get_index(i);
+
+			auto row = ptrs[idx];
+			ValidityBytes row_mask(row);
+			auto isnull = !row_mask.RowIsValid(row_mask.GetValidityEntry(entry_idx), idx_in_entry);
+
+			if (!isnull) {
+				sel.set_index(match_count++, idx);
+			} else {
+				if (NO_MATCH_SEL) {
+					no_match->set_index(no_match_count++, idx);
+				}
+			}
+		}
+	}
+	count = match_count;
+
+	// Now we construct row pointers to the structs
+	Vector struct_rows(LogicalTypeId::POINTER);
+	auto struct_ptrs = FlatVector::GetData(struct_rows);
+
+	const auto col_offset = layout.GetOffsets()[col_no];
+	for (idx_t i = 0; i < count; i++) {
+		auto idx = sel.get_index(i);
+		auto row = ptrs[idx];
+		struct_ptrs[idx] = row + col_offset;
+	}
+
+	// Get the struct layout, child columns, then recurse
+	const auto &struct_layout = layout.GetStructLayout(col_no);
+	auto &struct_entries = StructVector::GetEntries(vec);
+	D_ASSERT(struct_layout.ColumnCount() == struct_entries.size());
+	for (idx_t struct_col_no = 0; struct_col_no < struct_layout.ColumnCount(); struct_col_no++) {
+		auto &struct_vec = *struct_entries[struct_col_no];
+		UnifiedVectorFormat struct_col;
+		struct_vec.ToUnifiedFormat(original_count, struct_col);
+		TemplatedMatchOp(struct_vec, struct_col, struct_layout, struct_rows, sel, count,
+		                                   struct_col_no, no_match, no_match_count, original_count);
+	}
+}
+
+template 
+static void TemplatedMatchList(Vector &col, Vector &rows, SelectionVector &sel, idx_t &count,
+                               const TupleDataLayout &layout, const idx_t col_no, SelectionVector *no_match,
+                               idx_t &no_match_count) {
+	// Gather a dense Vector containing the column values being matched
+	Vector key(col.GetType());
+	const auto gather_function = TupleDataCollection::GetGatherFunction(col.GetType());
+	gather_function.function(layout, rows, col_no, sel, count, key, *FlatVector::IncrementalSelectionVector(), key,
+	                         gather_function.child_functions);
+
+	// Densify the input column
+	Vector sliced(col, sel, count);
+
+	if (NO_MATCH_SEL) {
+		SelectionVector no_match_sel_offset(no_match->data() + no_match_count);
+		auto match_count = SelectComparison(sliced, key, sel, count, &sel, &no_match_sel_offset);
+		no_match_count += count - match_count;
+		count = match_count;
+	} else {
+		count = SelectComparison(sliced, key, sel, count, &sel, nullptr);
+	}
+}
+
+template 
+static void TemplatedMatchOp(Vector &vec, UnifiedVectorFormat &col, const TupleDataLayout &layout, Vector &rows,
+                             SelectionVector &sel, idx_t &count, idx_t col_no, SelectionVector *no_match,
+                             idx_t &no_match_count, const idx_t original_count) {
+	if (count == 0) {
+		return;
+	}
+	auto col_offset = layout.GetOffsets()[col_no];
+	switch (layout.GetTypes()[col_no].InternalType()) {
+	case PhysicalType::BOOL:
+	case PhysicalType::INT8:
+		TemplatedMatchType(col, rows, sel, count, col_offset, col_no, no_match,
+		                                             no_match_count);
+		break;
+	case PhysicalType::INT16:
+		TemplatedMatchType(col, rows, sel, count, col_offset, col_no, no_match,
+		                                              no_match_count);
+		break;
+	case PhysicalType::INT32:
+		TemplatedMatchType(col, rows, sel, count, col_offset, col_no, no_match,
+		                                              no_match_count);
+		break;
+	case PhysicalType::INT64:
+		TemplatedMatchType(col, rows, sel, count, col_offset, col_no, no_match,
+		                                              no_match_count);
+		break;
+	case PhysicalType::UINT8:
+		TemplatedMatchType(col, rows, sel, count, col_offset, col_no, no_match,
+		                                              no_match_count);
+		break;
+	case PhysicalType::UINT16:
+		TemplatedMatchType(col, rows, sel, count, col_offset, col_no, no_match,
+		                                               no_match_count);
+		break;
+	case PhysicalType::UINT32:
+		TemplatedMatchType(col, rows, sel, count, col_offset, col_no, no_match,
+		                                               no_match_count);
+		break;
+	case PhysicalType::UINT64:
+		TemplatedMatchType(col, rows, sel, count, col_offset, col_no, no_match,
+		                                               no_match_count);
+		break;
+	case PhysicalType::INT128:
+		TemplatedMatchType(col, rows, sel, count, col_offset, col_no, no_match,
+		                                                no_match_count);
+		break;
+	case PhysicalType::FLOAT:
+		TemplatedMatchType(col, rows, sel, count, col_offset, col_no, no_match,
+		                                            no_match_count);
+		break;
+	case PhysicalType::DOUBLE:
+		TemplatedMatchType(col, rows, sel, count, col_offset, col_no, no_match,
+		                                             no_match_count);
+		break;
+	case PhysicalType::INTERVAL:
+		TemplatedMatchType(col, rows, sel, count, col_offset, col_no, no_match,
+		                                                 no_match_count);
+		break;
+	case PhysicalType::VARCHAR:
+		TemplatedMatchType(col, rows, sel, count, col_offset, col_no, no_match,
+		                                               no_match_count);
+		break;
+	case PhysicalType::STRUCT:
+		TemplatedMatchStruct(vec, col, layout, rows, sel, count, col_no, no_match, no_match_count,
+		                                       original_count);
+		break;
+	case PhysicalType::LIST:
+		TemplatedMatchList(vec, rows, sel, count, layout, col_no, no_match, no_match_count);
+		break;
+	default:
+		throw InternalException("Unsupported column type for RowOperations::Match");
+	}
+}
+
+template 
+static void TemplatedMatch(DataChunk &columns, UnifiedVectorFormat col_data[], const TupleDataLayout &layout,
+                           Vector &rows, const Predicates &predicates, SelectionVector &sel, idx_t &count,
+                           SelectionVector *no_match, idx_t &no_match_count) {
+	for (idx_t col_no = 0; col_no < predicates.size(); ++col_no) {
+		auto &vec = columns.data[col_no];
+		auto &col = col_data[col_no];
+		switch (predicates[col_no]) {
+		case ExpressionType::COMPARE_EQUAL:
+		case ExpressionType::COMPARE_NOT_DISTINCT_FROM:
+		case ExpressionType::COMPARE_DISTINCT_FROM:
+			TemplatedMatchOp(vec, col, layout, rows, sel, count, col_no, no_match, no_match_count,
+			                                       count);
+			break;
+		case ExpressionType::COMPARE_NOTEQUAL:
+			TemplatedMatchOp(vec, col, layout, rows, sel, count, col_no, no_match,
+			                                          no_match_count, count);
+			break;
+		case ExpressionType::COMPARE_GREATERTHAN:
+			TemplatedMatchOp(vec, col, layout, rows, sel, count, col_no, no_match,
+			                                            no_match_count, count);
+			break;
+		case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
+			TemplatedMatchOp(vec, col, layout, rows, sel, count, col_no, no_match,
+			                                                  no_match_count, count);
+			break;
+		case ExpressionType::COMPARE_LESSTHAN:
+			TemplatedMatchOp(vec, col, layout, rows, sel, count, col_no, no_match,
+			                                         no_match_count, count);
+			break;
+		case ExpressionType::COMPARE_LESSTHANOREQUALTO:
+			TemplatedMatchOp(vec, col, layout, rows, sel, count, col_no, no_match,
+			                                               no_match_count, count);
+			break;
+		default:
+			throw InternalException("Unsupported comparison type for RowOperations::Match");
+		}
+	}
+}
+
+idx_t RowOperations::Match(DataChunk &columns, UnifiedVectorFormat col_data[], const TupleDataLayout &layout,
+                           Vector &rows, const Predicates &predicates, SelectionVector &sel, idx_t count,
+                           SelectionVector *no_match, idx_t &no_match_count) {
+	if (no_match) {
+		TemplatedMatch(columns, col_data, layout, rows, predicates, sel, count, no_match, no_match_count);
+	} else {
+		TemplatedMatch(columns, col_data, layout, rows, predicates, sel, count, no_match, no_match_count);
+	}
+
+	return count;
+}
+
+} // namespace duckdb
diff --git a/src/duckdb/src/common/serializer.cpp b/src/duckdb/src/common/serializer.cpp
new file mode 100644
index 00000000..2321fb80
--- /dev/null
+++ b/src/duckdb/src/common/serializer.cpp
@@ -0,0 +1,24 @@
+#include "duckdb/common/serializer.hpp"
+
+namespace duckdb {
+
+template <>
+string Deserializer::Read() {
+	uint32_t size = Read();
+	if (size == 0) {
+		return string();
+	}
+	auto buffer = make_unsafe_uniq_array(size);
+	ReadData(buffer.get(), size);
+	return string(const_char_ptr_cast(buffer.get()), size);
+}
+
+void Deserializer::ReadStringVector(vector &list) {
+	uint32_t sz = Read();
+	list.resize(sz);
+	for (idx_t i = 0; i < sz; i++) {
+		list[i] = Read();
+	}
+}
+
+} // namespace duckdb
diff --git a/src/duckdb/src/common/serializer/buffered_deserializer.cpp b/src/duckdb/src/common/serializer/buffered_deserializer.cpp
new file mode 100644
index 00000000..e1636eb8
--- /dev/null
+++ b/src/duckdb/src/common/serializer/buffered_deserializer.cpp
@@ -0,0 +1,27 @@
+#include "duckdb/common/serializer/buffered_deserializer.hpp"
+
+#include 
+
+namespace duckdb {
+
+BufferedDeserializer::BufferedDeserializer(data_ptr_t ptr, idx_t data_size) : ptr(ptr), endptr(ptr + data_size) {
+}
+
+BufferedDeserializer::BufferedDeserializer(BufferedSerializer &serializer)
+    : BufferedDeserializer(serializer.data, serializer.maximum_size) {
+	SetVersion(serializer.GetVersion());
+}
+
+void BufferedDeserializer::ReadData(data_ptr_t buffer, idx_t read_size) {
+	if (ptr + read_size > endptr) {
+		throw SerializationException("Failed to deserialize: not enough data in buffer to fulfill read request");
+	}
+	memcpy(buffer, ptr, read_size);
+	ptr += read_size;
+}
+
+ClientContext &BufferedContextDeserializer::GetContext() {
+	return context;
+}
+
+} // namespace duckdb
diff --git a/src/duckdb/src/common/serializer/buffered_serializer.cpp b/src/duckdb/src/common/serializer/buffered_serializer.cpp
new file mode 100644
index 00000000..af2ec931
--- /dev/null
+++ b/src/duckdb/src/common/serializer/buffered_serializer.cpp
@@ -0,0 +1,36 @@
+#include "duckdb/common/serializer/buffered_serializer.hpp"
+
+#include 
+
+namespace duckdb {
+
+BufferedSerializer::BufferedSerializer(idx_t maximum_size)
+    : BufferedSerializer(make_unsafe_uniq_array(maximum_size), maximum_size) {
+}
+
+BufferedSerializer::BufferedSerializer(unsafe_unique_array data, idx_t size)
+    : maximum_size(size), data(data.get()) {
+	blob.size = 0;
+	blob.data = std::move(data);
+}
+
+BufferedSerializer::BufferedSerializer(data_ptr_t data, idx_t size) : maximum_size(size), data(data) {
+	blob.size = 0;
+}
+
+void BufferedSerializer::WriteData(const_data_ptr_t buffer, idx_t write_size) {
+	if (blob.size + write_size >= maximum_size) {
+		do {
+			maximum_size *= 2;
+		} while (blob.size + write_size > maximum_size);
+		auto new_data = new data_t[maximum_size];
+		memcpy(new_data, data, blob.size);
+		data = new_data;
+		blob.data = unsafe_unique_array(new_data);
+	}
+
+	memcpy(data + blob.size, buffer, write_size);
+	blob.size += write_size;
+}
+
+} // namespace duckdb
diff --git a/src/duckdb/src/common/serializer/format_serializer.cpp b/src/duckdb/src/common/serializer/format_serializer.cpp
new file mode 100644
index 00000000..76415a81
--- /dev/null
+++ b/src/duckdb/src/common/serializer/format_serializer.cpp
@@ -0,0 +1,15 @@
+#include "duckdb/common/serializer/format_serializer.hpp"
+
+namespace duckdb {
+
+template <>
+void FormatSerializer::WriteValue(const vector &vec) {
+	auto count = vec.size();
+	OnListBegin(count);
+	for (auto item : vec) {
+		WriteValue(item);
+	}
+	OnListEnd(count);
+}
+
+} // namespace duckdb
diff --git a/src/duckdb/src/common/sort/comparators.cpp b/src/duckdb/src/common/sort/comparators.cpp
index 82e8069d..560b44cc 100644
--- a/src/duckdb/src/common/sort/comparators.cpp
+++ b/src/duckdb/src/common/sort/comparators.cpp
@@ -24,7 +24,7 @@ bool Comparators::TieIsBreakable(const idx_t &tie_col, const data_ptr_t &row_ptr
 	}
 	const auto &tie_col_offset = row_layout.GetOffsets()[col_idx];
 	auto tie_string = Load(row_ptr + tie_col_offset);
-	if (tie_string.GetSize() < sort_layout.prefix_lengths[tie_col]) {
+	if (tie_string.GetSize() < sort_layout.prefix_lengths[tie_col] && tie_string.GetSize() > 0) {
 		// No need to break the tie - we already compared the full string
 		return false;
 	}
@@ -71,7 +71,7 @@ int Comparators::BreakBlobTie(const idx_t &tie_col, const SBScanState &left, con
                               const SortLayout &sort_layout, const bool &external) {
 	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(tie_col, l_data_ptr, sort_layout)) {
+	if (!TieIsBreakable(tie_col, l_data_ptr, sort_layout) && !TieIsBreakable(tie_col, r_data_ptr, sort_layout)) {
 		// Quick check to see if ties can be broken
 		return 0;
 	}
diff --git a/src/duckdb/src/common/types/bit.cpp b/src/duckdb/src/common/types/bit.cpp
index f263c2c4..5006d64f 100644
--- a/src/duckdb/src/common/types/bit.cpp
+++ b/src/duckdb/src/common/types/bit.cpp
@@ -22,7 +22,7 @@ idx_t Bit::ComputeBitstringLen(idx_t len) {
 	return result;
 }
 
-static inline idx_t GetBitPadding(const string_t &bit_string) {
+static inline idx_t GetBitPadding(const bitstring_t &bit_string) {
 	auto data = const_data_ptr_cast(bit_string.GetData());
 	D_ASSERT(idx_t(data[0]) <= 8);
 	return data[0];
@@ -37,14 +37,14 @@ static inline idx_t GetBitSize(const string_t &str) {
 	return str_len;
 }
 
-uint8_t Bit::GetFirstByte(const string_t &str) {
+uint8_t Bit::GetFirstByte(const bitstring_t &str) {
 	D_ASSERT(str.GetSize() > 1);
 
 	auto data = const_data_ptr_cast(str.GetData());
 	return data[1] & ((1 << (8 - data[0])) - 1);
 }
 
-void Bit::Finalize(string_t &str) {
+void Bit::Finalize(bitstring_t &str) {
 	// bit strings require all padding bits to be set to 1
 	// this method sets all padding bits to 1
 	auto padding = GetBitPadding(str);
@@ -55,7 +55,7 @@ void Bit::Finalize(string_t &str) {
 	Bit::Verify(str);
 }
 
-void Bit::SetEmptyBitString(string_t &target, string_t &input) {
+void Bit::SetEmptyBitString(bitstring_t &target, string_t &input) {
 	char *res_buf = target.GetDataWriteable();
 	const char *buf = input.GetData();
 	memset(res_buf, 0, input.GetSize());
@@ -63,7 +63,7 @@ void Bit::SetEmptyBitString(string_t &target, string_t &input) {
 	Bit::Finalize(target);
 }
 
-void Bit::SetEmptyBitString(string_t &target, idx_t len) {
+void Bit::SetEmptyBitString(bitstring_t &target, idx_t len) {
 	char *res_buf = target.GetDataWriteable();
 	memset(res_buf, 0, target.GetSize());
 	res_buf[0] = ComputePadding(len);
@@ -71,7 +71,7 @@ void Bit::SetEmptyBitString(string_t &target, idx_t len) {
 }
 
 // **** casting functions ****
-void Bit::ToString(string_t bits, char *output) {
+void Bit::ToString(bitstring_t bits, char *output) {
 	auto data = const_data_ptr_cast(bits.GetData());
 	auto len = bits.GetSize();
 
@@ -87,7 +87,7 @@ void Bit::ToString(string_t bits, char *output) {
 	}
 }
 
-string Bit::ToString(string_t str) {
+string Bit::ToString(bitstring_t str) {
 	auto len = BitLength(str);
 	auto buffer = make_unsafe_uniq_array_uninitialized(len);
 	ToString(str, buffer.get());
@@ -117,7 +117,7 @@ bool Bit::TryGetBitStringSize(string_t str, idx_t &str_len, string *error_messag
 	return true;
 }
 
-void Bit::ToBit(string_t str, string_t &output_str) {
+void Bit::ToBit(string_t str, bitstring_t &output_str) {
 	auto data = const_data_ptr_cast(str.GetData());
 	auto len = str.GetSize();
 	auto output = output_str.GetDataWriteable();
@@ -151,12 +151,12 @@ void Bit::ToBit(string_t str, string_t &output_str) {
 string Bit::ToBit(string_t str) {
 	auto bit_len = GetBitSize(str);
 	auto buffer = make_unsafe_uniq_array_uninitialized(bit_len);
-	string_t output_str(buffer.get(), UnsafeNumericCast(bit_len));
+	bitstring_t output_str(buffer.get(), UnsafeNumericCast(bit_len));
 	Bit::ToBit(str, output_str);
 	return output_str.GetString();
 }
 
-void Bit::BlobToBit(string_t blob, string_t &output_str) {
+void Bit::BlobToBit(string_t blob, bitstring_t &output_str) {
 	auto data = const_data_ptr_cast(blob.GetData());
 	auto output = output_str.GetDataWriteable();
 	idx_t size = blob.GetSize();
@@ -167,12 +167,12 @@ void Bit::BlobToBit(string_t blob, string_t &output_str) {
 
 string Bit::BlobToBit(string_t blob) {
 	auto buffer = make_unsafe_uniq_array_uninitialized(blob.GetSize() + 1);
-	string_t output_str(buffer.get(), UnsafeNumericCast(blob.GetSize() + 1));
+	bitstring_t output_str(buffer.get(), UnsafeNumericCast(blob.GetSize() + 1));
 	Bit::BlobToBit(blob, output_str);
 	return output_str.GetString();
 }
 
-void Bit::BitToBlob(string_t bit, string_t &output_blob) {
+void Bit::BitToBlob(bitstring_t bit, string_t &output_blob) {
 	D_ASSERT(bit.GetSize() == output_blob.GetSize() + 1);
 
 	auto data = const_data_ptr_cast(bit.GetData());
@@ -189,7 +189,7 @@ void Bit::BitToBlob(string_t bit, string_t &output_blob) {
 	}
 }
 
-string Bit::BitToBlob(string_t bit) {
+string Bit::BitToBlob(bitstring_t bit) {
 	D_ASSERT(bit.GetSize() > 1);
 
 	auto buffer = make_unsafe_uniq_array_uninitialized(bit.GetSize() - 1);
@@ -199,32 +199,53 @@ string Bit::BitToBlob(string_t bit) {
 }
 
 // **** scalar functions ****
-void Bit::BitString(const string_t &input, const idx_t &bit_length, string_t &result) {
+void Bit::BitString(const string_t &input, idx_t bit_length, bitstring_t &result) {
 	char *res_buf = result.GetDataWriteable();
 	const char *buf = input.GetData();
 
 	auto padding = ComputePadding(bit_length);
 	res_buf[0] = padding;
+	auto padding_len = UnsafeNumericCast(padding);
 	for (idx_t i = 0; i < bit_length; i++) {
 		if (i < bit_length - input.GetSize()) {
-			Bit::SetBit(result, i, 0);
+			Bit::SetBitInternal(result, i + padding_len, 0);
 		} else {
 			idx_t bit = buf[i - (bit_length - input.GetSize())] == '1' ? 1 : 0;
+			Bit::SetBitInternal(result, i + padding_len, bit);
+		}
+	}
+	Bit::Finalize(result);
+}
+
+void Bit::ExtendBitString(const bitstring_t &input, idx_t bit_length, bitstring_t &result) {
+	uint8_t *res_buf = reinterpret_cast(result.GetDataWriteable());
+
+	auto padding = ComputePadding(bit_length);
+	res_buf[0] = static_cast(padding);
+
+	idx_t original_length = Bit::BitLength(input);
+	D_ASSERT(bit_length >= original_length);
+	idx_t shift = bit_length - original_length;
+	for (idx_t i = 0; i < bit_length; i++) {
+		if (i < shift) {
+			Bit::SetBit(result, i, 0);
+		} else {
+			idx_t bit = Bit::GetBit(input, i - shift);
 			Bit::SetBit(result, i, bit);
 		}
 	}
 	Bit::Finalize(result);
 }
 
-idx_t Bit::BitLength(string_t bits) {
+idx_t Bit::BitLength(bitstring_t bits) {
 	return ((bits.GetSize() - 1) * 8) - GetBitPadding(bits);
 }
 
-idx_t Bit::OctetLength(string_t bits) {
+idx_t Bit::OctetLength(bitstring_t bits) {
 	return bits.GetSize() - 1;
 }
 
-idx_t Bit::BitCount(string_t bits) {
+idx_t Bit::BitCount(bitstring_t bits) {
 	idx_t count = 0;
 	const char *buf = bits.GetData();
 	for (idx_t byte_idx = 1; byte_idx < OctetLength(bits) + 1; byte_idx++) {
@@ -235,7 +256,7 @@ idx_t Bit::BitCount(string_t bits) {
 	return count - GetBitPadding(bits);
 }
 
-idx_t Bit::BitPosition(string_t substring, string_t bits) {
+idx_t Bit::BitPosition(bitstring_t substring, bitstring_t bits) {
 	const char *buf = bits.GetData();
 	auto len = bits.GetSize();
 	auto substr_len = BitLength(substring);
@@ -269,7 +290,7 @@ idx_t Bit::BitPosition(string_t substring, string_t bits) {
 	return 0;
 }
 
-idx_t Bit::GetBit(string_t bit_string, idx_t n) {
+idx_t Bit::GetBit(bitstring_t bit_string, idx_t n) {
 	return Bit::GetBitInternal(bit_string, n + GetBitPadding(bit_string));
 }
 
@@ -277,7 +298,7 @@ idx_t Bit::GetBitIndex(idx_t n) {
 	return n / 8 + 1;
 }
 
-idx_t Bit::GetBitInternal(string_t bit_string, idx_t n) {
+idx_t Bit::GetBitInternal(bitstring_t bit_string, idx_t n) {
 	const char *buf = bit_string.GetData();
 	auto idx = Bit::GetBitIndex(n);
 	D_ASSERT(idx < bit_string.GetSize());
@@ -285,12 +306,12 @@ idx_t Bit::GetBitInternal(string_t bit_string, idx_t n) {
 	return (byte & 1 ? 1 : 0);
 }
 
-void Bit::SetBit(string_t &bit_string, idx_t n, idx_t new_value) {
+void Bit::SetBit(bitstring_t &bit_string, idx_t n, idx_t new_value) {
 	SetBitInternal(bit_string, n + GetBitPadding(bit_string), new_value);
 	Bit::Finalize(bit_string);
 }
 
-void Bit::SetBitInternal(string_t &bit_string, idx_t n, idx_t new_value) {
+void Bit::SetBitInternal(bitstring_t &bit_string, idx_t n, idx_t new_value) {
 	uint8_t *buf = reinterpret_cast(bit_string.GetDataWriteable());
 
 	auto idx = Bit::GetBitIndex(n);
@@ -305,39 +326,41 @@ void Bit::SetBitInternal(string_t &bit_string, idx_t n, idx_t new_value) {
 }
 
 // **** BITWISE operators ****
-void Bit::RightShift(const string_t &bit_string, const idx_t &shift, string_t &result) {
+void Bit::RightShift(const bitstring_t &bit_string, idx_t shift, bitstring_t &result) {
 	uint8_t *res_buf = reinterpret_cast(result.GetDataWriteable());
 	const uint8_t *buf = reinterpret_cast(bit_string.GetData());
 
 	res_buf[0] = buf[0];
+	auto padding = GetBitPadding(result);
 	for (idx_t i = 0; i < Bit::BitLength(result); i++) {
 		if (i < shift) {
-			Bit::SetBit(result, i, 0);
+			Bit::SetBitInternal(result, i + padding, 0);
 		} else {
 			idx_t bit = Bit::GetBit(bit_string, i - shift);
-			Bit::SetBit(result, i, bit);
+			Bit::SetBitInternal(result, i + padding, bit);
 		}
 	}
 	Bit::Finalize(result);
 }
 
-void Bit::LeftShift(const string_t &bit_string, const idx_t &shift, string_t &result) {
+void Bit::LeftShift(const bitstring_t &bit_string, idx_t shift, bitstring_t &result) {
 	uint8_t *res_buf = reinterpret_cast(result.GetDataWriteable());
 	const uint8_t *buf = reinterpret_cast(bit_string.GetData());
 
 	res_buf[0] = buf[0];
+	auto padding = GetBitPadding(result);
 	for (idx_t i = 0; i < Bit::BitLength(bit_string); i++) {
 		if (i < (Bit::BitLength(bit_string) - shift)) {
 			idx_t bit = Bit::GetBit(bit_string, shift + i);
-			Bit::SetBit(result, i, bit);
+			Bit::SetBitInternal(result, i + padding, bit);
 		} else {
-			Bit::SetBit(result, i, 0);
+			Bit::SetBitInternal(result, i + padding, 0);
 		}
 	}
 	Bit::Finalize(result);
 }
 
-void Bit::BitwiseAnd(const string_t &rhs, const string_t &lhs, string_t &result) {
+void Bit::BitwiseAnd(const bitstring_t &rhs, const bitstring_t &lhs, bitstring_t &result) {
 	if (Bit::BitLength(lhs) != Bit::BitLength(rhs)) {
 		throw InvalidInputException("Cannot AND bit strings of different sizes");
 	}
@@ -353,7 +376,7 @@ void Bit::BitwiseAnd(const string_t &rhs, const string_t &lhs, string_t &result)
 	Bit::Finalize(result);
 }
 
-void Bit::BitwiseOr(const string_t &rhs, const string_t &lhs, string_t &result) {
+void Bit::BitwiseOr(const bitstring_t &rhs, const bitstring_t &lhs, bitstring_t &result) {
 	if (Bit::BitLength(lhs) != Bit::BitLength(rhs)) {
 		throw InvalidInputException("Cannot OR bit strings of different sizes");
 	}
@@ -369,7 +392,7 @@ void Bit::BitwiseOr(const string_t &rhs, const string_t &lhs, string_t &result)
 	Bit::Finalize(result);
 }
 
-void Bit::BitwiseXor(const string_t &rhs, const string_t &lhs, string_t &result) {
+void Bit::BitwiseXor(const bitstring_t &rhs, const bitstring_t &lhs, bitstring_t &result) {
 	if (Bit::BitLength(lhs) != Bit::BitLength(rhs)) {
 		throw InvalidInputException("Cannot XOR bit strings of different sizes");
 	}
@@ -385,7 +408,7 @@ void Bit::BitwiseXor(const string_t &rhs, const string_t &lhs, string_t &result)
 	Bit::Finalize(result);
 }
 
-void Bit::BitwiseNot(const string_t &input, string_t &result) {
+void Bit::BitwiseNot(const bitstring_t &input, bitstring_t &result) {
 	uint8_t *result_buf = reinterpret_cast(result.GetDataWriteable());
 	const uint8_t *buf = reinterpret_cast(input.GetData());
 
@@ -396,7 +419,7 @@ void Bit::BitwiseNot(const string_t &input, string_t &result) {
 	Bit::Finalize(result);
 }
 
-void Bit::Verify(const string_t &input) {
+void Bit::Verify(const bitstring_t &input) {
 #ifdef DEBUG
 	// bit strings require all padding bits to be set to 1
 	auto padding = GetBitPadding(input);
diff --git a/src/duckdb/src/common/types/data_chunk.cpp b/src/duckdb/src/common/types/data_chunk.cpp
index eea02568..8b00a95f 100644
--- a/src/duckdb/src/common/types/data_chunk.cpp
+++ b/src/duckdb/src/common/types/data_chunk.cpp
@@ -26,50 +26,53 @@ DataChunk::~DataChunk() {
 }
 
 void DataChunk::InitializeEmpty(const vector &types) {
-	InitializeEmpty(types.begin(), types.end());
-}
-
-void DataChunk::Initialize(Allocator &allocator, const vector &types, idx_t capacity_p) {
-	Initialize(allocator, types.begin(), types.end(), capacity_p);
+	D_ASSERT(data.empty());
+	capacity = STANDARD_VECTOR_SIZE;
+	for (idx_t i = 0; i < types.size(); i++) {
+		data.emplace_back(types[i], nullptr);
+	}
 }
 
 void DataChunk::Initialize(ClientContext &context, const vector &types, idx_t capacity_p) {
 	Initialize(Allocator::Get(context), types, capacity_p);
 }
 
-idx_t DataChunk::GetAllocationSize() const {
-	idx_t total_size = 0;
-	auto cardinality = size();
-	for (auto &vec : data) {
-		total_size += vec.GetAllocationSize(cardinality);
-	}
-	return total_size;
+void DataChunk::Initialize(Allocator &allocator, const vector &types, idx_t capacity_p) {
+	auto initialize = vector(types.size(), true);
+	Initialize(allocator, types, initialize, capacity_p);
 }
 
-void DataChunk::Initialize(Allocator &allocator, vector::const_iterator begin,
-                           vector::const_iterator end, idx_t capacity_p) {
-	D_ASSERT(data.empty());                   // can only be initialized once
-	D_ASSERT(std::distance(begin, end) != 0); // empty chunk not allowed
+void DataChunk::Initialize(ClientContext &context, const vector &types, const vector &initialize,
+                           idx_t capacity_p) {
+	Initialize(Allocator::Get(context), types, initialize, capacity_p);
+}
+
+void DataChunk::Initialize(Allocator &allocator, const vector &types, const vector &initialize,
+                           idx_t capacity_p) {
+	D_ASSERT(types.size() == initialize.size());
+	D_ASSERT(data.empty());
+
 	capacity = capacity_p;
-	for (; begin != end; begin++) {
-		VectorCache cache(allocator, *begin, capacity);
+	for (idx_t i = 0; i < types.size(); i++) {
+		if (!initialize[i]) {
+			data.emplace_back(types[i], nullptr);
+			vector_caches.emplace_back();
+			continue;
+		}
+
+		VectorCache cache(allocator, types[i], capacity);
 		data.emplace_back(cache);
 		vector_caches.push_back(std::move(cache));
 	}
 }
 
-void DataChunk::Initialize(ClientContext &context, vector::const_iterator begin,
-                           vector::const_iterator end, idx_t capacity_p) {
-	Initialize(Allocator::Get(context), begin, end, capacity_p);
-}
-
-void DataChunk::InitializeEmpty(vector::const_iterator begin, vector::const_iterator end) {
-	capacity = STANDARD_VECTOR_SIZE;
-	D_ASSERT(data.empty());                   // can only be initialized once
-	D_ASSERT(std::distance(begin, end) != 0); // empty chunk not allowed
-	for (; begin != end; begin++) {
-		data.emplace_back(*begin, nullptr);
+idx_t DataChunk::GetAllocationSize() const {
+	idx_t total_size = 0;
+	auto cardinality = size();
+	for (auto &vec : data) {
+		total_size += vec.GetAllocationSize(cardinality);
 	}
+	return total_size;
 }
 
 void DataChunk::Reset() {
diff --git a/src/duckdb/src/common/types/vector_cache.cpp b/src/duckdb/src/common/types/vector_cache.cpp
index 56664319..49ffe357 100644
--- a/src/duckdb/src/common/types/vector_cache.cpp
+++ b/src/duckdb/src/common/types/vector_cache.cpp
@@ -118,19 +118,25 @@ class VectorCacheBuffer : public VectorBuffer {
 	idx_t capacity;
 };
 
-VectorCache::VectorCache(Allocator &allocator, const LogicalType &type_p, idx_t capacity_p) {
+VectorCache::VectorCache() : buffer(nullptr) {
+}
+
+VectorCache::VectorCache(Allocator &allocator, const LogicalType &type_p, const idx_t capacity_p) {
 	buffer = make_buffer(allocator, type_p, capacity_p);
 }
 
 void VectorCache::ResetFromCache(Vector &result) const {
-	D_ASSERT(buffer);
-	auto &vcache = buffer->Cast();
-	vcache.ResetFromCache(result, buffer);
+	if (!buffer) {
+		return;
+	}
+	auto &vector_cache = buffer->Cast();
+	vector_cache.ResetFromCache(result, buffer);
 }
 
 const LogicalType &VectorCache::GetType() const {
-	auto &vcache = buffer->Cast();
-	return vcache.GetType();
+	D_ASSERT(buffer);
+	auto &vector_cache = buffer->Cast();
+	return vector_cache.GetType();
 }
 
 } // namespace duckdb
diff --git a/src/duckdb/src/common/vector_operations/comparison_operators.cpp b/src/duckdb/src/common/vector_operations/comparison_operators.cpp
index c66288d8..8a56cdfc 100644
--- a/src/duckdb/src/common/vector_operations/comparison_operators.cpp
+++ b/src/duckdb/src/common/vector_operations/comparison_operators.cpp
@@ -167,6 +167,9 @@ static void NestedComparisonExecutor(Vector &left, Vector &right, Vector &result
 		auto &result_validity = ConstantVector::Validity(result);
 		SelectionVector true_sel(1);
 		auto match_count = ComparisonSelector::Select(left, right, nullptr, 1, &true_sel, nullptr, result_validity);
+		// since we are dealing with nested types where the values are not NULL, the result is always valid (i.e true or
+		// false)
+		result_validity.SetAllValid(1);
 		auto result_data = ConstantVector::GetData(result);
 		result_data[0] = match_count > 0;
 		return;
@@ -182,6 +185,10 @@ static void NestedComparisonExecutor(Vector &left, Vector &right, Vector &result
 	if (!leftv.validity.AllValid() || !rightv.validity.AllValid()) {
 		ComparesNotNull(leftv, rightv, result_validity, count);
 	}
+	ValidityMask original_mask;
+	original_mask.SetAllValid(count);
+	original_mask.Copy(result_validity, count);
+
 	SelectionVector true_sel(count);
 	SelectionVector false_sel(count);
 	idx_t match_count =
@@ -190,12 +197,19 @@ static void NestedComparisonExecutor(Vector &left, Vector &right, Vector &result
 	for (idx_t i = 0; i < match_count; ++i) {
 		const auto idx = true_sel.get_index(i);
 		result_data[idx] = true;
+		// if the row was valid during the null check, set it to valid here as well
+		if (original_mask.RowIsValid(idx)) {
+			result_validity.SetValid(idx);
+		}
 	}
 
 	const idx_t no_match_count = count - match_count;
 	for (idx_t i = 0; i < no_match_count; ++i) {
 		const auto idx = false_sel.get_index(i);
 		result_data[idx] = false;
+		if (original_mask.RowIsValid(idx)) {
+			result_validity.SetValid(idx);
+		}
 	}
 }
 
diff --git a/src/duckdb/src/core_functions/aggregate/distributive/bitstring_agg.cpp b/src/duckdb/src/core_functions/aggregate/distributive/bitstring_agg.cpp
index 36920a47..f01cc50a 100644
--- a/src/duckdb/src/core_functions/aggregate/distributive/bitstring_agg.cpp
+++ b/src/duckdb/src/core_functions/aggregate/distributive/bitstring_agg.cpp
@@ -8,6 +8,8 @@
 #include "duckdb/execution/expression_executor.hpp"
 #include "duckdb/common/types/cast_helpers.hpp"
 #include "duckdb/common/operator/subtract.hpp"
+#include "duckdb/common/serializer/deserializer.hpp"
+#include "duckdb/common/serializer/serializer.hpp"
 
 namespace duckdb {
 
@@ -43,6 +45,21 @@ struct BitstringAggBindData : public FunctionData {
 		}
 		return false;
 	}
+
+	static void Serialize(Serializer &serializer, const optional_ptr bind_data_p,
+	                      const AggregateFunction &) {
+		auto &bind_data = bind_data_p->Cast();
+		serializer.WriteProperty(100, "min", bind_data.min);
+		serializer.WriteProperty(101, "max", bind_data.max);
+	}
+
+	static unique_ptr Deserialize(Deserializer &deserializer, AggregateFunction &) {
+		Value min;
+		Value max;
+		deserializer.ReadProperty(100, "min", min);
+		deserializer.ReadProperty(101, "max", max);
+		return make_uniq(min, max);
+	}
 };
 
 struct BitStringAggOperation {
@@ -247,7 +264,9 @@ static void BindBitString(AggregateFunctionSet &bitstring_agg, const LogicalType
 	auto function =
 	    AggregateFunction::UnaryAggregateDestructor, TYPE, string_t, BitStringAggOperation>(
 	        type, LogicalType::BIT);
-	function.bind = BindBitstringAgg;              // create new a 'BitstringAggBindData'
+	function.bind = BindBitstringAgg; // create new a 'BitstringAggBindData'
+	function.serialize = BitstringAggBindData::Serialize;
+	function.deserialize = BitstringAggBindData::Deserialize;
 	function.statistics = BitstringPropagateStats; // stores min and max from column stats in BitstringAggBindData
 	bitstring_agg.AddFunction(function); // uses the BitstringAggBindData to access statistics for creating bitstring
 	function.arguments = {type, type, type};
diff --git a/src/duckdb/src/core_functions/aggregate/distributive/minmax.cpp b/src/duckdb/src/core_functions/aggregate/distributive/minmax.cpp
index dba09e5a..9642da15 100644
--- a/src/duckdb/src/core_functions/aggregate/distributive/minmax.cpp
+++ b/src/duckdb/src/core_functions/aggregate/distributive/minmax.cpp
@@ -315,8 +315,8 @@ static AggregateFunction GetMinMaxOperator(const LogicalType &type) {
 	auto internal_type = type.InternalType();
 	switch (internal_type) {
 	case PhysicalType::VARCHAR:
-		return AggregateFunction::UnaryAggregateDestructor(type.id(),
-		                                                                                                     type.id());
+		return AggregateFunction::UnaryAggregateDestructor(type,
+		                                                                                                     type);
 	case PhysicalType::LIST:
 	case PhysicalType::STRUCT:
 	case PhysicalType::ARRAY:
diff --git a/src/duckdb/src/core_functions/aggregate/holistic/approx_top_k.cpp b/src/duckdb/src/core_functions/aggregate/holistic/approx_top_k.cpp
index 19b3ae88..b1cf41e0 100644
--- a/src/duckdb/src/core_functions/aggregate/holistic/approx_top_k.cpp
+++ b/src/duckdb/src/core_functions/aggregate/holistic/approx_top_k.cpp
@@ -48,7 +48,7 @@ struct ApproxTopKValue {
 	uint32_t capacity = 0;
 };
 
-struct ApproxTopKState {
+struct InternalApproxTopKState {
 	// the top-k data structure has two components
 	// a list of k values sorted on "count" (i.e. values[0] has the lowest count)
 	// a lookup map: string_t -> idx in "values" array
@@ -169,15 +169,34 @@ struct ApproxTopKState {
 	}
 };
 
+struct ApproxTopKState {
+	InternalApproxTopKState *state;
+
+	InternalApproxTopKState &GetState() {
+		if (!state) {
+			state = new InternalApproxTopKState();
+		}
+		return *state;
+	}
+
+	const InternalApproxTopKState &GetState() const {
+		if (!state) {
+			throw InternalException("No state available");
+		}
+		return *state;
+	}
+};
+
 struct ApproxTopKOperation {
 	template 
 	static void Initialize(STATE &state) {
-		new (&state) STATE();
+		state.state = nullptr;
 	}
 
 	template 
-	static void Operation(STATE &state, const TYPE &input, AggregateInputData &aggr_input, Vector &top_k_vector,
+	static void Operation(STATE &aggr_state, const TYPE &input, AggregateInputData &aggr_input, Vector &top_k_vector,
 	                      idx_t offset, idx_t count) {
+		auto &state = aggr_state.GetState();
 		if (state.values.empty()) {
 			static constexpr int64_t MAX_APPROX_K = 1000000;
 			// not initialized yet - initialize the K value and set all counters to 0
@@ -208,7 +227,13 @@ struct ApproxTopKOperation {
 	}
 
 	template 
-	static void Combine(const STATE &source, STATE &target, AggregateInputData &aggr_input) {
+	static void Combine(const STATE &aggr_source, STATE &aggr_target, AggregateInputData &aggr_input) {
+		if (!aggr_source.state) {
+			// source state is empty
+			return;
+		}
+		auto &source = aggr_source.GetState();
+		auto &target = aggr_target.GetState();
 		if (source.values.empty()) {
 			// source is empty
 			return;
@@ -279,7 +304,7 @@ struct ApproxTopKOperation {
 
 	template 
 	static void Destroy(STATE &state, AggregateInputData &aggr_input_data) {
-		state.~STATE();
+		delete state.state;
 	}
 
 	static bool IgnoreNull() {
@@ -324,7 +349,7 @@ static void ApproxTopKFinalize(Vector &state_vector, AggregateInputData &, Vecto
 	idx_t new_entries = 0;
 	// figure out how much space we need
 	for (idx_t i = 0; i < count; i++) {
-		auto &state = *states[sdata.sel->get_index(i)];
+		auto &state = states[sdata.sel->get_index(i)]->GetState();
 		if (state.values.empty()) {
 			continue;
 		}
@@ -340,7 +365,7 @@ static void ApproxTopKFinalize(Vector &state_vector, AggregateInputData &, Vecto
 	idx_t current_offset = old_len;
 	for (idx_t i = 0; i < count; i++) {
 		const auto rid = i + offset;
-		auto &state = *states[sdata.sel->get_index(i)];
+		auto &state = states[sdata.sel->get_index(i)]->GetState();
 		if (state.values.empty()) {
 			mask.SetInvalid(rid);
 			continue;
diff --git a/src/duckdb/src/core_functions/function_list.cpp b/src/duckdb/src/core_functions/function_list.cpp
index c01d3e85..ca77e030 100644
--- a/src/duckdb/src/core_functions/function_list.cpp
+++ b/src/duckdb/src/core_functions/function_list.cpp
@@ -52,7 +52,6 @@ static const StaticFunctionDefinition internal_functions[] = {
 	DUCKDB_SCALAR_FUNCTION_SET(BitwiseAndFun),
 	DUCKDB_SCALAR_FUNCTION_ALIAS(ListHasAnyFunAlias),
 	DUCKDB_SCALAR_FUNCTION(PowOperatorFun),
-	DUCKDB_SCALAR_FUNCTION_SET_ALIAS(ListNegativeInnerProductFunAlias),
 	DUCKDB_SCALAR_FUNCTION_SET_ALIAS(ListDistanceFunAlias),
 	DUCKDB_SCALAR_FUNCTION_SET(LeftShiftFun),
 	DUCKDB_SCALAR_FUNCTION_SET_ALIAS(ListCosineDistanceFunAlias),
@@ -117,7 +116,7 @@ static const StaticFunctionDefinition internal_functions[] = {
 	DUCKDB_AGGREGATE_FUNCTION_SET(BitOrFun),
 	DUCKDB_SCALAR_FUNCTION(BitPositionFun),
 	DUCKDB_AGGREGATE_FUNCTION_SET(BitXorFun),
-	DUCKDB_SCALAR_FUNCTION(BitStringFun),
+	DUCKDB_SCALAR_FUNCTION_SET(BitStringFun),
 	DUCKDB_AGGREGATE_FUNCTION_SET(BitstringAggFun),
 	DUCKDB_AGGREGATE_FUNCTION(BoolAndFun),
 	DUCKDB_AGGREGATE_FUNCTION(BoolOrFun),
diff --git a/src/duckdb/src/core_functions/scalar/bit/bitstring.cpp b/src/duckdb/src/core_functions/scalar/bit/bitstring.cpp
index fc176885..9a9a5eae 100644
--- a/src/duckdb/src/core_functions/scalar/bit/bitstring.cpp
+++ b/src/duckdb/src/core_functions/scalar/bit/bitstring.cpp
@@ -7,28 +7,46 @@ namespace duckdb {
 //===--------------------------------------------------------------------===//
 // BitStringFunction
 //===--------------------------------------------------------------------===//
+template 
 static void BitStringFunction(DataChunk &args, ExpressionState &state, Vector &result) {
 	BinaryExecutor::Execute(
 	    args.data[0], args.data[1], result, args.size(), [&](string_t input, int32_t n) {
 		    if (n < 0) {
 			    throw InvalidInputException("The bitstring length cannot be negative");
 		    }
-		    if (idx_t(n) < input.GetSize()) {
+		    idx_t input_length;
+		    if (FROM_STRING) {
+			    input_length = input.GetSize();
+		    } else {
+			    input_length = Bit::BitLength(input);
+		    }
+		    if (idx_t(n) < input_length) {
 			    throw InvalidInputException("Length must be equal or larger than input string");
 		    }
 		    idx_t len;
-		    Bit::TryGetBitStringSize(input, len, nullptr); // string verification
+		    if (FROM_STRING) {
+			    Bit::TryGetBitStringSize(input, len, nullptr); // string verification
+		    }
 
 		    len = Bit::ComputeBitstringLen(UnsafeNumericCast(n));
 		    string_t target = StringVector::EmptyString(result, len);
-		    Bit::BitString(input, UnsafeNumericCast(n), target);
+		    if (FROM_STRING) {
+			    Bit::BitString(input, UnsafeNumericCast(n), target);
+		    } else {
+			    Bit::ExtendBitString(input, UnsafeNumericCast(n), target);
+		    }
 		    target.Finalize();
 		    return target;
 	    });
 }
 
-ScalarFunction BitStringFun::GetFunction() {
-	return ScalarFunction({LogicalType::VARCHAR, LogicalType::INTEGER}, LogicalType::BIT, BitStringFunction);
+ScalarFunctionSet BitStringFun::GetFunctions() {
+	ScalarFunctionSet bitstring;
+	bitstring.AddFunction(
+	    ScalarFunction({LogicalType::VARCHAR, LogicalType::INTEGER}, LogicalType::BIT, BitStringFunction));
+	bitstring.AddFunction(
+	    ScalarFunction({LogicalType::BIT, LogicalType::INTEGER}, LogicalType::BIT, BitStringFunction));
+	return bitstring;
 }
 
 //===--------------------------------------------------------------------===//
diff --git a/src/duckdb/src/core_functions/scalar/date/date_diff.cpp b/src/duckdb/src/core_functions/scalar/date/date_diff.cpp
index 6266dda3..36376a2b 100644
--- a/src/duckdb/src/core_functions/scalar/date/date_diff.cpp
+++ b/src/duckdb/src/core_functions/scalar/date/date_diff.cpp
@@ -28,6 +28,14 @@ struct DateDiff {
 		    });
 	}
 
+	//	We need to truncate down, not towards 0
+	static inline int64_t Truncate(int64_t value, int64_t units) {
+		return (value + (value < 0)) / units - (value < 0);
+	}
+	static inline int64_t Diff(int64_t start, int64_t end, int64_t units) {
+		return Truncate(end, units) - Truncate(start, units);
+	}
+
 	struct YearOperator {
 		template 
 		static inline TR Operation(TA startdate, TB enddate) {
@@ -204,30 +212,28 @@ template <>
 int64_t DateDiff::MillisecondsOperator::Operation(timestamp_t startdate, timestamp_t enddate) {
 	D_ASSERT(Timestamp::IsFinite(startdate));
 	D_ASSERT(Timestamp::IsFinite(enddate));
-	return Timestamp::GetEpochMs(enddate) - Timestamp::GetEpochMs(startdate);
+	return Diff(startdate.value, enddate.value, Interval::MICROS_PER_MSEC);
 }
 
 template <>
 int64_t DateDiff::SecondsOperator::Operation(timestamp_t startdate, timestamp_t enddate) {
 	D_ASSERT(Timestamp::IsFinite(startdate));
 	D_ASSERT(Timestamp::IsFinite(enddate));
-	return Timestamp::GetEpochSeconds(enddate) - Timestamp::GetEpochSeconds(startdate);
+	return Diff(startdate.value, enddate.value, Interval::MICROS_PER_SEC);
 }
 
 template <>
 int64_t DateDiff::MinutesOperator::Operation(timestamp_t startdate, timestamp_t enddate) {
 	D_ASSERT(Timestamp::IsFinite(startdate));
 	D_ASSERT(Timestamp::IsFinite(enddate));
-	return Timestamp::GetEpochSeconds(enddate) / Interval::SECS_PER_MINUTE -
-	       Timestamp::GetEpochSeconds(startdate) / Interval::SECS_PER_MINUTE;
+	return Diff(startdate.value, enddate.value, Interval::MICROS_PER_MINUTE);
 }
 
 template <>
 int64_t DateDiff::HoursOperator::Operation(timestamp_t startdate, timestamp_t enddate) {
 	D_ASSERT(Timestamp::IsFinite(startdate));
 	D_ASSERT(Timestamp::IsFinite(enddate));
-	return Timestamp::GetEpochSeconds(enddate) / Interval::SECS_PER_HOUR -
-	       Timestamp::GetEpochSeconds(startdate) / Interval::SECS_PER_HOUR;
+	return Diff(startdate.value, enddate.value, Interval::MICROS_PER_HOUR);
 }
 
 // TIME specialisations
diff --git a/src/duckdb/src/core_functions/scalar/date/date_part.cpp b/src/duckdb/src/core_functions/scalar/date/date_part.cpp
index c234e1e3..ebe65f78 100644
--- a/src/duckdb/src/core_functions/scalar/date/date_part.cpp
+++ b/src/duckdb/src/core_functions/scalar/date/date_part.cpp
@@ -412,7 +412,7 @@ struct DatePart {
 			D_ASSERT(input.ColumnCount() == 1);
 
 			UnaryExecutor::Execute(input.data[0], result, input.size(), [&](int64_t input) {
-				// milisecond amounts provided to epoch_ms should never be considered infinite
+				// millisecond amounts provided to epoch_ms should never be considered infinite
 				// instead such values will just throw when converted to microseconds
 				return Timestamp::FromEpochMsPossiblyInfinite(input);
 			});
diff --git a/src/duckdb/src/execution/expression_executor.cpp b/src/duckdb/src/execution/expression_executor.cpp
index 716672d8..458348be 100644
--- a/src/duckdb/src/execution/expression_executor.cpp
+++ b/src/duckdb/src/execution/expression_executor.cpp
@@ -170,10 +170,16 @@ unique_ptr ExpressionExecutor::InitializeState(const Expression
 void ExpressionExecutor::Execute(const Expression &expr, ExpressionState *state, const SelectionVector *sel,
                                  idx_t count, Vector &result) {
 #ifdef DEBUG
-	// the result vector has to be used for the first time or has to be reset
-	// otherwise, the validity mask might contain previous (now incorrect) data
+	// The result vector must be used for the first time, or must be reset.
+	// Otherwise, the validity mask can contain previous (now incorrect) data.
 	if (result.GetVectorType() == VectorType::FLAT_VECTOR) {
-		D_ASSERT(FlatVector::Validity(result).CheckAllValid(count));
+
+		// We do not initialize vector caches for these expressions.
+		if (expr.GetExpressionClass() != ExpressionClass::BOUND_REF &&
+		    expr.GetExpressionClass() != ExpressionClass::BOUND_CONSTANT &&
+		    expr.GetExpressionClass() != ExpressionClass::BOUND_PARAMETER) {
+			D_ASSERT(FlatVector::Validity(result).CheckAllValid(count));
+		}
 	}
 #endif
 
diff --git a/src/duckdb/src/execution/expression_executor/execute_between.cpp b/src/duckdb/src/execution/expression_executor/execute_between.cpp
index ca7d45f7..95ff4507 100644
--- a/src/duckdb/src/execution/expression_executor/execute_between.cpp
+++ b/src/duckdb/src/execution/expression_executor/execute_between.cpp
@@ -89,9 +89,10 @@ static idx_t BetweenLoopTypeSwitch(Vector &input, Vector &lower, Vector &upper,
 unique_ptr ExpressionExecutor::InitializeState(const BoundBetweenExpression &expr,
                                                                 ExpressionExecutorState &root) {
 	auto result = make_uniq(expr, root);
-	result->AddChild(expr.input.get());
-	result->AddChild(expr.lower.get());
-	result->AddChild(expr.upper.get());
+	result->AddChild(*expr.input);
+	result->AddChild(*expr.lower);
+	result->AddChild(*expr.upper);
+
 	result->Finalize();
 	return result;
 }
diff --git a/src/duckdb/src/execution/expression_executor/execute_case.cpp b/src/duckdb/src/execution/expression_executor/execute_case.cpp
index 37d50af5..cdeae311 100644
--- a/src/duckdb/src/execution/expression_executor/execute_case.cpp
+++ b/src/duckdb/src/execution/expression_executor/execute_case.cpp
@@ -18,10 +18,11 @@ unique_ptr ExpressionExecutor::InitializeState(const BoundCaseE
                                                                 ExpressionExecutorState &root) {
 	auto result = make_uniq(expr, root);
 	for (auto &case_check : expr.case_checks) {
-		result->AddChild(case_check.when_expr.get());
-		result->AddChild(case_check.then_expr.get());
+		result->AddChild(*case_check.when_expr);
+		result->AddChild(*case_check.then_expr);
 	}
-	result->AddChild(expr.else_expr.get());
+	result->AddChild(*expr.else_expr);
+
 	result->Finalize();
 	return std::move(result);
 }
diff --git a/src/duckdb/src/execution/expression_executor/execute_cast.cpp b/src/duckdb/src/execution/expression_executor/execute_cast.cpp
index 688ffbb9..c0cca588 100644
--- a/src/duckdb/src/execution/expression_executor/execute_cast.cpp
+++ b/src/duckdb/src/execution/expression_executor/execute_cast.cpp
@@ -8,8 +8,9 @@ namespace duckdb {
 unique_ptr ExpressionExecutor::InitializeState(const BoundCastExpression &expr,
                                                                 ExpressionExecutorState &root) {
 	auto result = make_uniq(expr, root);
-	result->AddChild(expr.child.get());
+	result->AddChild(*expr.child);
 	result->Finalize();
+
 	if (expr.bound_cast.init_local_state) {
 		CastLocalStateParameters parameters(root.executor->GetContext(), expr.bound_cast.cast_data);
 		result->local_state = expr.bound_cast.init_local_state(parameters);
diff --git a/src/duckdb/src/execution/expression_executor/execute_comparison.cpp b/src/duckdb/src/execution/expression_executor/execute_comparison.cpp
index 58a4e480..949bc7ab 100644
--- a/src/duckdb/src/execution/expression_executor/execute_comparison.cpp
+++ b/src/duckdb/src/execution/expression_executor/execute_comparison.cpp
@@ -12,8 +12,9 @@ namespace duckdb {
 unique_ptr ExpressionExecutor::InitializeState(const BoundComparisonExpression &expr,
                                                                 ExpressionExecutorState &root) {
 	auto result = make_uniq(expr, root);
-	result->AddChild(expr.left.get());
-	result->AddChild(expr.right.get());
+	result->AddChild(*expr.left);
+	result->AddChild(*expr.right);
+
 	result->Finalize();
 	return result;
 }
diff --git a/src/duckdb/src/execution/expression_executor/execute_conjunction.cpp b/src/duckdb/src/execution/expression_executor/execute_conjunction.cpp
index 37161cfd..8ea55d63 100644
--- a/src/duckdb/src/execution/expression_executor/execute_conjunction.cpp
+++ b/src/duckdb/src/execution/expression_executor/execute_conjunction.cpp
@@ -18,8 +18,9 @@ unique_ptr ExpressionExecutor::InitializeState(const BoundConju
                                                                 ExpressionExecutorState &root) {
 	auto result = make_uniq(expr, root);
 	for (auto &child : expr.children) {
-		result->AddChild(child.get());
+		result->AddChild(*child);
 	}
+
 	result->Finalize();
 	return std::move(result);
 }
diff --git a/src/duckdb/src/execution/expression_executor/execute_function.cpp b/src/duckdb/src/execution/expression_executor/execute_function.cpp
index 0a7d3261..7fe9df2f 100644
--- a/src/duckdb/src/execution/expression_executor/execute_function.cpp
+++ b/src/duckdb/src/execution/expression_executor/execute_function.cpp
@@ -14,8 +14,9 @@ unique_ptr ExpressionExecutor::InitializeState(const BoundFunct
                                                                 ExpressionExecutorState &root) {
 	auto result = make_uniq(expr, root);
 	for (auto &child : expr.children) {
-		result->AddChild(child.get());
+		result->AddChild(*child);
 	}
+
 	result->Finalize();
 	if (expr.function.init_local_state) {
 		result->local_state = expr.function.init_local_state(*result, expr, expr.bind_info.get());
diff --git a/src/duckdb/src/execution/expression_executor/execute_operator.cpp b/src/duckdb/src/execution/expression_executor/execute_operator.cpp
index f357ff9c..7db87478 100644
--- a/src/duckdb/src/execution/expression_executor/execute_operator.cpp
+++ b/src/duckdb/src/execution/expression_executor/execute_operator.cpp
@@ -8,8 +8,9 @@ unique_ptr ExpressionExecutor::InitializeState(const BoundOpera
                                                                 ExpressionExecutorState &root) {
 	auto result = make_uniq(expr, root);
 	for (auto &child : expr.children) {
-		result->AddChild(child.get());
+		result->AddChild(*child);
 	}
+
 	result->Finalize();
 	return result;
 }
@@ -33,7 +34,7 @@ void ExpressionExecutor::Execute(const BoundOperatorExpression &expr, Expression
 		intermediate.Reference(false_val);
 
 		// in rhs is a list of constants
-		// for every child, OR the result of the comparision with the left
+		// for every child, OR the result of the comparison with the left
 		// to get the overall result.
 		for (idx_t child = 1; child < expr.children.size(); child++) {
 			Vector vector_to_check(expr.children[child]->return_type);
diff --git a/src/duckdb/src/execution/expression_executor/execute_reference.cpp b/src/duckdb/src/execution/expression_executor/execute_reference.cpp
index 4dac1539..88fdfa63 100644
--- a/src/duckdb/src/execution/expression_executor/execute_reference.cpp
+++ b/src/duckdb/src/execution/expression_executor/execute_reference.cpp
@@ -6,7 +6,7 @@ namespace duckdb {
 unique_ptr ExpressionExecutor::InitializeState(const BoundReferenceExpression &expr,
                                                                 ExpressionExecutorState &root) {
 	auto result = make_uniq(expr, root);
-	result->Finalize(true);
+	result->Finalize();
 	return result;
 }
 
diff --git a/src/duckdb/src/execution/expression_executor_state.cpp b/src/duckdb/src/execution/expression_executor_state.cpp
index 44161f94..070a399d 100644
--- a/src/duckdb/src/execution/expression_executor_state.cpp
+++ b/src/duckdb/src/execution/expression_executor_state.cpp
@@ -6,20 +6,22 @@
 
 namespace duckdb {
 
-void ExpressionState::AddChild(Expression *expr) {
-	types.push_back(expr->return_type);
-	child_states.push_back(ExpressionExecutor::InitializeState(*expr, root));
+void ExpressionState::AddChild(Expression &child_expr) {
+	types.push_back(child_expr.return_type);
+	auto child_state = ExpressionExecutor::InitializeState(child_expr, root);
+	child_states.push_back(std::move(child_state));
+
+	auto expr_class = child_expr.GetExpressionClass();
+	auto initialize_child = expr_class != ExpressionClass::BOUND_REF && expr_class != ExpressionClass::BOUND_CONSTANT &&
+	                        expr_class != ExpressionClass::BOUND_PARAMETER;
+	initialize.push_back(initialize_child);
 }
 
-void ExpressionState::Finalize(bool empty) {
+void ExpressionState::Finalize() {
 	if (types.empty()) {
 		return;
 	}
-	if (empty) {
-		intermediate_chunk.InitializeEmpty(types);
-	} else {
-		intermediate_chunk.Initialize(GetAllocator(), types);
-	}
+	intermediate_chunk.Initialize(GetAllocator(), types, initialize);
 }
 
 Allocator &ExpressionState::GetAllocator() {
diff --git a/src/duckdb/src/execution/index/art/fixed_size_allocator.cpp b/src/duckdb/src/execution/index/art/fixed_size_allocator.cpp
new file mode 100644
index 00000000..ac1526e2
--- /dev/null
+++ b/src/duckdb/src/execution/index/art/fixed_size_allocator.cpp
@@ -0,0 +1,238 @@
+#include "duckdb/execution/index/art/fixed_size_allocator.hpp"
+
+namespace duckdb {
+
+constexpr idx_t FixedSizeAllocator::BASE[];
+constexpr uint8_t FixedSizeAllocator::SHIFT[];
+
+FixedSizeAllocator::FixedSizeAllocator(const idx_t allocation_size, Allocator &allocator)
+    : allocation_size(allocation_size), total_allocations(0), allocator(allocator) {
+
+	// calculate how many allocations fit into one buffer
+
+	idx_t bits_per_value = sizeof(validity_t) * 8;
+	idx_t curr_alloc_size = 0;
+
+	bitmask_count = 0;
+	allocations_per_buffer = 0;
+
+	while (curr_alloc_size < BUFFER_ALLOC_SIZE) {
+		if (!bitmask_count || (bitmask_count * bits_per_value) % allocations_per_buffer == 0) {
+			bitmask_count++;
+			curr_alloc_size += sizeof(validity_t);
+		}
+
+		auto remaining_alloc_size = BUFFER_ALLOC_SIZE - curr_alloc_size;
+		auto remaining_allocations = MinValue(remaining_alloc_size / allocation_size, bits_per_value);
+
+		if (remaining_allocations == 0) {
+			break;
+		}
+
+		allocations_per_buffer += remaining_allocations;
+		curr_alloc_size += remaining_allocations * allocation_size;
+	}
+
+	allocation_offset = bitmask_count * sizeof(validity_t);
+}
+
+FixedSizeAllocator::~FixedSizeAllocator() {
+	for (auto &buffer : buffers) {
+		allocator.FreeData(buffer.ptr, BUFFER_ALLOC_SIZE);
+	}
+}
+
+Node FixedSizeAllocator::New() {
+
+	// no more free pointers
+	if (buffers_with_free_space.empty()) {
+
+		// add a new buffer
+		idx_t buffer_id = buffers.size();
+		D_ASSERT(buffer_id <= (uint32_t)DConstants::INVALID_INDEX);
+		auto buffer = allocator.AllocateData(BUFFER_ALLOC_SIZE);
+		buffers.emplace_back(buffer, 0);
+		buffers_with_free_space.insert(buffer_id);
+
+		// set the bitmask
+		ValidityMask mask(reinterpret_cast(buffer));
+		mask.SetAllValid(allocations_per_buffer);
+	}
+
+	// return a pointer
+	D_ASSERT(!buffers_with_free_space.empty());
+	auto buffer_id = (uint32_t)*buffers_with_free_space.begin();
+
+	auto bitmask_ptr = reinterpret_cast(buffers[buffer_id].ptr);
+	ValidityMask mask(bitmask_ptr);
+	auto offset = GetOffset(mask, buffers[buffer_id].allocation_count);
+
+	buffers[buffer_id].allocation_count++;
+	total_allocations++;
+	if (buffers[buffer_id].allocation_count == allocations_per_buffer) {
+		buffers_with_free_space.erase(buffer_id);
+	}
+
+	return Node(buffer_id, offset);
+}
+
+void FixedSizeAllocator::Free(const Node ptr) {
+	auto bitmask_ptr = reinterpret_cast(buffers[ptr.GetBufferId()].ptr);
+	ValidityMask mask(bitmask_ptr);
+	D_ASSERT(!mask.RowIsValid(ptr.GetOffset()));
+	mask.SetValid(ptr.GetOffset());
+	buffers_with_free_space.insert(ptr.GetBufferId());
+
+	D_ASSERT(total_allocations > 0);
+	D_ASSERT(buffers[ptr.GetBufferId()].allocation_count > 0);
+	buffers[ptr.GetBufferId()].allocation_count--;
+	total_allocations--;
+}
+
+void FixedSizeAllocator::Reset() {
+
+	for (auto &buffer : buffers) {
+		allocator.FreeData(buffer.ptr, BUFFER_ALLOC_SIZE);
+	}
+	buffers.clear();
+	buffers_with_free_space.clear();
+	total_allocations = 0;
+}
+
+void FixedSizeAllocator::Merge(FixedSizeAllocator &other) {
+
+	D_ASSERT(allocation_size == other.allocation_size);
+
+	// remember the buffer count and merge the buffers
+	idx_t buffer_count = buffers.size();
+	for (auto &buffer : other.buffers) {
+		buffers.push_back(buffer);
+	}
+	other.buffers.clear();
+
+	// merge the buffers with free spaces
+	for (auto &buffer_id : other.buffers_with_free_space) {
+		buffers_with_free_space.insert(buffer_id + buffer_count);
+	}
+	other.buffers_with_free_space.clear();
+
+	// add the total allocations
+	total_allocations += other.total_allocations;
+}
+
+bool FixedSizeAllocator::InitializeVacuum() {
+
+	if (total_allocations == 0) {
+		Reset();
+		return false;
+	}
+
+	auto total_available_allocations = allocations_per_buffer * buffers.size();
+	D_ASSERT(total_available_allocations >= total_allocations);
+	auto total_free_positions = total_available_allocations - total_allocations;
+
+	// vacuum_count buffers can be freed
+	auto vacuum_count = total_free_positions / allocations_per_buffer;
+
+	// calculate the vacuum threshold adaptively
+	D_ASSERT(vacuum_count < buffers.size());
+	idx_t memory_usage = GetMemoryUsage();
+	idx_t excess_memory_usage = vacuum_count * BUFFER_ALLOC_SIZE;
+	auto excess_percentage = (double)excess_memory_usage / (double)memory_usage;
+	auto threshold = (double)VACUUM_THRESHOLD / 100.0;
+	if (excess_percentage < threshold) {
+		return false;
+	}
+
+	min_vacuum_buffer_id = buffers.size() - vacuum_count;
+
+	// remove all invalid buffers from the available buffer list to ensure that we do not reuse them
+	auto it = buffers_with_free_space.begin();
+	while (it != buffers_with_free_space.end()) {
+		if (*it >= min_vacuum_buffer_id) {
+			it = buffers_with_free_space.erase(it);
+		} else {
+			it++;
+		}
+	}
+
+	return true;
+}
+
+void FixedSizeAllocator::FinalizeVacuum() {
+
+	// free all (now unused) buffers
+	while (min_vacuum_buffer_id < buffers.size()) {
+		allocator.FreeData(buffers.back().ptr, BUFFER_ALLOC_SIZE);
+		buffers.pop_back();
+	}
+}
+
+Node FixedSizeAllocator::VacuumPointer(const Node ptr) {
+
+	// we do not need to adjust the bitmask of the old buffer, because we will free the entire
+	// buffer after the vacuum operation
+
+	auto new_ptr = New();
+
+	// new increases the allocation count
+	total_allocations--;
+
+	memcpy(Get(new_ptr), Get(ptr), allocation_size);
+	return new_ptr;
+}
+
+void FixedSizeAllocator::Verify() const {
+#ifdef DEBUG
+	auto total_available_allocations = allocations_per_buffer * buffers.size();
+	D_ASSERT(total_available_allocations >= total_allocations);
+	D_ASSERT(buffers.size() >= buffers_with_free_space.size());
+#endif
+}
+
+uint32_t FixedSizeAllocator::GetOffset(ValidityMask &mask, const idx_t allocation_count) {
+
+	auto data = mask.GetData();
+
+	// fills up a buffer sequentially before searching for free bits
+	if (mask.RowIsValid(allocation_count)) {
+		mask.SetInvalid(allocation_count);
+		return allocation_count;
+	}
+
+	// get an entry with free bits
+	for (idx_t entry_idx = 0; entry_idx < bitmask_count; entry_idx++) {
+		if (data[entry_idx] != 0) {
+
+			// find the position of the free bit
+			auto entry = data[entry_idx];
+			idx_t first_valid_bit = 0;
+
+			// this loop finds the position of the rightmost set bit in entry and stores it
+			// in first_valid_bit
+			for (idx_t i = 0; i < 6; i++) {
+				// set the left half of the bits of this level to zero and test if the entry is still not zero
+				if (entry & BASE[i]) {
+					// first valid bit is in the rightmost s[i] bits
+					// permanently set the left half of the bits to zero
+					entry &= BASE[i];
+				} else {
+					// first valid bit is in the leftmost s[i] bits
+					// shift by s[i] for the next iteration and add s[i] to the position of the rightmost set bit
+					entry >>= SHIFT[i];
+					first_valid_bit += SHIFT[i];
+				}
+			}
+			D_ASSERT(entry);
+
+			auto prev_bits = entry_idx * sizeof(validity_t) * 8;
+			D_ASSERT(mask.RowIsValid(prev_bits + first_valid_bit));
+			mask.SetInvalid(prev_bits + first_valid_bit);
+			return (prev_bits + first_valid_bit);
+		}
+	}
+
+	throw InternalException("Invalid bitmask of FixedSizeAllocator");
+}
+
+} // namespace duckdb
diff --git a/src/duckdb/src/execution/index/art/plan_art.cpp b/src/duckdb/src/execution/index/art/plan_art.cpp
new file mode 100644
index 00000000..2acc5699
--- /dev/null
+++ b/src/duckdb/src/execution/index/art/plan_art.cpp
@@ -0,0 +1,94 @@
+
+#include "duckdb/execution/operator/order/physical_order.hpp"
+#include "duckdb/execution/operator/projection/physical_projection.hpp"
+#include "duckdb/execution/operator/filter/physical_filter.hpp"
+#include "duckdb/execution/operator/schema/physical_create_art_index.hpp"
+
+#include "duckdb/planner/expression/bound_operator_expression.hpp"
+#include "duckdb/planner/expression/bound_reference_expression.hpp"
+#include "duckdb/planner/operator/logical_create_index.hpp"
+
+#include "duckdb/execution/index/art/art.hpp"
+
+namespace duckdb {
+
+unique_ptr ART::CreatePlan(PlanIndexInput &input) {
+	// generate a physical plan for the parallel index creation which consists of the following operators
+	// table scan - projection (for expression execution) - filter (NOT NULL) - order (if applicable) - create index
+
+	auto &op = input.op;
+	auto &table_scan = input.table_scan;
+
+	vector new_column_types;
+	vector> select_list;
+	for (idx_t i = 0; i < op.expressions.size(); i++) {
+		new_column_types.push_back(op.expressions[i]->return_type);
+		select_list.push_back(std::move(op.expressions[i]));
+	}
+	new_column_types.emplace_back(LogicalType::ROW_TYPE);
+	select_list.push_back(make_uniq(LogicalType::ROW_TYPE, op.info->scan_types.size() - 1));
+
+	auto projection = make_uniq(new_column_types, std::move(select_list), op.estimated_cardinality);
+	projection->children.push_back(std::move(table_scan));
+
+	// filter operator for IS_NOT_NULL on each key column
+
+	vector filter_types;
+	vector> filter_select_list;
+
+	for (idx_t i = 0; i < new_column_types.size() - 1; i++) {
+		filter_types.push_back(new_column_types[i]);
+		auto is_not_null_expr =
+		    make_uniq(ExpressionType::OPERATOR_IS_NOT_NULL, LogicalType::BOOLEAN);
+		auto bound_ref = make_uniq(new_column_types[i], i);
+		is_not_null_expr->children.push_back(std::move(bound_ref));
+		filter_select_list.push_back(std::move(is_not_null_expr));
+	}
+
+	auto null_filter =
+	    make_uniq(std::move(filter_types), std::move(filter_select_list), op.estimated_cardinality);
+	null_filter->types.emplace_back(LogicalType::ROW_TYPE);
+	null_filter->children.push_back(std::move(projection));
+
+	// determine if we sort the data prior to index creation
+	// we don't sort, if either VARCHAR or compound key
+	auto perform_sorting = true;
+	if (op.unbound_expressions.size() > 1) {
+		perform_sorting = false;
+	} else if (op.unbound_expressions[0]->return_type.InternalType() == PhysicalType::VARCHAR) {
+		perform_sorting = false;
+	}
+
+	// actual physical create index operator
+
+	auto physical_create_index =
+	    make_uniq(op, op.table, op.info->column_ids, std::move(op.info),
+	                                      std::move(op.unbound_expressions), op.estimated_cardinality, perform_sorting);
+
+	if (perform_sorting) {
+
+		// optional order operator
+		vector orders;
+		vector projections;
+		for (idx_t i = 0; i < new_column_types.size() - 1; i++) {
+			auto col_expr = make_uniq_base(new_column_types[i], i);
+			orders.emplace_back(OrderType::ASCENDING, OrderByNullType::NULLS_FIRST, std::move(col_expr));
+			projections.emplace_back(i);
+		}
+		projections.emplace_back(new_column_types.size() - 1);
+
+		auto physical_order = make_uniq(new_column_types, std::move(orders), std::move(projections),
+		                                               op.estimated_cardinality);
+		physical_order->children.push_back(std::move(null_filter));
+
+		physical_create_index->children.push_back(std::move(physical_order));
+	} else {
+
+		// no ordering
+		physical_create_index->children.push_back(std::move(null_filter));
+	}
+
+	return std::move(physical_create_index);
+}
+
+} // namespace duckdb
diff --git a/src/duckdb/src/execution/index/index_type_set.cpp b/src/duckdb/src/execution/index/index_type_set.cpp
index 4e1dda7e..4fe7cda4 100644
--- a/src/duckdb/src/execution/index/index_type_set.cpp
+++ b/src/duckdb/src/execution/index/index_type_set.cpp
@@ -5,10 +5,13 @@
 namespace duckdb {
 
 IndexTypeSet::IndexTypeSet() {
-	// Register the ART index type
+
+	// Register the ART index type by default
 	IndexType art_index_type;
 	art_index_type.name = ART::TYPE_NAME;
 	art_index_type.create_instance = ART::Create;
+	art_index_type.create_plan = ART::CreatePlan;
+
 	RegisterIndexType(art_index_type);
 }
 
diff --git a/src/duckdb/src/execution/join_hashtable.cpp b/src/duckdb/src/execution/join_hashtable.cpp
index e19d2a7e..095745c3 100644
--- a/src/duckdb/src/execution/join_hashtable.cpp
+++ b/src/duckdb/src/execution/join_hashtable.cpp
@@ -453,23 +453,21 @@ static inline data_ptr_t InsertRowToEntry(atomic &entry, const data_
 		// if we expect the entry to be empty, if the operation fails we need to cancel the whole operation as another
 		// key might have been inserted in the meantime that does not match the current key
 		if (EXPECT_EMPTY) {
-
 			// add nullptr to the end of the list to mark the end
 			StorePointer(nullptr, row_ptr_to_insert + pointer_offset);
 
 			ht_entry_t new_empty_entry = ht_entry_t::GetDesiredEntry(row_ptr_to_insert, salt);
 			ht_entry_t expected_empty_entry = ht_entry_t::GetEmptyEntry();
-			std::atomic_compare_exchange_weak(&entry, &expected_empty_entry, new_empty_entry);
+			entry.compare_exchange_strong(expected_empty_entry, new_empty_entry, std::memory_order_acquire,
+			                              std::memory_order_relaxed);
 
 			// if the expected empty entry actually was null, we can just return the pointer, and it will be a nullptr
 			// if the expected entry was filled in the meantime, we need to cancel the operation and will return the
 			// pointer to the next entry
 			return expected_empty_entry.GetPointerOrNull();
-		}
-
-		// if we expect the entry to be full, we know that even if the insert fails the keys still match so we can
-		// just keep trying until we succeed
-		else {
+		} else {
+			// if we expect the entry to be full, we know that even if the insert fails the keys still match so we can
+			// just keep trying until we succeed
 			ht_entry_t expected_current_entry = entry.load(std::memory_order_relaxed);
 			ht_entry_t desired_new_entry = ht_entry_t::GetDesiredEntry(row_ptr_to_insert, salt);
 			D_ASSERT(expected_current_entry.IsOccupied());
@@ -477,7 +475,8 @@ static inline data_ptr_t InsertRowToEntry(atomic &entry, const data_
 			do {
 				data_ptr_t current_row_pointer = expected_current_entry.GetPointer();
 				StorePointer(current_row_pointer, row_ptr_to_insert + pointer_offset);
-			} while (!std::atomic_compare_exchange_weak(&entry, &expected_current_entry, desired_new_entry));
+			} while (!entry.compare_exchange_weak(expected_current_entry, desired_new_entry, std::memory_order_release,
+			                                      std::memory_order_relaxed));
 
 			return nullptr;
 		}
diff --git a/src/duckdb/src/execution/operator/aggregate/physical_hash_aggregate.cpp b/src/duckdb/src/execution/operator/aggregate/physical_hash_aggregate.cpp
index c4cf4b55..e7d0c756 100644
--- a/src/duckdb/src/execution/operator/aggregate/physical_hash_aggregate.cpp
+++ b/src/duckdb/src/execution/operator/aggregate/physical_hash_aggregate.cpp
@@ -319,15 +319,17 @@ void PhysicalHashAggregate::SinkDistinctGrouping(ExecutionContext &context, Data
 			for (idx_t group_idx = 0; group_idx < grouped_aggregate_data.groups.size(); group_idx++) {
 				auto &group = grouped_aggregate_data.groups[group_idx];
 				auto &bound_ref = group->Cast();
-				filtered_input.data[bound_ref.index].Reference(chunk.data[bound_ref.index]);
+				auto &col = filtered_input.data[bound_ref.index];
+				col.Reference(chunk.data[bound_ref.index]);
+				col.Slice(sel_vec, count);
 			}
 			for (idx_t child_idx = 0; child_idx < aggregate.children.size(); child_idx++) {
 				auto &child = aggregate.children[child_idx];
 				auto &bound_ref = child->Cast();
-
-				filtered_input.data[bound_ref.index].Reference(chunk.data[bound_ref.index]);
+				auto &col = filtered_input.data[bound_ref.index];
+				col.Reference(chunk.data[bound_ref.index]);
+				col.Slice(sel_vec, count);
 			}
-			filtered_input.Slice(sel_vec, count);
 			filtered_input.SetCardinality(count);
 
 			radix_table.Sink(context, filtered_input, sink_input, empty_chunk, empty_filter);
diff --git a/src/duckdb/src/execution/operator/csv_scanner/buffer_manager/csv_buffer_manager.cpp b/src/duckdb/src/execution/operator/csv_scanner/buffer_manager/csv_buffer_manager.cpp
index c8a7d167..064595f3 100644
--- a/src/duckdb/src/execution/operator/csv_scanner/buffer_manager/csv_buffer_manager.cpp
+++ b/src/duckdb/src/execution/operator/csv_scanner/buffer_manager/csv_buffer_manager.cpp
@@ -119,15 +119,15 @@ void CSVBufferManager::ResetBuffer(const idx_t buffer_idx) {
 	}
 }
 
-idx_t CSVBufferManager::GetBufferSize() {
+idx_t CSVBufferManager::GetBufferSize() const {
 	return buffer_size;
 }
 
-idx_t CSVBufferManager::BufferCount() {
+idx_t CSVBufferManager::BufferCount() const {
 	return cached_buffers.size();
 }
 
-bool CSVBufferManager::Done() {
+bool CSVBufferManager::Done() const {
 	return done;
 }
 
@@ -144,7 +144,7 @@ void CSVBufferManager::ResetBufferManager() {
 	}
 }
 
-string CSVBufferManager::GetFilePath() {
+string CSVBufferManager::GetFilePath() const {
 	return file_path;
 }
 
diff --git a/src/duckdb/src/execution/operator/csv_scanner/scanner/base_scanner.cpp b/src/duckdb/src/execution/operator/csv_scanner/scanner/base_scanner.cpp
index 63e93eda..757598e1 100644
--- a/src/duckdb/src/execution/operator/csv_scanner/scanner/base_scanner.cpp
+++ b/src/duckdb/src/execution/operator/csv_scanner/scanner/base_scanner.cpp
@@ -1,6 +1,6 @@
 #include "duckdb/execution/operator/csv_scanner/base_scanner.hpp"
 
-#include "duckdb/execution/operator/csv_scanner/csv_sniffer.hpp"
+#include "duckdb/execution/operator/csv_scanner/sniffer/csv_sniffer.hpp"
 #include "duckdb/execution/operator/csv_scanner/skip_scanner.hpp"
 
 namespace duckdb {
diff --git a/src/duckdb/src/execution/operator/csv_scanner/scanner/csv_schema.cpp b/src/duckdb/src/execution/operator/csv_scanner/scanner/csv_schema.cpp
index 5d6a9b0d..139398d7 100644
--- a/src/duckdb/src/execution/operator/csv_scanner/scanner/csv_schema.cpp
+++ b/src/duckdb/src/execution/operator/csv_scanner/scanner/csv_schema.cpp
@@ -60,14 +60,53 @@ bool CSVSchema::Empty() const {
 	return columns.empty();
 }
 
-bool CSVSchema::SchemasMatch(string &error_message, vector &names, vector &types,
-                             const string &cur_file_path) {
-	D_ASSERT(names.size() == types.size());
+bool CSVSchema::SchemasMatch(string &error_message, SnifferResult &sniffer_result, const string &cur_file_path,
+                             bool is_minimal_sniffer) const {
+	D_ASSERT(sniffer_result.names.size() == sniffer_result.return_types.size());
 	bool match = true;
 	unordered_map current_schema;
-	for (idx_t i = 0; i < names.size(); i++) {
+
+	for (idx_t i = 0; i < sniffer_result.names.size(); i++) {
 		// Populate our little schema
-		current_schema[names[i]] = {types[i], i};
+		current_schema[sniffer_result.names[i]] = {sniffer_result.return_types[i], i};
+	}
+	if (is_minimal_sniffer) {
+		auto min_sniffer = static_cast(sniffer_result);
+		if (!min_sniffer.more_than_one_row) {
+			bool min_sniff_match = true;
+			// If we don't have more than one row, either the names must match or the types must match.
+			for (auto &column : columns) {
+				if (current_schema.find(column.name) == current_schema.end()) {
+					min_sniff_match = false;
+					break;
+				}
+			}
+			if (min_sniff_match) {
+				return true;
+			}
+			// Otherwise, the types must match.
+			min_sniff_match = true;
+			if (sniffer_result.return_types.size() == columns.size()) {
+				idx_t return_type_idx = 0;
+				for (auto &column : columns) {
+					if (column.type != sniffer_result.return_types[return_type_idx++]) {
+						min_sniff_match = false;
+						break;
+					}
+				}
+			} else {
+				min_sniff_match = false;
+			}
+			if (min_sniff_match) {
+				// If we got here, we have the right types but the wrong names, lets fix the names
+				idx_t sniff_name_idx = 0;
+				for (auto &column : columns) {
+					sniffer_result.names[sniff_name_idx++] = column.name;
+				}
+				return true;
+			}
+		}
+		// If we got to this point, the minimal sniffer doesn't match, we throw an error.
 	}
 	// Here we check if the schema of a given file matched our original schema
 	// We consider it's not a match if:
diff --git a/src/duckdb/src/execution/operator/csv_scanner/scanner/string_value_scanner.cpp b/src/duckdb/src/execution/operator/csv_scanner/scanner/string_value_scanner.cpp
index 173ca8a1..9662e849 100644
--- a/src/duckdb/src/execution/operator/csv_scanner/scanner/string_value_scanner.cpp
+++ b/src/duckdb/src/execution/operator/csv_scanner/scanner/string_value_scanner.cpp
@@ -258,7 +258,7 @@ void StringValueResult::AddValueToVector(const char *value_ptr, const idx_t size
 							// We check for a weird case, where we ignore an extra value, if it is a null value
 							return;
 						}
-						validity_mask[chunk_col_id]->SetInvalid(number_of_rows);
+						validity_mask[chunk_col_id]->SetInvalid(static_cast(number_of_rows));
 					}
 					cur_col_id++;
 					chunk_col_id++;
@@ -447,7 +447,11 @@ void StringValueResult::AddValueToVector(const char *value_ptr, const idx_t size
 }
 
 DataChunk &StringValueResult::ToChunk() {
-	parse_chunk.SetCardinality(number_of_rows);
+	if (number_of_rows < 0) {
+		throw InternalException("CSVScanner: ToChunk() function. Has a negative number of rows, this indicates an "
+		                        "issue with the error handler.");
+	}
+	parse_chunk.SetCardinality(static_cast(number_of_rows));
 	return parse_chunk;
 }
 
@@ -658,7 +662,7 @@ bool LineError::HandleErrors(StringValueResult &result) {
 			result.RemoveLastLine();
 		} else {
 			// Otherwise, we add it to the borked rows to remove it later and just cleanup the column variables.
-			result.borked_rows.insert(result.number_of_rows);
+			result.borked_rows.insert(static_cast(result.number_of_rows));
 			result.cur_col_id = 0;
 			result.chunk_col_id = 0;
 		}
@@ -740,9 +744,9 @@ bool StringValueResult::AddRowInternal() {
 	}
 
 	if (current_errors.HandleErrors(*this)) {
-		line_positions_per_row[number_of_rows] = current_line_position;
+		line_positions_per_row[static_cast(number_of_rows)] = current_line_position;
 		number_of_rows++;
-		if (number_of_rows >= result_size) {
+		if (static_cast(number_of_rows) >= result_size) {
 			// We have a full chunk
 			return true;
 		}
@@ -769,7 +773,7 @@ bool StringValueResult::AddRowInternal() {
 				if (empty) {
 					static_cast(vector_ptr[chunk_col_id])[number_of_rows] = string_t();
 				} else {
-					validity_mask[chunk_col_id]->SetInvalid(number_of_rows);
+					validity_mask[chunk_col_id]->SetInvalid(static_cast(number_of_rows));
 				}
 				cur_col_id++;
 				chunk_col_id++;
@@ -799,11 +803,11 @@ bool StringValueResult::AddRowInternal() {
 			RemoveLastLine();
 		}
 	}
-	line_positions_per_row[number_of_rows] = current_line_position;
+	line_positions_per_row[static_cast(number_of_rows)] = current_line_position;
 	cur_col_id = 0;
 	chunk_col_id = 0;
 	number_of_rows++;
-	if (number_of_rows >= result_size) {
+	if (static_cast(number_of_rows) >= result_size) {
 		// We have a full chunk
 		return true;
 	}
@@ -861,12 +865,12 @@ bool StringValueResult::EmptyLine(StringValueResult &result, const idx_t buffer_
 				if (empty) {
 					static_cast(result.vector_ptr[0])[result.number_of_rows] = string_t();
 				} else {
-					result.validity_mask[0]->SetInvalid(result.number_of_rows);
+					result.validity_mask[0]->SetInvalid(static_cast(result.number_of_rows));
 				}
 				result.number_of_rows++;
 			}
 		}
-		if (result.number_of_rows >= result.result_size) {
+		if (static_cast(result.number_of_rows) >= result.result_size) {
 			// We have a full chunk
 			return true;
 		}
@@ -1043,15 +1047,15 @@ void StringValueScanner::Flush(DataChunk &insert_chunk) {
 	}
 	if (!result.borked_rows.empty()) {
 		// We must remove the borked lines from our chunk
-		SelectionVector succesful_rows(parse_chunk.size());
+		SelectionVector successful_rows(parse_chunk.size());
 		idx_t sel_idx = 0;
 		for (idx_t row_idx = 0; row_idx < parse_chunk.size(); row_idx++) {
 			if (result.borked_rows.find(row_idx) == result.borked_rows.end()) {
-				succesful_rows.set_index(sel_idx++, row_idx);
+				successful_rows.set_index(sel_idx++, row_idx);
 			}
 		}
 		// Now we slice the result
-		insert_chunk.Slice(succesful_rows, sel_idx);
+		insert_chunk.Slice(successful_rows, sel_idx);
 	}
 }
 
@@ -1389,7 +1393,7 @@ void StringValueResult::SkipBOM() const {
 void StringValueResult::RemoveLastLine() {
 	// potentially de-nullify values
 	for (idx_t i = 0; i < chunk_col_id; i++) {
-		validity_mask[i]->SetValid(number_of_rows);
+		validity_mask[i]->SetValid(static_cast(number_of_rows));
 	}
 	// reset column trackers
 	cur_col_id = 0;
@@ -1470,10 +1474,6 @@ void StringValueScanner::SetStart() {
 		}
 		return;
 	}
-	if (state_machine->options.IgnoreErrors()) {
-		// If we are ignoring errors we don't really need to figure out a line.
-		return;
-	}
 	// The result size of the data after skipping the row is one line
 	// We have to look for a new line that fits our schema
 	// 1. We walk until the next new line
@@ -1524,7 +1524,7 @@ void StringValueScanner::SetStart() {
 }
 
 void StringValueScanner::FinalizeChunkProcess() {
-	if (result.number_of_rows >= result.result_size || iterator.done) {
+	if (static_cast(result.number_of_rows) >= result.result_size || iterator.done) {
 		// We are done
 		if (!sniffing) {
 			if (csv_file_scan) {
@@ -1562,14 +1562,18 @@ void StringValueScanner::FinalizeChunkProcess() {
 			if (result.current_errors.HasErrorType(UNTERMINATED_QUOTES)) {
 				has_unterminated_quotes = true;
 			}
-			result.current_errors.HandleErrors(result);
+			if (result.current_errors.HandleErrors(result)) {
+				result.number_of_rows++;
+			}
 		}
 		if (states.IsQuotedCurrent() && !has_unterminated_quotes) {
 			// If we finish the execution of a buffer, and we end in a quoted state, it means we have unterminated
 			// quotes
 			result.current_errors.Insert(UNTERMINATED_QUOTES, result.cur_col_id, result.chunk_col_id,
 			                             result.last_position);
-			result.current_errors.HandleErrors(result);
+			if (result.current_errors.HandleErrors(result)) {
+				result.number_of_rows++;
+			}
 		}
 		if (!iterator.done) {
 			if (iterator.pos.buffer_pos >= iterator.GetEndPos() || iterator.pos.buffer_idx > iterator.GetBufferIdx() ||
@@ -1580,9 +1584,9 @@ void StringValueScanner::FinalizeChunkProcess() {
 	} else {
 		// 2) If a boundary is not set
 		// We read until the chunk is complete, or we have nothing else to read.
-		while (!FinishedFile() && result.number_of_rows < result.result_size) {
+		while (!FinishedFile() && static_cast(result.number_of_rows) < result.result_size) {
 			MoveToNextBuffer();
-			if (result.number_of_rows >= result.result_size) {
+			if (static_cast(result.number_of_rows) >= result.result_size) {
 				return;
 			}
 			if (cur_buffer_handle) {
@@ -1592,7 +1596,7 @@ void StringValueScanner::FinalizeChunkProcess() {
 		iterator.done = FinishedFile();
 		if (result.null_padding && result.number_of_rows < STANDARD_VECTOR_SIZE && result.chunk_col_id > 0) {
 			while (result.chunk_col_id < result.parse_chunk.ColumnCount()) {
-				result.validity_mask[result.chunk_col_id++]->SetInvalid(result.number_of_rows);
+				result.validity_mask[result.chunk_col_id++]->SetInvalid(static_cast(result.number_of_rows));
 				result.cur_col_id++;
 			}
 			result.number_of_rows++;
diff --git a/src/duckdb/src/execution/operator/csv_scanner/sniffer/csv_sniffer.cpp b/src/duckdb/src/execution/operator/csv_scanner/sniffer/csv_sniffer.cpp
index bee31f88..950d7489 100644
--- a/src/duckdb/src/execution/operator/csv_scanner/sniffer/csv_sniffer.cpp
+++ b/src/duckdb/src/execution/operator/csv_scanner/sniffer/csv_sniffer.cpp
@@ -1,4 +1,4 @@
-#include "duckdb/execution/operator/csv_scanner/csv_sniffer.hpp"
+#include "duckdb/execution/operator/csv_scanner/sniffer/csv_sniffer.hpp"
 #include "duckdb/common/types/value.hpp"
 
 namespace duckdb {
@@ -41,7 +41,7 @@ void MatchAndReplace(CSVOption &original, CSVOption &sniffed, const string
 		// We verify that the user input matches the sniffed value
 		if (original != sniffed) {
 			error += "CSV Sniffer: Sniffer detected value different than the user input for the " + name;
-			error += " options \n Set: " + original.FormatValue() + " Sniffed: " + sniffed.FormatValue() + "\n";
+			error += " options \n Set: " + original.FormatValue() + ", Sniffed: " + sniffed.FormatValue() + "\n";
 		}
 	} else {
 		// We replace the value of original with the sniffed value
@@ -88,15 +88,14 @@ void CSVSniffer::SetResultOptions() {
 	options.dialect_options.rows_until_header = best_candidate->GetStateMachine().dialect_options.rows_until_header;
 }
 
-SnifferResult CSVSniffer::MinimalSniff() {
+AdaptiveSnifferResult CSVSniffer::MinimalSniff() {
 	if (set_columns.IsSet()) {
 		// Nothing to see here
-		return SnifferResult(*set_columns.types, *set_columns.names);
+		return AdaptiveSnifferResult(*set_columns.types, *set_columns.names, true);
 	}
 	// Return Types detected
 	vector return_types;
 	// Column Names detected
-	vector names;
 
 	buffer_manager->sniffing = true;
 	constexpr idx_t result_size = 2;
@@ -106,7 +105,8 @@ SnifferResult CSVSniffer::MinimalSniff() {
 	ColumnCountScanner count_scanner(buffer_manager, state_machine, error_handler, result_size);
 	auto &sniffed_column_counts = count_scanner.ParseChunk();
 	if (sniffed_column_counts.result_position == 0) {
-		return {{}, {}};
+		// The file is an empty file, we just return
+		return {{}, {}, false};
 	}
 
 	state_machine->dialect_options.num_cols = sniffed_column_counts[0].number_of_columns;
@@ -130,20 +130,20 @@ SnifferResult CSVSniffer::MinimalSniff() {
 
 	// Possibly Gather Header
 	vector potential_header;
-	if (start_row != 0) {
-		for (idx_t col_idx = 0; col_idx < data_chunk.ColumnCount(); col_idx++) {
-			auto &cur_vector = data_chunk.data[col_idx];
-			auto vector_data = FlatVector::GetData(cur_vector);
-			auto &validity = FlatVector::Validity(cur_vector);
-			HeaderValue val;
-			if (validity.RowIsValid(0)) {
-				val = HeaderValue(vector_data[0]);
-			}
-			potential_header.emplace_back(val);
+
+	for (idx_t col_idx = 0; col_idx < data_chunk.ColumnCount(); col_idx++) {
+		auto &cur_vector = data_chunk.data[col_idx];
+		auto vector_data = FlatVector::GetData(cur_vector);
+		auto &validity = FlatVector::Validity(cur_vector);
+		HeaderValue val;
+		if (validity.RowIsValid(0)) {
+			val = HeaderValue(vector_data[0]);
 		}
+		potential_header.emplace_back(val);
 	}
-	names = DetectHeaderInternal(buffer_manager->context, potential_header, *state_machine, set_columns,
-	                             best_sql_types_candidates_per_column_idx, options, *error_handler);
+
+	vector names = DetectHeaderInternal(buffer_manager->context, potential_header, *state_machine, set_columns,
+	                                            best_sql_types_candidates_per_column_idx, options, *error_handler);
 
 	for (idx_t column_idx = 0; column_idx < best_sql_types_candidates_per_column_idx.size(); column_idx++) {
 		LogicalType d_type = best_sql_types_candidates_per_column_idx[column_idx].back();
@@ -153,10 +153,10 @@ SnifferResult CSVSniffer::MinimalSniff() {
 		detected_types.push_back(d_type);
 	}
 
-	return {detected_types, names};
+	return {detected_types, names, sniffed_column_counts.result_position > 1};
 }
 
-SnifferResult CSVSniffer::AdaptiveSniff(CSVSchema &file_schema) {
+SnifferResult CSVSniffer::AdaptiveSniff(const CSVSchema &file_schema) {
 	auto min_sniff_res = MinimalSniff();
 	bool run_full = error_handler->AnyErrors() || detection_error_handler->AnyErrors();
 	// Check if we are happy with the result or if we need to do more sniffing
@@ -164,8 +164,7 @@ SnifferResult CSVSniffer::AdaptiveSniff(CSVSchema &file_schema) {
 		// If we got no errors, we also run full if schemas do not match.
 		if (!set_columns.IsSet() && !options.file_options.AnySet()) {
 			string error;
-			run_full =
-			    !file_schema.SchemasMatch(error, min_sniff_res.names, min_sniff_res.return_types, options.file_path);
+			run_full = !file_schema.SchemasMatch(error, min_sniff_res, options.file_path, true);
 		}
 	}
 	if (run_full) {
@@ -173,14 +172,14 @@ SnifferResult CSVSniffer::AdaptiveSniff(CSVSchema &file_schema) {
 		auto full_sniffer = SniffCSV();
 		if (!set_columns.IsSet() && !options.file_options.AnySet()) {
 			string error;
-			if (!file_schema.SchemasMatch(error, full_sniffer.names, full_sniffer.return_types, options.file_path) &&
+			if (!file_schema.SchemasMatch(error, full_sniffer, options.file_path, false) &&
 			    !options.ignore_errors.GetValue()) {
 				throw InvalidInputException(error);
 			}
 		}
 		return full_sniffer;
 	}
-	return min_sniff_res;
+	return min_sniff_res.ToSnifferResult();
 }
 SnifferResult CSVSniffer::SniffCSV(bool force_match) {
 	buffer_manager->sniffing = true;
@@ -228,8 +227,8 @@ SnifferResult CSVSniffer::SniffCSV(bool force_match) {
 			if (set_names.size() == names.size()) {
 				for (idx_t i = 0; i < set_columns.Size(); i++) {
 					if (set_names[i] != names[i]) {
-						header_error += "Column at position: " + to_string(i) + " Set name: " + set_names[i] +
-						                " Sniffed Name: " + names[i] + "\n";
+						header_error += "Column at position: " + to_string(i) + ", Set name: " + set_names[i] +
+						                ", Sniffed Name: " + names[i] + "\n";
 						match = false;
 					}
 				}
diff --git a/src/duckdb/src/execution/operator/csv_scanner/sniffer/dialect_detection.cpp b/src/duckdb/src/execution/operator/csv_scanner/sniffer/dialect_detection.cpp
index bf142a93..43cef4fc 100644
--- a/src/duckdb/src/execution/operator/csv_scanner/sniffer/dialect_detection.cpp
+++ b/src/duckdb/src/execution/operator/csv_scanner/sniffer/dialect_detection.cpp
@@ -1,5 +1,5 @@
 #include "duckdb/common/shared_ptr.hpp"
-#include "duckdb/execution/operator/csv_scanner/csv_sniffer.hpp"
+#include "duckdb/execution/operator/csv_scanner/sniffer/csv_sniffer.hpp"
 #include "duckdb/main/client_data.hpp"
 #include "duckdb/execution/operator/csv_scanner/csv_reader_options.hpp"
 
@@ -302,6 +302,8 @@ void CSVSniffer::AnalyzeDialectCandidate(unique_ptr scanner,
 	// Whether there are more values (rows) available that are consistent, exceeding the current best.
 	bool more_values = consistent_rows > best_consistent_rows && num_cols >= max_columns_found;
 
+	bool more_columns = consistent_rows == best_consistent_rows && num_cols > max_columns_found;
+
 	// If additional padding is required when compared to the previous padding count.
 	bool require_more_padding = padding_count > prev_padding_count;
 
@@ -338,10 +340,10 @@ void CSVSniffer::AnalyzeDialectCandidate(unique_ptr scanner,
 	// - There are more values and no additional padding is required.
 	// - There's more than one column and less padding is required.
 	if (rows_consistent &&
-	    (single_column_before || (more_values && !require_more_padding) ||
+	    (single_column_before || ((more_values || more_columns) && !require_more_padding) ||
 	     (more_than_one_column && require_less_padding)) &&
 	    !invalid_padding && comments_are_acceptable) {
-		if (!candidates.empty() && set_columns.IsSet() && max_columns_found == candidates.size()) {
+		if (!candidates.empty() && set_columns.IsSet() && max_columns_found == set_columns.Size()) {
 			// We have a candidate that fits our requirements better
 			return;
 		}
diff --git a/src/duckdb/src/execution/operator/csv_scanner/sniffer/header_detection.cpp b/src/duckdb/src/execution/operator/csv_scanner/sniffer/header_detection.cpp
index fd050400..9475f594 100644
--- a/src/duckdb/src/execution/operator/csv_scanner/sniffer/header_detection.cpp
+++ b/src/duckdb/src/execution/operator/csv_scanner/sniffer/header_detection.cpp
@@ -1,5 +1,5 @@
 #include "duckdb/common/types/cast_helpers.hpp"
-#include "duckdb/execution/operator/csv_scanner/csv_sniffer.hpp"
+#include "duckdb/execution/operator/csv_scanner/sniffer/csv_sniffer.hpp"
 #include "duckdb/execution/operator/csv_scanner/csv_reader_options.hpp"
 
 #include "utf8proc.hpp"
@@ -114,9 +114,9 @@ bool CSVSniffer::DetectHeaderWithSetColumn(ClientContext &context, vector
Error(error); + error_handler->Error(error, true); } // Assert that it's all good at this point. D_ASSERT(best_candidate && !best_format_candidates.empty()); diff --git a/src/duckdb/src/execution/operator/csv_scanner/sniffer/type_refinement.cpp b/src/duckdb/src/execution/operator/csv_scanner/sniffer/type_refinement.cpp index 43d69318..8d3e2684 100644 --- a/src/duckdb/src/execution/operator/csv_scanner/sniffer/type_refinement.cpp +++ b/src/duckdb/src/execution/operator/csv_scanner/sniffer/type_refinement.cpp @@ -1,4 +1,4 @@ -#include "duckdb/execution/operator/csv_scanner/csv_sniffer.hpp" +#include "duckdb/execution/operator/csv_scanner/sniffer/csv_sniffer.hpp" #include "duckdb/execution/operator/csv_scanner/csv_casting.hpp" namespace duckdb { diff --git a/src/duckdb/src/execution/operator/csv_scanner/sniffer/type_replacement.cpp b/src/duckdb/src/execution/operator/csv_scanner/sniffer/type_replacement.cpp index 34fa4146..a693144d 100644 --- a/src/duckdb/src/execution/operator/csv_scanner/sniffer/type_replacement.cpp +++ b/src/duckdb/src/execution/operator/csv_scanner/sniffer/type_replacement.cpp @@ -1,4 +1,4 @@ -#include "duckdb/execution/operator/csv_scanner/csv_sniffer.hpp" +#include "duckdb/execution/operator/csv_scanner/sniffer/csv_sniffer.hpp" namespace duckdb { void CSVSniffer::ReplaceTypes() { diff --git a/src/duckdb/src/execution/operator/csv_scanner/state_machine/csv_state_machine.cpp b/src/duckdb/src/execution/operator/csv_scanner/state_machine/csv_state_machine.cpp index 665c5b39..eae140f7 100644 --- a/src/duckdb/src/execution/operator/csv_scanner/state_machine/csv_state_machine.cpp +++ b/src/duckdb/src/execution/operator/csv_scanner/state_machine/csv_state_machine.cpp @@ -1,5 +1,5 @@ #include "duckdb/execution/operator/csv_scanner/csv_state_machine.hpp" -#include "duckdb/execution/operator/csv_scanner/csv_sniffer.hpp" +#include "duckdb/execution/operator/csv_scanner/sniffer/csv_sniffer.hpp" #include "utf8proc_wrapper.hpp" #include "duckdb/main/error_manager.hpp" #include "duckdb/execution/operator/csv_scanner/csv_state_machine_cache.hpp" diff --git a/src/duckdb/src/execution/operator/csv_scanner/state_machine/csv_state_machine_cache.cpp b/src/duckdb/src/execution/operator/csv_scanner/state_machine/csv_state_machine_cache.cpp index 6c93cc93..9c40809c 100644 --- a/src/duckdb/src/execution/operator/csv_scanner/state_machine/csv_state_machine_cache.cpp +++ b/src/duckdb/src/execution/operator/csv_scanner/state_machine/csv_state_machine_cache.cpp @@ -1,6 +1,6 @@ #include "duckdb/execution/operator/csv_scanner/csv_state_machine.hpp" #include "duckdb/execution/operator/csv_scanner/csv_state_machine_cache.hpp" -#include "duckdb/execution/operator/csv_scanner/csv_sniffer.hpp" +#include "duckdb/execution/operator/csv_scanner/sniffer/csv_sniffer.hpp" namespace duckdb { @@ -26,10 +26,10 @@ void CSVStateMachineCache::Insert(const CSVStateMachineOptions &state_machine_op switch (cur_state) { case CSVState::QUOTED: case CSVState::QUOTED_NEW_LINE: + case CSVState::ESCAPE: InitializeTransitionArray(transition_array, cur_state, CSVState::QUOTED); break; case CSVState::UNQUOTED: - case CSVState::ESCAPE: InitializeTransitionArray(transition_array, cur_state, CSVState::INVALID); break; case CSVState::COMMENT: diff --git a/src/duckdb/src/execution/operator/csv_scanner/table_function/csv_file_scanner.cpp b/src/duckdb/src/execution/operator/csv_scanner/table_function/csv_file_scanner.cpp index e3589486..3e457580 100644 --- a/src/duckdb/src/execution/operator/csv_scanner/table_function/csv_file_scanner.cpp +++ b/src/duckdb/src/execution/operator/csv_scanner/table_function/csv_file_scanner.cpp @@ -1,6 +1,6 @@ #include "duckdb/execution/operator/csv_scanner/csv_file_scanner.hpp" -#include "duckdb/execution/operator/csv_scanner/csv_sniffer.hpp" +#include "duckdb/execution/operator/csv_scanner/sniffer/csv_sniffer.hpp" #include "duckdb/execution/operator/csv_scanner/skip_scanner.hpp" #include "duckdb/function/table/read_csv.hpp" diff --git a/src/duckdb/src/execution/operator/csv_scanner/table_function/global_csv_state.cpp b/src/duckdb/src/execution/operator/csv_scanner/table_function/global_csv_state.cpp index 4f3e9dce..cefb1341 100644 --- a/src/duckdb/src/execution/operator/csv_scanner/table_function/global_csv_state.cpp +++ b/src/duckdb/src/execution/operator/csv_scanner/table_function/global_csv_state.cpp @@ -1,6 +1,6 @@ #include "duckdb/execution/operator/csv_scanner/global_csv_state.hpp" -#include "duckdb/execution/operator/csv_scanner/csv_sniffer.hpp" +#include "duckdb/execution/operator/csv_scanner/sniffer/csv_sniffer.hpp" #include "duckdb/execution/operator/csv_scanner/scanner_boundary.hpp" #include "duckdb/execution/operator/csv_scanner/skip_scanner.hpp" #include "duckdb/execution/operator/persistent/csv_rejects_table.hpp" diff --git a/src/duckdb/src/execution/operator/csv_scanner/util/csv_reader_options.cpp b/src/duckdb/src/execution/operator/csv_scanner/util/csv_reader_options.cpp index 21f910ec..97fb22a9 100644 --- a/src/duckdb/src/execution/operator/csv_scanner/util/csv_reader_options.cpp +++ b/src/duckdb/src/execution/operator/csv_scanner/util/csv_reader_options.cpp @@ -4,6 +4,7 @@ #include "duckdb/common/string_util.hpp" #include "duckdb/common/enum_util.hpp" #include "duckdb/common/multi_file_reader.hpp" +#include "duckdb/common/set.hpp" namespace duckdb { @@ -404,7 +405,7 @@ string CSVReaderOptions::ToString(const string ¤t_file_path) const { auto &skip_rows = dialect_options.skip_rows; auto &header = dialect_options.header; - string error = " file=" + current_file_path + "\n "; + string error = " file = " + current_file_path + "\n "; // Let's first print options that can either be set by the user or by the sniffer // delimiter error += FormatOptionLine("delimiter", delimiter); @@ -427,13 +428,13 @@ string CSVReaderOptions::ToString(const string ¤t_file_path) const { // Now we do options that can only be set by the user, that might hold some general significance // null padding - error += "null_padding=" + std::to_string(null_padding) + "\n "; + error += "null_padding = " + std::to_string(null_padding) + "\n "; // sample_size - error += "sample_size=" + std::to_string(sample_size_chunks * STANDARD_VECTOR_SIZE) + "\n "; + error += "sample_size = " + std::to_string(sample_size_chunks * STANDARD_VECTOR_SIZE) + "\n "; // ignore_errors - error += "ignore_errors=" + ignore_errors.FormatValue() + "\n "; + error += "ignore_errors = " + ignore_errors.FormatValue() + "\n "; // all_varchar - error += "all_varchar=" + std::to_string(all_varchar) + "\n"; + error += "all_varchar = " + std::to_string(all_varchar) + "\n"; // Add information regarding sniffer mismatches (if any) error += sniffer_user_mismatch_error; @@ -452,15 +453,15 @@ static Value StringVectorToValue(const vector &vec) { static uint8_t GetCandidateSpecificity(const LogicalType &candidate_type) { //! Const ht with accepted auto_types and their weights in specificity const duckdb::unordered_map auto_type_candidates_specificity { - {(uint8_t)LogicalTypeId::VARCHAR, 0}, {(uint8_t)LogicalTypeId::DOUBLE, 1}, - {(uint8_t)LogicalTypeId::FLOAT, 2}, {(uint8_t)LogicalTypeId::DECIMAL, 3}, - {(uint8_t)LogicalTypeId::BIGINT, 4}, {(uint8_t)LogicalTypeId::INTEGER, 5}, - {(uint8_t)LogicalTypeId::SMALLINT, 6}, {(uint8_t)LogicalTypeId::TINYINT, 7}, - {(uint8_t)LogicalTypeId::TIMESTAMP, 8}, {(uint8_t)LogicalTypeId::DATE, 9}, - {(uint8_t)LogicalTypeId::TIME, 10}, {(uint8_t)LogicalTypeId::BOOLEAN, 11}, - {(uint8_t)LogicalTypeId::SQLNULL, 12}}; - - auto id = (uint8_t)candidate_type.id(); + {static_cast(LogicalTypeId::VARCHAR), 0}, {static_cast(LogicalTypeId::DOUBLE), 1}, + {static_cast(LogicalTypeId::FLOAT), 2}, {static_cast(LogicalTypeId::DECIMAL), 3}, + {static_cast(LogicalTypeId::BIGINT), 4}, {static_cast(LogicalTypeId::INTEGER), 5}, + {static_cast(LogicalTypeId::SMALLINT), 6}, {static_cast(LogicalTypeId::TINYINT), 7}, + {static_cast(LogicalTypeId::TIMESTAMP), 8}, {static_cast(LogicalTypeId::DATE), 9}, + {static_cast(LogicalTypeId::TIME), 10}, {static_cast(LogicalTypeId::BOOLEAN), 11}, + {static_cast(LogicalTypeId::SQLNULL), 12}}; + + auto id = static_cast(candidate_type.id()); auto it = auto_type_candidates_specificity.find(id); if (it == auto_type_candidates_specificity.end()) { throw BinderException("Auto Type Candidate of type %s is not accepted as a valid input", @@ -468,7 +469,7 @@ static uint8_t GetCandidateSpecificity(const LogicalType &candidate_type) { } return it->second; } -bool StoreUserDefinedParameter(string &option) { +bool StoreUserDefinedParameter(const string &option) { if (option == "column_types" || option == "types" || option == "dtypes" || option == "auto_detect" || option == "auto_type_candidates" || option == "columns" || option == "names") { // We don't store options related to types, names and auto-detection since these are either irrelevant to our @@ -477,20 +478,49 @@ bool StoreUserDefinedParameter(string &option) { } return true; } -void CSVReaderOptions::FromNamedParameters(named_parameter_map_t &in, ClientContext &context) { + +void CSVReaderOptions::Verify() { + if (rejects_table_name.IsSetByUser() && !store_rejects.GetValue() && store_rejects.IsSetByUser()) { + throw BinderException("REJECTS_TABLE option is only supported when store_rejects is not manually set to false"); + } + if (rejects_scan_name.IsSetByUser() && !store_rejects.GetValue() && store_rejects.IsSetByUser()) { + throw BinderException("REJECTS_SCAN option is only supported when store_rejects is not manually set to false"); + } + if (rejects_scan_name.IsSetByUser() || rejects_table_name.IsSetByUser()) { + // Ensure we set store_rejects to true automagically + store_rejects.Set(true, false); + } + // Validate rejects_table options + if (store_rejects.GetValue()) { + if (!ignore_errors.GetValue() && ignore_errors.IsSetByUser()) { + throw BinderException( + "STORE_REJECTS option is only supported when IGNORE_ERRORS is not manually set to false"); + } + // Ensure we set ignore errors to true automagically + ignore_errors.Set(true, false); + if (file_options.union_by_name) { + throw BinderException("REJECTS_TABLE option is not supported when UNION_BY_NAME is set to true"); + } + } + if (rejects_limit != 0 && !store_rejects.GetValue()) { + throw BinderException("REJECTS_LIMIT option is only supported when REJECTS_TABLE is set to a table name"); + } +} + +void CSVReaderOptions::FromNamedParameters(const named_parameter_map_t &in, ClientContext &context) { map ordered_user_defined_parameters; for (auto &kv : in) { if (MultiFileReader().ParseOption(kv.first, kv.second, file_options, context)) { continue; } auto loption = StringUtil::Lower(kv.first); - // skip variables that are specific to auto detection + // skip variables that are specific to auto-detection if (StoreUserDefinedParameter(loption)) { ordered_user_defined_parameters[loption] = kv.second.ToSQLString(); } if (loption == "columns") { if (!name_list.empty()) { - throw BinderException("read_csv_auto column_names/names can only be supplied once"); + throw BinderException("read_csv column_names/names can only be supplied once"); } columns_set = true; auto &child_type = kv.second.type(); @@ -539,23 +569,40 @@ void CSVReaderOptions::FromNamedParameters(named_parameter_map_t &in, ClientCont auto_type_candidates.emplace_back(candidate_type.second); } } else if (loption == "column_names" || loption == "names") { + unordered_set column_names; if (!name_list.empty()) { - throw BinderException("read_csv_auto column_names/names can only be supplied once"); + throw BinderException("read_csv column_names/names can only be supplied once"); } if (kv.second.IsNull()) { - throw BinderException("read_csv_auto %s cannot be NULL", kv.first); + throw BinderException("read_csv %s cannot be NULL", kv.first); } auto &children = ListValue::GetChildren(kv.second); for (auto &child : children) { name_list.push_back(StringValue::Get(child)); } + for (auto &name : name_list) { + bool empty = true; + for (auto &c : name) { + if (!StringUtil::CharacterIsSpace(c)) { + empty = false; + break; + } + } + if (empty) { + throw BinderException("read_csv %s cannot have empty (or all whitespace) value", kv.first); + } + if (column_names.find(name) != column_names.end()) { + throw BinderException("read_csv %s must have unique values. \"%s\" is repeated.", kv.first, name); + } + column_names.insert(name); + } } else if (loption == "column_types" || loption == "types" || loption == "dtypes") { auto &child_type = kv.second.type(); if (child_type.id() != LogicalTypeId::STRUCT && child_type.id() != LogicalTypeId::LIST) { - throw BinderException("read_csv_auto %s requires a struct or list as input", kv.first); + throw BinderException("read_csv %s requires a struct or list as input", kv.first); } if (!sql_type_list.empty()) { - throw BinderException("read_csv_auto column_types/types/dtypes can only be supplied once"); + throw BinderException("read_csv column_types/types/dtypes can only be supplied once"); } vector sql_type_names; if (child_type.id() == LogicalTypeId::STRUCT) { @@ -565,7 +612,7 @@ void CSVReaderOptions::FromNamedParameters(named_parameter_map_t &in, ClientCont auto &name = StructType::GetChildName(child_type, i); auto &val = struct_children[i]; if (val.type().id() != LogicalTypeId::VARCHAR) { - throw BinderException("read_csv_auto %s requires a type specification as string", kv.first); + throw BinderException("read_csv %s requires a type specification as string", kv.first); } sql_type_names.push_back(StringValue::Get(val)); sql_types_per_column[name] = i; @@ -573,7 +620,7 @@ void CSVReaderOptions::FromNamedParameters(named_parameter_map_t &in, ClientCont } else { auto &list_child = ListType::GetChildType(child_type); if (list_child.id() != LogicalTypeId::VARCHAR) { - throw BinderException("read_csv_auto %s requires a list of types (varchar) as input", kv.first); + throw BinderException("read_csv %s requires a list of types (varchar) as input", kv.first); } auto &children = ListValue::GetChildren(kv.second); for (auto &child : children) { @@ -584,8 +631,7 @@ void CSVReaderOptions::FromNamedParameters(named_parameter_map_t &in, ClientCont for (auto &sql_type : sql_type_names) { auto def_type = TransformStringToLogicalType(sql_type, context); if (def_type.id() == LogicalTypeId::USER) { - throw BinderException("Unrecognized type \"%s\" for read_csv_auto %s definition", sql_type, - kv.first); + throw BinderException("Unrecognized type \"%s\" for read_csv %s definition", sql_type, kv.first); } sql_type_list.push_back(std::move(def_type)); } @@ -606,7 +652,7 @@ void CSVReaderOptions::FromNamedParameters(named_parameter_map_t &in, ClientCont } //! This function is used to remember options set by the sniffer, for use in ReadCSVRelation -void CSVReaderOptions::ToNamedParameters(named_parameter_map_t &named_params) { +void CSVReaderOptions::ToNamedParameters(named_parameter_map_t &named_params) const { auto &delimiter = dialect_options.state_machine_options.delimiter; auto "e = dialect_options.state_machine_options.quote; auto &escape = dialect_options.state_machine_options.escape; diff --git a/src/duckdb/src/execution/operator/helper/physical_buffered_collector.cpp b/src/duckdb/src/execution/operator/helper/physical_buffered_collector.cpp index 6a036109..d52b7bc4 100644 --- a/src/duckdb/src/execution/operator/helper/physical_buffered_collector.cpp +++ b/src/duckdb/src/execution/operator/helper/physical_buffered_collector.cpp @@ -59,7 +59,7 @@ unique_ptr PhysicalBufferedCollector::GetLocalSinkState(Executio unique_ptr PhysicalBufferedCollector::GetResult(GlobalSinkState &state) { auto &gstate = state.Cast(); lock_guard l(gstate.glock); - // FIXME: maybe we want to check if the execution was successfull before creating the StreamQueryResult ? + // FIXME: maybe we want to check if the execution was successful before creating the StreamQueryResult ? auto cc = gstate.context.lock(); auto result = make_uniq(statement_type, properties, types, names, cc->GetClientProperties(), gstate.buffered_data); diff --git a/src/duckdb/src/execution/operator/persistent/base_csv_reader.cpp b/src/duckdb/src/execution/operator/persistent/base_csv_reader.cpp new file mode 100644 index 00000000..073e11df --- /dev/null +++ b/src/duckdb/src/execution/operator/persistent/base_csv_reader.cpp @@ -0,0 +1,695 @@ +#include "duckdb/execution/operator/persistent/base_csv_reader.hpp" +#include "duckdb/catalog/catalog_entry/table_catalog_entry.hpp" +#include "duckdb/common/file_system.hpp" +#include "duckdb/common/string_util.hpp" +#include "duckdb/common/to_string.hpp" +#include "duckdb/common/types/cast_helpers.hpp" +#include "duckdb/common/operator/cast_operators.hpp" +#include "duckdb/common/operator/decimal_cast_operators.hpp" +#include "duckdb/common/vector_operations/unary_executor.hpp" +#include "duckdb/common/vector_operations/vector_operations.hpp" +#include "duckdb/function/scalar/strftime_format.hpp" +#include "duckdb/main/appender.hpp" +#include "duckdb/main/database.hpp" +#include "duckdb/parser/column_definition.hpp" +#include "duckdb/storage/data_table.hpp" +#include "utf8proc_wrapper.hpp" +#include "utf8proc.hpp" +#include "duckdb/parser/keyword_helper.hpp" +#include "duckdb/main/error_manager.hpp" +#include "duckdb/execution/operator/persistent/parallel_csv_reader.hpp" +#include "duckdb/execution/operator/persistent/csv_rejects_table.hpp" +#include "duckdb/main/client_data.hpp" +#include +#include +#include +#include + +namespace duckdb { + +string BaseCSVReader::GetLineNumberStr(idx_t line_error, bool is_line_estimated, idx_t buffer_idx) { + // If an error happens during auto-detect it is an estimated line + string estimated = (is_line_estimated ? string(" (estimated)") : string("")); + return to_string(GetLineError(line_error, buffer_idx)) + estimated; +} + +BaseCSVReader::BaseCSVReader(ClientContext &context_p, BufferedCSVReaderOptions options_p, + const vector &requested_types) + : context(context_p), fs(FileSystem::GetFileSystem(context)), allocator(BufferAllocator::Get(context)), + options(std::move(options_p)) { +} + +BaseCSVReader::~BaseCSVReader() { +} + +unique_ptr BaseCSVReader::OpenCSV(const BufferedCSVReaderOptions &options_p) { + return CSVFileHandle::OpenFile(fs, allocator, options_p.file_path, options_p.compression, true); +} + +void BaseCSVReader::InitParseChunk(idx_t num_cols) { + // adapt not null info + if (options.force_not_null.size() != num_cols) { + options.force_not_null.resize(num_cols, false); + } + if (num_cols == parse_chunk.ColumnCount()) { + parse_chunk.Reset(); + } else { + parse_chunk.Destroy(); + + // initialize the parse_chunk with a set of VARCHAR types + vector varchar_types(num_cols, LogicalType::VARCHAR); + parse_chunk.Initialize(allocator, varchar_types); + } +} + +void BaseCSVReader::InitializeProjection() { + for (idx_t i = 0; i < GetTypes().size(); i++) { + reader_data.column_ids.push_back(i); + reader_data.column_mapping.push_back(i); + } +} + +void BaseCSVReader::SetDateFormat(const string &format_specifier, const LogicalTypeId &sql_type) { + options.has_format[sql_type] = true; + auto &date_format = options.date_format[sql_type]; + date_format.format_specifier = format_specifier; + StrTimeFormat::ParseFormatSpecifier(date_format.format_specifier, date_format); +} + +struct TryCastDecimalOperator { + template + static bool Operation(string_t input, uint8_t width, uint8_t scale) { + T result; + string error_message; + return OP::Operation(input, result, &error_message, width, scale); + } +}; + +struct TryCastFloatingOperator { + template + static bool Operation(string_t input) { + T result; + string error_message; + return OP::Operation(input, result, &error_message); + } +}; + +bool TryCastDecimalValueCommaSeparated(const string_t &value_str, const LogicalType &sql_type) { + auto width = DecimalType::GetWidth(sql_type); + auto scale = DecimalType::GetScale(sql_type); + switch (sql_type.InternalType()) { + case PhysicalType::INT16: + return TryCastDecimalOperator::Operation(value_str, width, scale); + case PhysicalType::INT32: + return TryCastDecimalOperator::Operation(value_str, width, scale); + case PhysicalType::INT64: + return TryCastDecimalOperator::Operation(value_str, width, scale); + case PhysicalType::INT128: + return TryCastDecimalOperator::Operation(value_str, width, scale); + default: + throw InternalException("Unimplemented physical type for decimal"); + } +} + +bool TryCastFloatingValueCommaSeparated(const string_t &value_str, const LogicalType &sql_type) { + switch (sql_type.InternalType()) { + case PhysicalType::DOUBLE: + return TryCastFloatingOperator::Operation(value_str); + case PhysicalType::FLOAT: + return TryCastFloatingOperator::Operation(value_str); + default: + throw InternalException("Unimplemented physical type for floating"); + } +} + +bool BaseCSVReader::TryCastValue(const Value &value, const LogicalType &sql_type) { + if (value.IsNull()) { + return true; + } + 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(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(StringValue::Get(value)), + result, error_message); + } else if (options.decimal_separator != "." && sql_type.id() == LogicalTypeId::DECIMAL) { + return TryCastDecimalValueCommaSeparated(string_t(StringValue::Get(value)), sql_type); + } else if (options.decimal_separator != "." && + ((sql_type.id() == LogicalTypeId::FLOAT) || (sql_type.id() == LogicalTypeId::DOUBLE))) { + return TryCastFloatingValueCommaSeparated(string_t(StringValue::Get(value)), sql_type); + } else { + Value new_value; + string error_message; + return value.TryCastAs(context, sql_type, new_value, &error_message, true); + } +} + +struct TryCastDateOperator { + static bool Operation(BufferedCSVReaderOptions &options, string_t input, date_t &result, string &error_message) { + return options.date_format[LogicalTypeId::DATE].TryParseDate(input, result, error_message); + } +}; + +struct TryCastTimestampOperator { + static bool Operation(BufferedCSVReaderOptions &options, string_t input, timestamp_t &result, + string &error_message) { + return options.date_format[LogicalTypeId::TIMESTAMP].TryParseTimestamp(input, result, error_message); + } +}; + +template +static bool TemplatedTryCastDateVector(BufferedCSVReaderOptions &options, Vector &input_vector, Vector &result_vector, + idx_t count, string &error_message, idx_t &line_error) { + D_ASSERT(input_vector.GetType().id() == LogicalTypeId::VARCHAR); + bool all_converted = true; + idx_t cur_line = 0; + UnaryExecutor::Execute(input_vector, result_vector, count, [&](string_t input) { + T result; + if (!OP::Operation(options, input, result, error_message)) { + line_error = cur_line; + all_converted = false; + } + cur_line++; + return result; + }); + return all_converted; +} + +bool TryCastDateVector(BufferedCSVReaderOptions &options, Vector &input_vector, Vector &result_vector, idx_t count, + string &error_message, idx_t &line_error) { + return TemplatedTryCastDateVector(options, input_vector, result_vector, count, + error_message, line_error); +} + +bool TryCastTimestampVector(BufferedCSVReaderOptions &options, Vector &input_vector, Vector &result_vector, idx_t count, + string &error_message) { + idx_t line_error; + return TemplatedTryCastDateVector(options, input_vector, result_vector, + count, error_message, line_error); +} + +template +bool TemplatedTryCastFloatingVector(BufferedCSVReaderOptions &options, Vector &input_vector, Vector &result_vector, + idx_t count, string &error_message, idx_t &line_error) { + D_ASSERT(input_vector.GetType().id() == LogicalTypeId::VARCHAR); + bool all_converted = true; + idx_t row = 0; + UnaryExecutor::Execute(input_vector, result_vector, count, [&](string_t input) { + T result; + if (!OP::Operation(input, result, &error_message)) { + line_error = row; + all_converted = false; + } else { + row++; + } + return result; + }); + return all_converted; +} + +template +bool TemplatedTryCastDecimalVector(BufferedCSVReaderOptions &options, Vector &input_vector, Vector &result_vector, + idx_t count, string &error_message, uint8_t width, uint8_t scale) { + D_ASSERT(input_vector.GetType().id() == LogicalTypeId::VARCHAR); + bool all_converted = true; + UnaryExecutor::Execute(input_vector, result_vector, count, [&](string_t input) { + T result; + if (!OP::Operation(input, result, &error_message, width, scale)) { + all_converted = false; + } + return result; + }); + return all_converted; +} + +bool BaseCSVReader::TryCastVector(Vector &parse_chunk_col, idx_t size, const LogicalType &sql_type) { + // try vector-cast from string to sql_type + Vector dummy_result(sql_type); + if (options.has_format[LogicalTypeId::DATE] && sql_type == LogicalTypeId::DATE) { + // use the date format to cast the chunk + string error_message; + idx_t line_error; + return TryCastDateVector(options, parse_chunk_col, dummy_result, size, error_message, line_error); + } else if (options.has_format[LogicalTypeId::TIMESTAMP] && sql_type == LogicalTypeId::TIMESTAMP) { + // use the timestamp format to cast the chunk + string error_message; + return TryCastTimestampVector(options, parse_chunk_col, dummy_result, size, error_message); + } else { + // target type is not varchar: perform a cast + string error_message; + return VectorOperations::DefaultTryCast(parse_chunk_col, dummy_result, size, &error_message, true); + } +} + +void BaseCSVReader::AddValue(string_t str_val, idx_t &column, vector &escape_positions, bool has_quotes, + idx_t buffer_idx) { + auto length = str_val.GetSize(); + if (length == 0 && column == 0) { + row_empty = true; + } else { + row_empty = false; + } + if (!return_types.empty() && column == return_types.size() && length == 0) { + // skip a single trailing delimiter in last column + return; + } + if (mode == ParserMode::SNIFFING_DIALECT) { + column++; + return; + } + if (column >= return_types.size()) { + if (options.ignore_errors) { + error_column_overflow = true; + return; + } else { + throw InvalidInputException( + "Error in file \"%s\", on line %s: expected %lld values per row, but got more. (%s)", options.file_path, + GetLineNumberStr(linenr, linenr_estimated, buffer_idx).c_str(), return_types.size(), + options.ToString()); + } + } + + // insert the line number into the chunk + idx_t row_entry = parse_chunk.size(); + + // test against null string, but only if the value was not quoted + if ((!(has_quotes && !options.allow_quoted_nulls) || return_types[column].id() != LogicalTypeId::VARCHAR) && + !options.force_not_null[column] && Equals::Operation(str_val, string_t(options.null_str))) { + FlatVector::SetNull(parse_chunk.data[column], row_entry, true); + } else { + auto &v = parse_chunk.data[column]; + auto parse_data = FlatVector::GetData(v); + if (!escape_positions.empty()) { + // remove escape characters (if any) + string old_val = str_val.GetString(); + string new_val = ""; + idx_t prev_pos = 0; + for (idx_t i = 0; i < escape_positions.size(); i++) { + idx_t next_pos = escape_positions[i]; + new_val += old_val.substr(prev_pos, next_pos - prev_pos); + + if (options.escape.empty() || options.escape == options.quote) { + prev_pos = next_pos + options.quote.size(); + } else { + prev_pos = next_pos + options.escape.size(); + } + } + new_val += old_val.substr(prev_pos, old_val.size() - prev_pos); + escape_positions.clear(); + parse_data[row_entry] = StringVector::AddStringOrBlob(v, string_t(new_val)); + } else { + parse_data[row_entry] = str_val; + } + } + + // move to the next column + column++; +} + +bool BaseCSVReader::AddRow(DataChunk &insert_chunk, idx_t &column, string &error_message, idx_t buffer_idx) { + linenr++; + + if (row_empty) { + row_empty = false; + if (return_types.size() != 1) { + if (mode == ParserMode::PARSING) { + FlatVector::SetNull(parse_chunk.data[0], parse_chunk.size(), false); + } + column = 0; + return false; + } + } + + // Error forwarded by 'ignore_errors' - originally encountered in 'AddValue' + if (error_column_overflow) { + D_ASSERT(options.ignore_errors); + error_column_overflow = false; + column = 0; + return false; + } + + if (column < return_types.size() && mode != ParserMode::SNIFFING_DIALECT) { + if (options.null_padding) { + for (; column < return_types.size(); column++) { + FlatVector::SetNull(parse_chunk.data[column], parse_chunk.size(), true); + } + } else if (options.ignore_errors) { + column = 0; + return false; + } else { + if (mode == ParserMode::SNIFFING_DATATYPES) { + error_message = "Error when adding line"; + return false; + } else { + throw InvalidInputException( + "Error in file \"%s\" on line %s: expected %lld values per row, but got %d.\nParser options:\n%s", + options.file_path, GetLineNumberStr(linenr, linenr_estimated, buffer_idx).c_str(), + return_types.size(), column, options.ToString()); + } + } + } + + if (mode == ParserMode::SNIFFING_DIALECT) { + sniffed_column_counts.push_back(column); + + if (sniffed_column_counts.size() == options.sample_chunk_size) { + return true; + } + } else { + parse_chunk.SetCardinality(parse_chunk.size() + 1); + } + + if (mode == ParserMode::PARSING_HEADER) { + return true; + } + + if (mode == ParserMode::SNIFFING_DATATYPES && parse_chunk.size() == options.sample_chunk_size) { + return true; + } + + if (mode == ParserMode::PARSING && parse_chunk.size() == STANDARD_VECTOR_SIZE) { + Flush(insert_chunk, buffer_idx); + return true; + } + + column = 0; + return false; +} + +void BaseCSVReader::VerifyUTF8(idx_t col_idx, idx_t row_idx, DataChunk &chunk, int64_t offset) { + D_ASSERT(col_idx < chunk.data.size()); + D_ASSERT(row_idx < chunk.size()); + auto &v = chunk.data[col_idx]; + if (FlatVector::IsNull(v, row_idx)) { + return; + } + + auto parse_data = FlatVector::GetData(chunk.data[col_idx]); + auto s = parse_data[row_idx]; + auto utf_type = Utf8Proc::Analyze(s.GetData(), s.GetSize()); + if (utf_type == UnicodeType::INVALID) { + string col_name = to_string(col_idx); + if (col_idx < names.size()) { + col_name = "\"" + names[col_idx] + "\""; + } + int64_t error_line = linenr - (chunk.size() - row_idx) + 1 + offset; + D_ASSERT(error_line >= 0); + throw InvalidInputException("Error in file \"%s\" at line %llu in column \"%s\": " + "%s. Parser options:\n%s", + options.file_path, error_line, col_name, + ErrorManager::InvalidUnicodeError(s.GetString(), "CSV file"), options.ToString()); + } +} + +void BaseCSVReader::VerifyUTF8(idx_t col_idx) { + D_ASSERT(col_idx < parse_chunk.data.size()); + for (idx_t i = 0; i < parse_chunk.size(); i++) { + VerifyUTF8(col_idx, i, parse_chunk); + } +} + +bool TryCastDecimalVectorCommaSeparated(BufferedCSVReaderOptions &options, Vector &input_vector, Vector &result_vector, + idx_t count, string &error_message, const LogicalType &result_type) { + auto width = DecimalType::GetWidth(result_type); + auto scale = DecimalType::GetScale(result_type); + switch (result_type.InternalType()) { + case PhysicalType::INT16: + return TemplatedTryCastDecimalVector( + options, input_vector, result_vector, count, error_message, width, scale); + case PhysicalType::INT32: + return TemplatedTryCastDecimalVector( + options, input_vector, result_vector, count, error_message, width, scale); + case PhysicalType::INT64: + return TemplatedTryCastDecimalVector( + options, input_vector, result_vector, count, error_message, width, scale); + case PhysicalType::INT128: + return TemplatedTryCastDecimalVector( + options, input_vector, result_vector, count, error_message, width, scale); + default: + throw InternalException("Unimplemented physical type for decimal"); + } +} + +bool TryCastFloatingVectorCommaSeparated(BufferedCSVReaderOptions &options, Vector &input_vector, Vector &result_vector, + idx_t count, string &error_message, const LogicalType &result_type, + idx_t &line_error) { + switch (result_type.InternalType()) { + case PhysicalType::DOUBLE: + return TemplatedTryCastFloatingVector( + options, input_vector, result_vector, count, error_message, line_error); + case PhysicalType::FLOAT: + return TemplatedTryCastFloatingVector( + options, input_vector, result_vector, count, error_message, line_error); + default: + throw InternalException("Unimplemented physical type for floating"); + } +} + +// Location of erroneous value in the current parse chunk +struct ErrorLocation { + idx_t row_idx; + idx_t col_idx; + idx_t row_line; + + ErrorLocation(idx_t row_idx, idx_t col_idx, idx_t row_line) + : row_idx(row_idx), col_idx(col_idx), row_line(row_line) { + } +}; + +bool BaseCSVReader::Flush(DataChunk &insert_chunk, idx_t buffer_idx, bool try_add_line) { + if (parse_chunk.size() == 0) { + return true; + } + + bool conversion_error_ignored = false; + + // convert the columns in the parsed chunk to the types of the table + insert_chunk.SetCardinality(parse_chunk); + if (reader_data.column_ids.empty() && !reader_data.empty_columns) { + throw InternalException("BaseCSVReader::Flush called on a CSV reader that was not correctly initialized. Call " + "MultiFileReader::InitializeReader or InitializeProjection"); + } + D_ASSERT(reader_data.column_ids.size() == reader_data.column_mapping.size()); + for (idx_t c = 0; c < reader_data.column_ids.size(); c++) { + auto col_idx = reader_data.column_ids[c]; + auto result_idx = reader_data.column_mapping[c]; + auto &parse_vector = parse_chunk.data[col_idx]; + auto &result_vector = insert_chunk.data[result_idx]; + auto &type = result_vector.GetType(); + if (type.id() == LogicalTypeId::VARCHAR) { + // target type is varchar: no need to convert + // just test that all strings are valid utf-8 strings + VerifyUTF8(col_idx); + // reinterpret rather than reference so we can deal with user-defined types + result_vector.Reinterpret(parse_vector); + } else { + string error_message; + bool success; + idx_t line_error = 0; + bool target_type_not_varchar = false; + if (options.has_format[LogicalTypeId::DATE] && type.id() == LogicalTypeId::DATE) { + // use the date format to cast the chunk + success = TryCastDateVector(options, parse_vector, result_vector, parse_chunk.size(), error_message, + line_error); + } else if (options.has_format[LogicalTypeId::TIMESTAMP] && type.id() == LogicalTypeId::TIMESTAMP) { + // use the date format to cast the chunk + success = + TryCastTimestampVector(options, parse_vector, result_vector, parse_chunk.size(), error_message); + } else if (options.decimal_separator != "." && + (type.id() == LogicalTypeId::FLOAT || type.id() == LogicalTypeId::DOUBLE)) { + success = TryCastFloatingVectorCommaSeparated(options, parse_vector, result_vector, parse_chunk.size(), + error_message, type, line_error); + } else if (options.decimal_separator != "." && type.id() == LogicalTypeId::DECIMAL) { + success = TryCastDecimalVectorCommaSeparated(options, parse_vector, result_vector, parse_chunk.size(), + error_message, type); + } else { + // target type is not varchar: perform a cast + target_type_not_varchar = true; + success = + VectorOperations::TryCast(context, parse_vector, result_vector, parse_chunk.size(), &error_message); + } + if (success) { + continue; + } + if (try_add_line) { + return false; + } + + string col_name = to_string(col_idx); + if (col_idx < names.size()) { + col_name = "\"" + names[col_idx] + "\""; + } + + // figure out the exact line number + if (target_type_not_varchar) { + UnifiedVectorFormat inserted_column_data; + result_vector.ToUnifiedFormat(parse_chunk.size(), inserted_column_data); + for (; line_error < parse_chunk.size(); line_error++) { + if (!inserted_column_data.validity.RowIsValid(line_error) && + !FlatVector::IsNull(parse_vector, line_error)) { + break; + } + } + } + + // The line_error must be summed with linenr (All lines emmited from this batch) + // But subtracted from the parse_chunk + D_ASSERT(line_error + linenr >= parse_chunk.size()); + line_error += linenr; + line_error -= parse_chunk.size(); + + auto error_line = GetLineError(line_error, buffer_idx); + + if (options.ignore_errors) { + conversion_error_ignored = true; + + } else if (options.auto_detect) { + throw InvalidInputException("%s in column %s, at line %llu.\n\nParser " + "options:\n%s.\n\nConsider either increasing the sample size " + "(SAMPLE_SIZE=X [X rows] or SAMPLE_SIZE=-1 [all rows]), " + "or skipping column conversion (ALL_VARCHAR=1)", + error_message, col_name, error_line, options.ToString()); + } else { + throw InvalidInputException("%s at line %llu in column %s. Parser options:\n%s ", error_message, + error_line, col_name, options.ToString()); + } + } + } + if (conversion_error_ignored) { + D_ASSERT(options.ignore_errors); + + SelectionVector succesful_rows(parse_chunk.size()); + idx_t sel_size = 0; + + // Keep track of failed cells + vector failed_cells; + + for (idx_t row_idx = 0; row_idx < parse_chunk.size(); row_idx++) { + + auto global_row_idx = row_idx + linenr - parse_chunk.size(); + auto row_line = GetLineError(global_row_idx, buffer_idx, false); + + bool row_failed = false; + for (idx_t c = 0; c < reader_data.column_ids.size(); c++) { + auto col_idx = reader_data.column_ids[c]; + auto result_idx = reader_data.column_mapping[c]; + + auto &parse_vector = parse_chunk.data[col_idx]; + auto &result_vector = insert_chunk.data[result_idx]; + + bool was_already_null = FlatVector::IsNull(parse_vector, row_idx); + if (!was_already_null && FlatVector::IsNull(result_vector, row_idx)) { + row_failed = true; + failed_cells.emplace_back(row_idx, col_idx, row_line); + } + } + if (!row_failed) { + succesful_rows.set_index(sel_size++, row_idx); + } + } + + // Now do a second pass to produce the reject table entries + if (!failed_cells.empty() && !options.rejects_table_name.empty()) { + auto limit = options.rejects_limit; + + auto rejects = CSVRejectsTable::GetOrCreate(context, options.rejects_table_name); + lock_guard lock(rejects->write_lock); + + // short circuit if we already have too many rejects + if (limit == 0 || rejects->count < limit) { + auto &table = rejects->GetTable(context); + InternalAppender appender(context, table); + auto file_name = GetFileName(); + + for (auto &cell : failed_cells) { + if (limit != 0 && rejects->count >= limit) { + break; + } + rejects->count++; + + auto row_idx = cell.row_idx; + auto col_idx = cell.col_idx; + auto row_line = cell.row_line; + + auto col_name = to_string(col_idx); + if (col_idx < names.size()) { + col_name = "\"" + names[col_idx] + "\""; + } + + auto &parse_vector = parse_chunk.data[col_idx]; + auto parsed_str = FlatVector::GetData(parse_vector)[row_idx]; + auto &type = insert_chunk.data[col_idx].GetType(); + auto row_error_msg = StringUtil::Format("Could not convert string '%s' to '%s'", + parsed_str.GetString(), type.ToString()); + + // Add the row to the rejects table + appender.BeginRow(); + appender.Append(string_t(file_name)); + appender.Append(row_line); + appender.Append(col_idx); + appender.Append(string_t(col_name)); + appender.Append(parsed_str); + + if (!options.rejects_recovery_columns.empty()) { + child_list_t recovery_key; + for (auto &key_idx : options.rejects_recovery_column_ids) { + // Figure out if the recovery key is valid. + // If not, error out for real. + auto &component_vector = parse_chunk.data[key_idx]; + if (FlatVector::IsNull(component_vector, row_idx)) { + throw InvalidInputException("%s at line %llu in column %s. Parser options:\n%s ", + "Could not parse recovery column", row_line, col_name, + options.ToString()); + } + auto component = Value(FlatVector::GetData(component_vector)[row_idx]); + recovery_key.emplace_back(names[key_idx], component); + } + appender.Append(Value::STRUCT(recovery_key)); + } + + appender.Append(string_t(row_error_msg)); + appender.EndRow(); + } + appender.Close(); + } + } + + // Now slice the insert chunk to only include the succesful rows + insert_chunk.Slice(succesful_rows, sel_size); + } + parse_chunk.Reset(); + return true; +} + +void BaseCSVReader::SetNewLineDelimiter(bool carry, bool carry_followed_by_nl) { + if ((mode == ParserMode::SNIFFING_DIALECT && !options.has_newline) || + options.new_line == NewLineIdentifier::NOT_SET) { + if (options.new_line == NewLineIdentifier::MIX) { + return; + } + NewLineIdentifier this_line_identifier; + if (carry) { + if (carry_followed_by_nl) { + this_line_identifier = NewLineIdentifier::CARRY_ON; + } else { + this_line_identifier = NewLineIdentifier::SINGLE; + } + } else { + this_line_identifier = NewLineIdentifier::SINGLE; + } + if (options.new_line == NewLineIdentifier::NOT_SET) { + options.new_line = this_line_identifier; + return; + } + if (options.new_line != this_line_identifier) { + options.new_line = NewLineIdentifier::MIX; + return; + } + options.new_line = this_line_identifier; + } +} +} // namespace duckdb diff --git a/src/duckdb/src/execution/operator/persistent/buffered_csv_reader.cpp b/src/duckdb/src/execution/operator/persistent/buffered_csv_reader.cpp new file mode 100644 index 00000000..d8ac2b97 --- /dev/null +++ b/src/duckdb/src/execution/operator/persistent/buffered_csv_reader.cpp @@ -0,0 +1,1487 @@ +#include "duckdb/execution/operator/persistent/buffered_csv_reader.hpp" + +#include "duckdb/catalog/catalog_entry/table_catalog_entry.hpp" +#include "duckdb/common/file_system.hpp" +#include "duckdb/common/string_util.hpp" +#include "duckdb/common/to_string.hpp" +#include "duckdb/common/types/cast_helpers.hpp" +#include "duckdb/common/vector_operations/unary_executor.hpp" +#include "duckdb/common/vector_operations/vector_operations.hpp" +#include "duckdb/function/scalar/strftime_format.hpp" +#include "duckdb/main/database.hpp" +#include "duckdb/parser/column_definition.hpp" +#include "duckdb/storage/data_table.hpp" +#include "utf8proc_wrapper.hpp" +#include "utf8proc.hpp" +#include "duckdb/parser/keyword_helper.hpp" +#include "duckdb/main/error_manager.hpp" +#include "duckdb/main/client_data.hpp" + +#include +#include +#include +#include + +namespace duckdb { + +BufferedCSVReader::BufferedCSVReader(ClientContext &context, BufferedCSVReaderOptions options_p, + const vector &requested_types) + : BaseCSVReader(context, std::move(options_p), requested_types), buffer_size(0), position(0), start(0) { + file_handle = OpenCSV(options); + Initialize(requested_types); +} + +BufferedCSVReader::BufferedCSVReader(ClientContext &context, string filename, BufferedCSVReaderOptions options_p, + const vector &requested_types) + : BaseCSVReader(context, std::move(options_p), requested_types), buffer_size(0), position(0), start(0) { + options.file_path = std::move(filename); + file_handle = OpenCSV(options); + Initialize(requested_types); +} + +enum class QuoteRule : uint8_t { QUOTES_RFC = 0, QUOTES_OTHER = 1, NO_QUOTES = 2 }; + +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); + if (field1 == end) { + return false; + } + + // first numeric field must start immediately + if (!StringUtil::CharacterIsDigit(*field1)) { + return false; + } + auto literal1 = std::find_if_not(field1, end, StringUtil::CharacterIsDigit); + if (literal1 == end) { + return false; + } + + // second numeric field must exist + auto field2 = std::find_if(literal1, end, StringUtil::CharacterIsDigit); + if (field2 == end) { + return false; + } + auto literal2 = std::find_if_not(field2, end, StringUtil::CharacterIsDigit); + if (literal2 == end) { + return false; + } + + // third numeric field must exist + auto field3 = std::find_if(literal2, end, StringUtil::CharacterIsDigit); + if (field3 == end) { + return false; + } + + // second literal must match first + if (((field3 - literal2) != (field2 - literal1)) || strncmp(literal1, literal2, (field2 - literal1)) != 0) { + return false; + } + + // copy the literal as the separator, escaping percent signs + separator.clear(); + while (literal1 < field2) { + const auto literal_char = *literal1++; + if (literal_char == '%') { + separator.push_back(literal_char); + } + separator.push_back(literal_char); + } + + return true; +} + +string GenerateDateFormat(const string &separator, const char *format_template) { + string format_specifier = format_template; + auto amount_of_dashes = std::count(format_specifier.begin(), format_specifier.end(), '-'); + if (!amount_of_dashes) { + return format_specifier; + } + string result; + result.reserve(format_specifier.size() - amount_of_dashes + (amount_of_dashes * separator.size())); + for (auto &character : format_specifier) { + if (character == '-') { + result += separator; + } else { + result += character; + } + } + return result; +} + +TextSearchShiftArray::TextSearchShiftArray() { +} + +TextSearchShiftArray::TextSearchShiftArray(string search_term) : length(search_term.size()) { + if (length > 255) { + throw InvalidInputException("Size of delimiter/quote/escape in CSV reader is limited to 255 bytes"); + } + // initialize the shifts array + shifts = unique_ptr(new uint8_t[length * 255]); + memset(shifts.get(), 0, length * 255 * sizeof(uint8_t)); + // iterate over each of the characters in the array + for (idx_t main_idx = 0; main_idx < length; main_idx++) { + uint8_t current_char = (uint8_t)search_term[main_idx]; + // now move over all the remaining positions + for (idx_t i = main_idx; i < length; i++) { + bool is_match = true; + // check if the prefix matches at this position + // if it does, we move to this position after encountering the current character + for (idx_t j = 0; j < main_idx; j++) { + if (search_term[i - main_idx + j] != search_term[j]) { + is_match = false; + } + } + if (!is_match) { + continue; + } + shifts[i * 255 + current_char] = main_idx + 1; + } + } +} + +// Helper function to generate column names +static string GenerateColumnName(const idx_t total_cols, const idx_t col_number, const string &prefix = "column") { + int max_digits = NumericHelper::UnsignedLength(total_cols - 1); + int digits = NumericHelper::UnsignedLength(col_number); + string leading_zeros = string(max_digits - digits, '0'); + string value = to_string(col_number); + return string(prefix + leading_zeros + value); +} + +// Helper function for UTF-8 aware space trimming +static string TrimWhitespace(const string &col_name) { + utf8proc_int32_t codepoint; + auto str = reinterpret_cast(col_name.c_str()); + idx_t size = col_name.size(); + // Find the first character that is not left trimmed + idx_t begin = 0; + while (begin < size) { + auto bytes = utf8proc_iterate(str + begin, size - begin, &codepoint); + D_ASSERT(bytes > 0); + if (utf8proc_category(codepoint) != UTF8PROC_CATEGORY_ZS) { + break; + } + begin += bytes; + } + + // Find the last character that is not right trimmed + idx_t end; + end = begin; + for (auto next = begin; next < col_name.size();) { + auto bytes = utf8proc_iterate(str + next, size - next, &codepoint); + D_ASSERT(bytes > 0); + next += bytes; + if (utf8proc_category(codepoint) != UTF8PROC_CATEGORY_ZS) { + end = next; + } + } + + // return the trimmed string + return col_name.substr(begin, end - begin); +} + +static string NormalizeColumnName(const string &col_name) { + // normalize UTF8 characters to NFKD + auto nfkd = utf8proc_NFKD(reinterpret_cast(col_name.c_str()), col_name.size()); + const string col_name_nfkd = string(const_char_ptr_cast(nfkd), strlen(const_char_ptr_cast(nfkd))); + free(nfkd); + + // only keep ASCII characters 0-9 a-z A-Z and replace spaces with regular whitespace + string col_name_ascii = ""; + for (idx_t i = 0; i < col_name_nfkd.size(); i++) { + if (col_name_nfkd[i] == '_' || (col_name_nfkd[i] >= '0' && col_name_nfkd[i] <= '9') || + (col_name_nfkd[i] >= 'A' && col_name_nfkd[i] <= 'Z') || + (col_name_nfkd[i] >= 'a' && col_name_nfkd[i] <= 'z')) { + col_name_ascii += col_name_nfkd[i]; + } else if (StringUtil::CharacterIsSpace(col_name_nfkd[i])) { + col_name_ascii += " "; + } + } + + // trim whitespace and replace remaining whitespace by _ + string col_name_trimmed = TrimWhitespace(col_name_ascii); + string col_name_cleaned = ""; + bool in_whitespace = false; + for (idx_t i = 0; i < col_name_trimmed.size(); i++) { + if (col_name_trimmed[i] == ' ') { + if (!in_whitespace) { + col_name_cleaned += "_"; + in_whitespace = true; + } + } else { + col_name_cleaned += col_name_trimmed[i]; + in_whitespace = false; + } + } + + // don't leave string empty; if not empty, make lowercase + if (col_name_cleaned.empty()) { + col_name_cleaned = "_"; + } else { + col_name_cleaned = StringUtil::Lower(col_name_cleaned); + } + + // prepend _ if name starts with a digit or is a reserved keyword + if (KeywordHelper::IsKeyword(col_name_cleaned) || (col_name_cleaned[0] >= '0' && col_name_cleaned[0] <= '9')) { + col_name_cleaned = "_" + col_name_cleaned; + } + return col_name_cleaned; +} + +void BufferedCSVReader::Initialize(const vector &requested_types) { + PrepareComplexParser(); + if (options.auto_detect) { + return_types = SniffCSV(requested_types); + if (return_types.empty()) { + throw InvalidInputException("Failed to detect column types from CSV: is the file a valid CSV file?"); + } + JumpToBeginning(options.skip_rows, options.header); + } else { + return_types = requested_types; + ResetBuffer(); + SkipRowsAndReadHeader(options.skip_rows, options.header); + } + InitParseChunk(return_types.size()); +} + +void BufferedCSVReader::ResetBuffer() { + buffer.reset(); + buffer_size = 0; + position = 0; + start = 0; + cached_buffers.clear(); +} + +void BufferedCSVReader::ResetStream() { + file_handle->Reset(); + linenr = 0; + linenr_estimated = false; + bytes_per_line_avg = 0; + sample_chunk_idx = 0; + jumping_samples = false; +} + +void BufferedCSVReader::JumpToBeginning(idx_t skip_rows = 0, bool skip_header = false) { + ResetBuffer(); + ResetStream(); + 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) { + for (idx_t i = 0; i < skip_rows; i++) { + // ignore skip rows + string read_line = file_handle->ReadLine(); + linenr++; + } + + if (skip_header) { + // ignore the first line as a header line + InitParseChunk(return_types.size()); + ParseCSV(ParserMode::PARSING_HEADER); + } +} + +void BufferedCSVReader::PrepareComplexParser() { + delimiter_search = TextSearchShiftArray(options.delimiter); + escape_search = TextSearchShiftArray(options.escape); + quote_search = TextSearchShiftArray(options.quote); +} + +bool BufferedCSVReader::JumpToNextSample() { + // get bytes contained in the previously read chunk + idx_t remaining_bytes_in_buffer = buffer_size - start; + bytes_in_chunk -= remaining_bytes_in_buffer; + if (remaining_bytes_in_buffer == 0) { + return false; + } + + // 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_handle->FileSize() / (double)bytes_first_chunk); + jumping_samples = chunks_fit >= options.sample_chunks; + + // jump back to the beginning + JumpToBeginning(options.skip_rows, options.header); + sample_chunk_idx++; + return true; + } + + if (end_of_file_reached || sample_chunk_idx >= options.sample_chunks) { + return false; + } + + // 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 (!file_handle->OnDiskFile() || !jumping_samples) { + sample_chunk_idx++; + return true; + } + + // update average bytes per line + double bytes_per_line = bytes_in_chunk / (double)options.sample_chunk_size; + 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_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_handle->FileSize()) { + // set position in stream and clear failure bits + file_handle->Seek(current_pos + offset); + + // estimate linenr + linenr += (idx_t)round((offset + remaining_bytes_in_buffer) / bytes_per_line_avg); + linenr_estimated = true; + } else { + // 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_handle->FileSize() - bytes_in_chunk); + + // estimate linenr + linenr = (idx_t)round((file_handle->FileSize() - bytes_in_chunk) / bytes_per_line_avg); + linenr_estimated = true; + } + + // reset buffers and parse chunk + ResetBuffer(); + + // seek beginning of next line + // FIXME: if this jump ends up in a quoted linebreak, we will have a problem + string read_line = file_handle->ReadLine(); + linenr++; + + sample_chunk_idx++; + + return true; +} + +void BufferedCSVReader::DetectDialect(const vector &requested_types, + BufferedCSVReaderOptions &original_options, + vector &info_candidates, idx_t &best_num_cols) { + // set up the candidates we consider for delimiter and quote rules based on user input + vector delim_candidates; + vector quoterule_candidates; + vector> quote_candidates_map; + vector> escape_candidates_map = {{""}, {"\\"}, {""}}; + + if (options.has_delimiter) { + // user provided a delimiter: use that delimiter + delim_candidates = {options.delimiter}; + } else { + // no delimiter provided: try standard/common delimiters + delim_candidates = {",", "|", ";", "\t"}; + } + if (options.has_quote) { + // user provided quote: use that quote rule + quote_candidates_map = {{options.quote}, {options.quote}, {options.quote}}; + } else { + // no quote rule provided: use standard/common quotes + quote_candidates_map = {{"\""}, {"\"", "'"}, {""}}; + } + if (options.has_escape) { + // user provided escape: use that escape rule + if (options.escape.empty()) { + quoterule_candidates = {QuoteRule::QUOTES_RFC}; + } else { + quoterule_candidates = {QuoteRule::QUOTES_OTHER}; + } + escape_candidates_map[static_cast(quoterule_candidates[0])] = {options.escape}; + } else { + // no escape provided: try standard/common escapes + quoterule_candidates = {QuoteRule::QUOTES_RFC, QuoteRule::QUOTES_OTHER, QuoteRule::NO_QUOTES}; + } + + idx_t best_consistent_rows = 0; + idx_t prev_padding_count = 0; + for (auto quoterule : quoterule_candidates) { + const auto "e_candidates = quote_candidates_map[static_cast(quoterule)]; + for (const auto "e : quote_candidates) { + for (const auto &delim : delim_candidates) { + const auto &escape_candidates = escape_candidates_map[static_cast(quoterule)]; + for (const auto &escape : escape_candidates) { + BufferedCSVReaderOptions sniff_info = original_options; + sniff_info.delimiter = delim; + sniff_info.quote = quote; + sniff_info.escape = escape; + + options = sniff_info; + PrepareComplexParser(); + + JumpToBeginning(original_options.skip_rows); + sniffed_column_counts.clear(); + if (!TryParseCSV(ParserMode::SNIFFING_DIALECT)) { + continue; + } + + idx_t start_row = original_options.skip_rows; + idx_t consistent_rows = 0; + idx_t num_cols = sniffed_column_counts.empty() ? 0 : sniffed_column_counts[0]; + idx_t padding_count = 0; + bool allow_padding = original_options.null_padding; + for (idx_t row = 0; row < sniffed_column_counts.size(); row++) { + if (sniffed_column_counts[row] == num_cols) { + consistent_rows++; + } else if (num_cols < sniffed_column_counts[row] && !original_options.skip_rows_set) { + // we use the maximum amount of num_cols that we find + num_cols = sniffed_column_counts[row]; + start_row = row + original_options.skip_rows; + consistent_rows = 1; + padding_count = 0; + } else if (num_cols >= sniffed_column_counts[row] && allow_padding) { + // we are missing some columns, we can parse this as long as we add padding + padding_count++; + } + } + + // some logic + consistent_rows += padding_count; + bool more_values = (consistent_rows > best_consistent_rows && num_cols >= best_num_cols); + bool require_more_padding = padding_count > prev_padding_count; + bool require_less_padding = padding_count < prev_padding_count; + bool single_column_before = best_num_cols < 2 && num_cols > best_num_cols; + bool rows_consistent = + start_row + consistent_rows - original_options.skip_rows == sniffed_column_counts.size(); + bool more_than_one_row = (consistent_rows > 1); + bool more_than_one_column = (num_cols > 1); + bool start_good = !info_candidates.empty() && (start_row <= info_candidates.front().skip_rows); + + if (!requested_types.empty() && requested_types.size() != num_cols) { + continue; + } else if (rows_consistent && (single_column_before || (more_values && !require_more_padding) || + (more_than_one_column && require_less_padding))) { + sniff_info.skip_rows = start_row; + sniff_info.num_cols = num_cols; + sniff_info.new_line = options.new_line; + best_consistent_rows = consistent_rows; + best_num_cols = num_cols; + prev_padding_count = padding_count; + + info_candidates.clear(); + info_candidates.push_back(sniff_info); + } else if (more_than_one_row && more_than_one_column && start_good && rows_consistent && + !require_more_padding) { + bool same_quote_is_candidate = false; + for (auto &info_candidate : info_candidates) { + if (quote.compare(info_candidate.quote) == 0) { + same_quote_is_candidate = true; + } + } + if (!same_quote_is_candidate) { + sniff_info.skip_rows = start_row; + sniff_info.num_cols = num_cols; + sniff_info.new_line = options.new_line; + info_candidates.push_back(sniff_info); + } + } + } + } + } + } +} + +void BufferedCSVReader::DetectCandidateTypes(const vector &type_candidates, + const map> &format_template_candidates, + const vector &info_candidates, + BufferedCSVReaderOptions &original_options, idx_t best_num_cols, + vector> &best_sql_types_candidates, + std::map> &best_format_candidates, + DataChunk &best_header_row) { + BufferedCSVReaderOptions best_options; + idx_t min_varchar_cols = best_num_cols + 1; + + // check which info candidate leads to minimum amount of non-varchar columns... + for (const auto &t : format_template_candidates) { + best_format_candidates[t.first].clear(); + } + for (auto &info_candidate : info_candidates) { + options = info_candidate; + vector> info_sql_types_candidates(options.num_cols, type_candidates); + std::map has_format_candidates; + std::map> format_candidates; + for (const auto &t : format_template_candidates) { + has_format_candidates[t.first] = false; + format_candidates[t.first].clear(); + } + + // set all return_types to VARCHAR so we can do datatype detection based on VARCHAR values + return_types.clear(); + return_types.assign(options.num_cols, LogicalType::VARCHAR); + + // jump to beginning and skip potential header + JumpToBeginning(options.skip_rows, true); + DataChunk header_row; + header_row.Initialize(allocator, return_types); + parse_chunk.Copy(header_row); + + if (header_row.size() == 0) { + continue; + } + + // init parse chunk and read csv with info candidate + InitParseChunk(return_types.size()); + if (!TryParseCSV(ParserMode::SNIFFING_DATATYPES)) { + continue; + } + for (idx_t row_idx = 0; row_idx <= parse_chunk.size(); row_idx++) { + bool is_header_row = row_idx == 0; + idx_t row = row_idx - 1; + for (idx_t col = 0; col < parse_chunk.ColumnCount(); col++) { + auto &col_type_candidates = info_sql_types_candidates[col]; + while (col_type_candidates.size() > 1) { + const auto &sql_type = col_type_candidates.back(); + // try cast from string to sql_type + Value dummy_val; + if (is_header_row) { + VerifyUTF8(col, 0, header_row, -int64_t(parse_chunk.size())); + dummy_val = header_row.GetValue(col, 0); + } else { + VerifyUTF8(col, row, parse_chunk); + dummy_val = parse_chunk.GetValue(col, row); + } + // 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()] && + !dummy_val.IsNull() && 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()]; + if (!has_format_candidates[sql_type.id()]) { + has_format_candidates[sql_type.id()] = true; + // order by preference + auto entry = format_template_candidates.find(sql_type.id()); + if (entry != format_template_candidates.end()) { + const auto &format_template_list = entry->second; + for (const auto &t : format_template_list) { + const auto format_string = GenerateDateFormat(separator, t); + // don't parse ISO 8601 + if (format_string.find("%Y-%m-%d") == string::npos) { + type_format_candidates.emplace_back(format_string); + } + } + } + // initialise the first candidate + options.has_format[sql_type.id()] = true; + // all formats are constructed to be valid + SetDateFormat(type_format_candidates.back(), sql_type.id()); + } + // check all formats and keep the first one that works + StrpTimeFormat::ParseResult result; + auto save_format_candidates = type_format_candidates; + while (!type_format_candidates.empty()) { + // avoid using exceptions for flow control... + auto ¤t_format = options.date_format[sql_type.id()]; + if (current_format.Parse(StringValue::Get(dummy_val), result)) { + break; + } + // doesn't work - move to the next one + type_format_candidates.pop_back(); + options.has_format[sql_type.id()] = (!type_format_candidates.empty()); + if (!type_format_candidates.empty()) { + SetDateFormat(type_format_candidates.back(), sql_type.id()); + } + } + // if none match, then this is not a value of type sql_type, + if (type_format_candidates.empty()) { + // so restore the candidates that did work. + // or throw them out if they were generated by this value. + if (had_format_candidates) { + type_format_candidates.swap(save_format_candidates); + if (!type_format_candidates.empty()) { + SetDateFormat(type_format_candidates.back(), sql_type.id()); + } + } else { + has_format_candidates[sql_type.id()] = false; + } + } + } + // try cast from string to sql_type + if (TryCastValue(dummy_val, sql_type)) { + break; + } else { + col_type_candidates.pop_back(); + } + } + } + // reset type detection, because first row could be header, + // but only do it if csv has more than one line (including header) + if (parse_chunk.size() > 0 && is_header_row) { + info_sql_types_candidates = vector>(options.num_cols, type_candidates); + for (auto &f : format_candidates) { + f.second.clear(); + } + for (auto &h : has_format_candidates) { + h.second = false; + } + } + } + + idx_t varchar_cols = 0; + for (idx_t col = 0; col < parse_chunk.ColumnCount(); col++) { + auto &col_type_candidates = info_sql_types_candidates[col]; + // check number of varchar columns + const auto &col_type = col_type_candidates.back(); + if (col_type == LogicalType::VARCHAR) { + varchar_cols++; + } + } + + // it's good if the dialect creates more non-varchar columns, but only if we sacrifice < 30% of best_num_cols. + if (varchar_cols < min_varchar_cols && parse_chunk.ColumnCount() > (best_num_cols * 0.7)) { + // we have a new best_options candidate + best_options = info_candidate; + min_varchar_cols = varchar_cols; + best_sql_types_candidates = info_sql_types_candidates; + best_format_candidates = format_candidates; + best_header_row.Destroy(); + auto header_row_types = header_row.GetTypes(); + best_header_row.Initialize(allocator, header_row_types); + header_row.Copy(best_header_row); + } + } + + options = best_options; + for (const auto &best : best_format_candidates) { + if (!best.second.empty()) { + SetDateFormat(best.second.back(), best.first); + } + } +} + +void BufferedCSVReader::DetectHeader(const vector> &best_sql_types_candidates, + const DataChunk &best_header_row) { + // information for header detection + bool first_row_consistent = true; + bool first_row_nulls = false; + + // check if header row is all null and/or consistent with detected column data types + 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.IsNull()) { + first_row_nulls = false; + } + + // try cast to sql_type of column + const auto &sql_type = best_sql_types_candidates[col].back(); + if (!TryCastValue(dummy_val, sql_type)) { + first_row_consistent = false; + } + } + + // 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; + 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.IsNull()) { + col_name = GenerateColumnName(options.num_cols, col); + } + + // normalize names or at least trim whitespace + if (options.normalize_names) { + col_name = NormalizeColumnName(col_name); + } else { + col_name = TrimWhitespace(col_name); + } + + // avoid duplicate header names + const string col_name_raw = col_name; + while (name_collision_count.find(col_name) != name_collision_count.end()) { + name_collision_count[col_name] += 1; + col_name = col_name + "_" + to_string(name_collision_count[col_name]); + } + + names.push_back(col_name); + name_collision_count[col_name] = 0; + } + + } else { + options.header = false; + for (idx_t col = 0; col < options.num_cols; col++) { + string column_name = GenerateColumnName(options.num_cols, col); + names.push_back(column_name); + } + } + for (idx_t i = 0; i < MinValue(names.size(), options.name_list.size()); i++) { + names[i] = options.name_list[i]; + } +} + +vector BufferedCSVReader::RefineTypeDetection(const vector &type_candidates, + const vector &requested_types, + vector> &best_sql_types_candidates, + map> &best_format_candidates) { + // for the type refine we set the SQL types to VARCHAR for all columns + return_types.clear(); + return_types.assign(options.num_cols, LogicalType::VARCHAR); + + vector detected_types; + + // if data types were provided, exit here if number of columns does not match + if (!requested_types.empty()) { + if (requested_types.size() != options.num_cols) { + throw InvalidInputException( + "Error while determining column types: found %lld columns but expected %d. (%s)", options.num_cols, + requested_types.size(), options.ToString()); + } else { + detected_types = requested_types; + } + } else if (options.all_varchar) { + // return all types varchar + detected_types = return_types; + } else { + // jump through the rest of the file and continue to refine the sql type guess + while (JumpToNextSample()) { + InitParseChunk(return_types.size()); + // if jump ends up a bad line, we just skip this chunk + if (!TryParseCSV(ParserMode::SNIFFING_DATATYPES)) { + continue; + } + for (idx_t col = 0; col < parse_chunk.ColumnCount(); col++) { + vector &col_type_candidates = best_sql_types_candidates[col]; + while (col_type_candidates.size() > 1) { + const auto &sql_type = col_type_candidates.back(); + // narrow down the date formats + if (best_format_candidates.count(sql_type.id())) { + auto &best_type_format_candidates = best_format_candidates[sql_type.id()]; + auto save_format_candidates = best_type_format_candidates; + while (!best_type_format_candidates.empty()) { + if (TryCastVector(parse_chunk.data[col], parse_chunk.size(), sql_type)) { + break; + } + // doesn't work - move to the next one + best_type_format_candidates.pop_back(); + options.has_format[sql_type.id()] = (!best_type_format_candidates.empty()); + if (!best_type_format_candidates.empty()) { + SetDateFormat(best_type_format_candidates.back(), sql_type.id()); + } + } + // if none match, then this is not a column of type sql_type, + if (best_type_format_candidates.empty()) { + // so restore the candidates that did work. + best_type_format_candidates.swap(save_format_candidates); + if (!best_type_format_candidates.empty()) { + SetDateFormat(best_type_format_candidates.back(), sql_type.id()); + } + } + } + + if (TryCastVector(parse_chunk.data[col], parse_chunk.size(), sql_type)) { + break; + } else { + col_type_candidates.pop_back(); + } + } + } + } + + // set sql types + for (auto &best_sql_types_candidate : best_sql_types_candidates) { + LogicalType d_type = best_sql_types_candidate.back(); + if (best_sql_types_candidate.size() == type_candidates.size()) { + d_type = LogicalType::VARCHAR; + } + detected_types.push_back(d_type); + } + } + + return detected_types; +} + +string BufferedCSVReader::ColumnTypesError(case_insensitive_map_t sql_types_per_column, + const vector &names) { + for (idx_t i = 0; i < names.size(); i++) { + auto it = sql_types_per_column.find(names[i]); + if (it != sql_types_per_column.end()) { + sql_types_per_column.erase(names[i]); + continue; + } + } + if (sql_types_per_column.empty()) { + return string(); + } + string exception = "COLUMN_TYPES error: Columns with names: "; + for (auto &col : sql_types_per_column) { + exception += "\"" + col.first + "\","; + } + exception.pop_back(); + exception += " do not exist in the CSV File"; + return exception; +} + +vector BufferedCSVReader::SniffCSV(const vector &requested_types) { + for (auto &type : requested_types) { + // auto detect for blobs not supported: there may be invalid UTF-8 in the file + if (type.id() == LogicalTypeId::BLOB) { + return requested_types; + } + } + + // ####### + // ### dialect detection + // ####### + BufferedCSVReaderOptions original_options = options; + vector info_candidates; + idx_t best_num_cols = 0; + + DetectDialect(requested_types, original_options, info_candidates, best_num_cols); + + // if no dialect candidate was found, then file was most likely empty and we throw an exception + if (info_candidates.empty()) { + throw InvalidInputException( + "Error in file \"%s\": CSV options could not be auto-detected. Consider setting parser options manually.", + options.file_path); + } + + // ####### + // ### type detection (initial) + // ####### + + // format template candidates, ordered by descending specificity (~ from high to low) + std::map> format_template_candidates = { + {LogicalTypeId::DATE, {"%m-%d-%Y", "%m-%d-%y", "%d-%m-%Y", "%d-%m-%y", "%Y-%m-%d", "%y-%m-%d"}}, + {LogicalTypeId::TIMESTAMP, + {"%Y-%m-%d %H:%M:%S.%f", "%m-%d-%Y %I:%M:%S %p", "%m-%d-%y %I:%M:%S %p", "%d-%m-%Y %H:%M:%S", + "%d-%m-%y %H:%M:%S", "%Y-%m-%d %H:%M:%S", "%y-%m-%d %H:%M:%S"}}, + }; + vector> best_sql_types_candidates; + map> best_format_candidates; + DataChunk best_header_row; + DetectCandidateTypes(options.auto_type_candidates, format_template_candidates, info_candidates, original_options, + best_num_cols, best_sql_types_candidates, best_format_candidates, best_header_row); + + if (best_format_candidates.empty() || best_header_row.size() == 0) { + throw InvalidInputException( + "Error in file \"%s\": CSV options could not be auto-detected. Consider setting parser options manually.", + original_options.file_path); + } + + // ####### + // ### header detection + // ####### + options.num_cols = best_num_cols; + DetectHeader(best_sql_types_candidates, best_header_row); + if (!options.sql_type_list.empty()) { + // user-defined types were supplied for certain columns + // override the types + if (!options.sql_types_per_column.empty()) { + // types supplied as name -> value map + idx_t found = 0; + for (idx_t i = 0; i < names.size(); i++) { + auto it = options.sql_types_per_column.find(names[i]); + if (it != options.sql_types_per_column.end()) { + best_sql_types_candidates[i] = {options.sql_type_list[it->second]}; + found++; + continue; + } + } + if (!options.file_options.union_by_name && found < options.sql_types_per_column.size()) { + string exception = ColumnTypesError(options.sql_types_per_column, names); + if (!exception.empty()) { + throw BinderException(exception); + } + } + } else { + // types supplied as list + if (names.size() < options.sql_type_list.size()) { + throw BinderException("read_csv: %d types were provided, but CSV file only has %d columns", + options.sql_type_list.size(), names.size()); + } + for (idx_t i = 0; i < options.sql_type_list.size(); i++) { + best_sql_types_candidates[i] = {options.sql_type_list[i]}; + } + } + } + + // ####### + // ### type detection (refining) + // ####### + return RefineTypeDetection(options.auto_type_candidates, requested_types, best_sql_types_candidates, + best_format_candidates); +} + +bool BufferedCSVReader::TryParseComplexCSV(DataChunk &insert_chunk, string &error_message) { + // used for parsing algorithm + bool finished_chunk = false; + idx_t column = 0; + vector escape_positions; + bool has_quotes = false; + uint8_t delimiter_pos = 0, escape_pos = 0, quote_pos = 0; + idx_t offset = 0; + idx_t line_start = 0; + // read values into the buffer (if any) + if (position >= buffer_size) { + if (!ReadBuffer(start, line_start)) { + return true; + } + } + // start parsing the first value + start = position; + goto value_start; +value_start: + /* state: value_start */ + // this state parses the first characters of a value + offset = 0; + delimiter_pos = 0; + quote_pos = 0; + do { + idx_t count = 0; + for (; position < buffer_size; position++) { + quote_search.Match(quote_pos, buffer[position]); + delimiter_search.Match(delimiter_pos, buffer[position]); + count++; + if (delimiter_pos == options.delimiter.size()) { + // found a delimiter, add the value + offset = options.delimiter.size() - 1; + goto add_value; + } else if (StringUtil::CharacterIsNewline(buffer[position])) { + // found a newline, add the row + goto add_row; + } + if (count > quote_pos) { + // did not find a quote directly at the start of the value, stop looking for the quote now + goto normal; + } + if (quote_pos == options.quote.size()) { + // found a quote, go to quoted loop and skip the initial quote + start += options.quote.size(); + goto in_quotes; + } + } + } while (ReadBuffer(start, line_start)); + // file ends while scanning for quote/delimiter, go to final state + goto final_state; +normal: + /* state: normal parsing state */ + // this state parses the remainder of a non-quoted value until we reach a delimiter or newline + position++; + do { + for (; position < buffer_size; position++) { + delimiter_search.Match(delimiter_pos, buffer[position]); + if (delimiter_pos == options.delimiter.size()) { + offset = options.delimiter.size() - 1; + goto add_value; + } else if (StringUtil::CharacterIsNewline(buffer[position])) { + goto add_row; + } + } + } while (ReadBuffer(start, line_start)); + goto final_state; +add_value: + AddValue(string_t(buffer.get() + start, position - start - offset), column, escape_positions, has_quotes); + // increase position by 1 and move start to the new position + offset = 0; + has_quotes = false; + start = ++position; + if (position >= buffer_size && !ReadBuffer(start, line_start)) { + // file ends right after delimiter, go to final state + goto final_state; + } + goto value_start; +add_row : { + // check type of newline (\r or \n) + bool carriage_return = buffer[position] == '\r'; + AddValue(string_t(buffer.get() + start, position - start - offset), column, escape_positions, has_quotes); + finished_chunk = AddRow(insert_chunk, column, error_message); + + if (!error_message.empty()) { + return false; + } + // increase position by 1 and move start to the new position + offset = 0; + has_quotes = false; + position++; + SkipEmptyLines(); + start = position; + if (position >= buffer_size && !ReadBuffer(start, line_start)) { + // file ends right after newline, go to final state + goto final_state; + } + if (carriage_return) { + // \r newline, go to special state that parses an optional \n afterwards + goto carriage_return; + } else { + // \n newline, move to value start + if (finished_chunk) { + return true; + } + goto value_start; + } +} +in_quotes: + /* state: in_quotes */ + // this state parses the remainder of a quoted value + quote_pos = 0; + escape_pos = 0; + has_quotes = true; + position++; + do { + for (; position < buffer_size; position++) { + quote_search.Match(quote_pos, buffer[position]); + escape_search.Match(escape_pos, buffer[position]); + if (quote_pos == options.quote.size()) { + goto unquote; + } else if (escape_pos == options.escape.size()) { + escape_positions.push_back(position - start - (options.escape.size() - 1)); + goto handle_escape; + } + } + } while (ReadBuffer(start, line_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()); + return false; +unquote: + /* state: unquote */ + // this state handles the state directly after we unquote + // in this state we expect either another quote (entering the quoted state again, and escaping the quote) + // or a delimiter/newline, ending the current value and moving on to the next value + delimiter_pos = 0; + quote_pos = 0; + position++; + if (position >= buffer_size && !ReadBuffer(start, line_start)) { + // file ends right after unquote, go to final state + offset = options.quote.size(); + goto final_state; + } + if (StringUtil::CharacterIsNewline(buffer[position])) { + // quote followed by newline, add row + offset = options.quote.size(); + goto add_row; + } + do { + idx_t count = 0; + for (; position < buffer_size; position++) { + quote_search.Match(quote_pos, buffer[position]); + delimiter_search.Match(delimiter_pos, buffer[position]); + count++; + if (count > delimiter_pos && count > quote_pos) { + 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()); + return false; + } + if (delimiter_pos == options.delimiter.size()) { + // quote followed by delimiter, add value + offset = options.quote.size() + options.delimiter.size() - 1; + goto add_value; + } else if (quote_pos == options.quote.size() && + (options.escape.empty() || options.escape == options.quote)) { + // quote followed by quote, go back to quoted state and add to escape + escape_positions.push_back(position - start - (options.quote.size() - 1)); + goto in_quotes; + } + } + } while (ReadBuffer(start, line_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()); + return false; +handle_escape: + escape_pos = 0; + quote_pos = 0; + position++; + do { + idx_t count = 0; + for (; position < buffer_size; position++) { + quote_search.Match(quote_pos, buffer[position]); + escape_search.Match(escape_pos, buffer[position]); + count++; + 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()); + return false; + } + if (quote_pos == options.quote.size() || escape_pos == options.escape.size()) { + // found quote or escape: move back to quoted state + goto in_quotes; + } + } + } while (ReadBuffer(start, line_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()); + return false; +carriage_return: + /* state: carriage_return */ + // this stage optionally skips a newline (\n) character, which allows \r\n to be interpreted as a single line + if (buffer[position] == '\n') { + // newline after carriage return: skip + start = ++position; + if (position >= buffer_size && !ReadBuffer(start, line_start)) { + // file ends right after newline, go to final state + goto final_state; + } + } + if (finished_chunk) { + return true; + } + goto value_start; +final_state: + if (finished_chunk) { + return true; + } + if (column > 0 || position > start) { + // remaining values to be added to the chunk + AddValue(string_t(buffer.get() + start, position - start - offset), column, escape_positions, has_quotes); + finished_chunk = AddRow(insert_chunk, column, error_message); + SkipEmptyLines(); + if (!error_message.empty()) { + return false; + } + } + // final stage, only reached after parsing the file is finished + // flush the parsed chunk and finalize parsing + if (mode == ParserMode::PARSING) { + Flush(insert_chunk); + } + + end_of_file_reached = true; + return true; +} + +void BufferedCSVReader::SkipEmptyLines() { + if (parse_chunk.data.size() == 1) { + // Empty lines are null data. + return; + } + for (; position < buffer_size; position++) { + if (!StringUtil::CharacterIsNewline(buffer[position])) { + return; + } + } +} + +void UpdateMaxLineLength(ClientContext &context, idx_t line_length) { + if (!context.client_data->debug_set_max_line_length) { + return; + } + if (line_length < context.client_data->debug_max_line_length) { + return; + } + context.client_data->debug_max_line_length = line_length; +} + +bool BufferedCSVReader::TryParseSimpleCSV(DataChunk &insert_chunk, string &error_message) { + // used for parsing algorithm + bool finished_chunk = false; + idx_t column = 0; + idx_t offset = 0; + bool has_quotes = false; + vector escape_positions; + + idx_t line_start = position; + // read values into the buffer (if any) + if (position >= buffer_size) { + if (!ReadBuffer(start, line_start)) { + return true; + } + } + + // start parsing the first value + goto value_start; +value_start: + offset = 0; + /* state: value_start */ + // this state parses the first character of a value + if (buffer[position] == options.quote[0]) { + // quote: actual value starts in the next position + // move to in_quotes state + start = position + 1; + goto in_quotes; + } else { + // no quote, move to normal parsing state + start = position; + goto normal; + } +normal: + /* state: normal parsing state */ + // this state parses the remainder of a non-quoted value until we reach a delimiter or newline + do { + for (; position < buffer_size; position++) { + if (buffer[position] == options.delimiter[0]) { + // delimiter: end the value and add it to the chunk + goto add_value; + } else if (StringUtil::CharacterIsNewline(buffer[position])) { + // newline: add row + goto add_row; + } + } + } while (ReadBuffer(start, line_start)); + // file ends during normal scan: go to end state + goto final_state; +add_value: + AddValue(string_t(buffer.get() + start, position - start - offset), column, escape_positions, has_quotes); + // increase position by 1 and move start to the new position + offset = 0; + has_quotes = false; + start = ++position; + if (position >= buffer_size && !ReadBuffer(start, line_start)) { + // file ends right after delimiter, go to final state + goto final_state; + } + goto value_start; +add_row : { + // check type of newline (\r or \n) + bool carriage_return = buffer[position] == '\r'; + AddValue(string_t(buffer.get() + start, position - start - offset), column, escape_positions, has_quotes); + if (!error_message.empty()) { + return false; + } + finished_chunk = AddRow(insert_chunk, column, error_message); + UpdateMaxLineLength(context, position - line_start); + if (!error_message.empty()) { + return false; + } + // increase position by 1 and move start to the new position + offset = 0; + has_quotes = false; + position++; + start = position; + line_start = position; + if (position >= buffer_size && !ReadBuffer(start, line_start)) { + // file ends right after delimiter, go to final state + goto final_state; + } + if (carriage_return) { + // \r newline, go to special state that parses an optional \n afterwards + goto carriage_return; + } else { + SetNewLineDelimiter(); + SkipEmptyLines(); + + start = position; + line_start = position; + if (position >= buffer_size && !ReadBuffer(start, line_start)) { + // file ends right after delimiter, go to final state + goto final_state; + } + // \n newline, move to value start + if (finished_chunk) { + return true; + } + goto value_start; + } +} +in_quotes: + /* state: in_quotes */ + // this state parses the remainder of a quoted value + has_quotes = true; + position++; + do { + for (; position < buffer_size; position++) { + if (buffer[position] == options.quote[0]) { + // quote: move to unquoted state + goto unquote; + } else if (buffer[position] == options.escape[0]) { + // escape: store the escaped position and move to handle_escape state + escape_positions.push_back(position - start); + goto handle_escape; + } + } + } while (ReadBuffer(start, line_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()); +unquote: + /* state: unquote */ + // this state handles the state directly after we unquote + // in this state we expect either another quote (entering the quoted state again, and escaping the quote) + // or a delimiter/newline, ending the current value and moving on to the next value + position++; + if (position >= buffer_size && !ReadBuffer(start, line_start)) { + // file ends right after unquote, go to final state + offset = 1; + goto final_state; + } + if (buffer[position] == options.quote[0] && (options.escape.empty() || options.escape[0] == options.quote[0])) { + // escaped quote, return to quoted state and store escape position + escape_positions.push_back(position - start); + goto in_quotes; + } else if (buffer[position] == options.delimiter[0]) { + // delimiter, add value + offset = 1; + goto add_value; + } else if (StringUtil::CharacterIsNewline(buffer[position])) { + offset = 1; + goto add_row; + } else { + 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()); + return false; + } +handle_escape: + /* state: handle_escape */ + // escape should be followed by a quote or another escape character + position++; + if (position >= buffer_size && !ReadBuffer(start, line_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()); + 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()); + return false; + } + // escape was followed by quote or escape, go back to quoted state + goto in_quotes; +carriage_return: + /* state: carriage_return */ + // this stage optionally skips a newline (\n) character, which allows \r\n to be interpreted as a single line + if (buffer[position] == '\n') { + SetNewLineDelimiter(true, true); + // newline after carriage return: skip + // increase position by 1 and move start to the new position + start = ++position; + if (position >= buffer_size && !ReadBuffer(start, line_start)) { + // file ends right after delimiter, go to final state + goto final_state; + } + } else { + SetNewLineDelimiter(true, false); + } + if (finished_chunk) { + return true; + } + SkipEmptyLines(); + start = position; + line_start = position; + if (position >= buffer_size && !ReadBuffer(start, line_start)) { + // file ends right after delimiter, go to final state + goto final_state; + } + + goto value_start; +final_state: + if (finished_chunk) { + return true; + } + + if (column > 0 || position > start) { + // remaining values to be added to the chunk + AddValue(string_t(buffer.get() + start, position - start - offset), column, escape_positions, has_quotes); + finished_chunk = AddRow(insert_chunk, column, error_message); + SkipEmptyLines(); + UpdateMaxLineLength(context, position - line_start); + if (!error_message.empty()) { + return false; + } + } + + // final stage, only reached after parsing the file is finished + // flush the parsed chunk and finalize parsing + if (mode == ParserMode::PARSING) { + Flush(insert_chunk); + } + + end_of_file_reached = true; + return true; +} + +bool BufferedCSVReader::ReadBuffer(idx_t &start, idx_t &line_start) { + if (start > buffer_size) { + return false; + } + auto old_buffer = std::move(buffer); + + // the remaining part of the last buffer + idx_t remaining = buffer_size - start; + + bool large_buffers = mode == ParserMode::PARSING && !file_handle->OnDiskFile() && file_handle->CanSeek(); + idx_t buffer_read_size = large_buffers ? INITIAL_BUFFER_SIZE_LARGE : INITIAL_BUFFER_SIZE; + + while (remaining > buffer_read_size) { + buffer_read_size *= 2; + } + + // Check line length + if (remaining > options.maximum_line_size) { + throw InvalidInputException("Maximum line size of %llu bytes exceeded on line %s!", options.maximum_line_size, + GetLineNumberStr(linenr, linenr_estimated)); + } + + buffer = make_unsafe_uniq_array(buffer_read_size + remaining + 1); + buffer_size = remaining + buffer_read_size; + if (remaining > 0) { + // remaining from last buffer: copy it here + memcpy(buffer.get(), old_buffer.get() + start, remaining); + } + idx_t read_count = file_handle->Read(buffer.get() + remaining, buffer_read_size); + + bytes_in_chunk += read_count; + buffer_size = remaining + read_count; + buffer[buffer_size] = '\0'; + if (old_buffer) { + cached_buffers.push_back(std::move(old_buffer)); + } + start = 0; + position = remaining; + if (!bom_checked) { + bom_checked = true; + if (read_count >= 3 && buffer[0] == '\xEF' && buffer[1] == '\xBB' && buffer[2] == '\xBF') { + start += 3; + position += 3; + } + } + line_start = start; + + return read_count > 0; +} + +void BufferedCSVReader::ParseCSV(DataChunk &insert_chunk) { + string error_message; + if (!TryParseCSV(ParserMode::PARSING, insert_chunk, error_message)) { + throw InvalidInputException(error_message); + } +} + +bool BufferedCSVReader::TryParseCSV(ParserMode mode) { + DataChunk dummy_chunk; + string error_message; + return TryParseCSV(mode, dummy_chunk, error_message); +} + +void BufferedCSVReader::ParseCSV(ParserMode mode) { + DataChunk dummy_chunk; + string error_message; + if (!TryParseCSV(mode, dummy_chunk, error_message)) { + throw InvalidInputException(error_message); + } +} + +bool BufferedCSVReader::TryParseCSV(ParserMode parser_mode, DataChunk &insert_chunk, string &error_message) { + mode = parser_mode; + + if (options.quote.size() <= 1 && options.escape.size() <= 1 && options.delimiter.size() == 1) { + return TryParseSimpleCSV(insert_chunk, error_message); + } else { + return TryParseComplexCSV(insert_chunk, error_message); + } +} + +} // namespace duckdb diff --git a/src/duckdb/src/execution/operator/persistent/csv_buffer.cpp b/src/duckdb/src/execution/operator/persistent/csv_buffer.cpp new file mode 100644 index 00000000..e2466289 --- /dev/null +++ b/src/duckdb/src/execution/operator/persistent/csv_buffer.cpp @@ -0,0 +1,72 @@ +#include "duckdb/execution/operator/persistent/csv_buffer.hpp" +#include "duckdb/common/string_util.hpp" + +namespace duckdb { + +CSVBuffer::CSVBuffer(ClientContext &context, idx_t buffer_size_p, CSVFileHandle &file_handle, + idx_t &global_csv_current_position, idx_t file_number_p) + : context(context), first_buffer(true), file_number(file_number_p) { + this->handle = AllocateBuffer(buffer_size_p); + + auto buffer = Ptr(); + actual_size = file_handle.Read(buffer, buffer_size_p); + global_csv_start = global_csv_current_position; + global_csv_current_position += actual_size; + if (actual_size >= 3 && buffer[0] == '\xEF' && buffer[1] == '\xBB' && buffer[2] == '\xBF') { + start_position += 3; + } + last_buffer = file_handle.FinishedReading(); +} + +CSVBuffer::CSVBuffer(ClientContext &context, BufferHandle buffer_p, idx_t buffer_size_p, idx_t actual_size_p, + bool final_buffer, idx_t global_csv_current_position, idx_t file_number_p) + : context(context), handle(std::move(buffer_p)), actual_size(actual_size_p), last_buffer(final_buffer), + global_csv_start(global_csv_current_position), file_number(file_number_p) { +} + +unique_ptr CSVBuffer::Next(CSVFileHandle &file_handle, idx_t buffer_size, idx_t &global_csv_current_position, + idx_t file_number_p) { + auto next_buffer = AllocateBuffer(buffer_size); + idx_t next_buffer_actual_size = file_handle.Read(next_buffer.Ptr(), buffer_size); + if (next_buffer_actual_size == 0) { + // We are done reading + return nullptr; + } + + auto next_csv_buffer = + make_uniq(context, std::move(next_buffer), buffer_size, next_buffer_actual_size, + file_handle.FinishedReading(), global_csv_current_position, file_number_p); + global_csv_current_position += next_buffer_actual_size; + return next_csv_buffer; +} + +BufferHandle CSVBuffer::AllocateBuffer(idx_t buffer_size) { + auto &buffer_manager = BufferManager::GetBufferManager(context); + return buffer_manager.Allocate(MaxValue(Storage::BLOCK_SIZE, buffer_size)); +} + +idx_t CSVBuffer::GetBufferSize() { + return actual_size; +} + +idx_t CSVBuffer::GetStart() { + return start_position; +} + +bool CSVBuffer::IsCSVFileLastBuffer() { + return last_buffer; +} + +bool CSVBuffer::IsCSVFileFirstBuffer() { + return first_buffer; +} + +idx_t CSVBuffer::GetCSVGlobalStart() { + return global_csv_start; +} + +idx_t CSVBuffer::GetFileNumber() { + return file_number; +} + +} // namespace duckdb diff --git a/src/duckdb/src/execution/operator/persistent/csv_file_handle.cpp b/src/duckdb/src/execution/operator/persistent/csv_file_handle.cpp new file mode 100644 index 00000000..03ef4ede --- /dev/null +++ b/src/duckdb/src/execution/operator/persistent/csv_file_handle.cpp @@ -0,0 +1,158 @@ +#include "duckdb/execution/operator/persistent/csv_file_handle.hpp" + +namespace duckdb { + +CSVFileHandle::CSVFileHandle(FileSystem &fs, Allocator &allocator, unique_ptr file_handle_p, + const string &path_p, FileCompressionType compression, bool enable_reset) + : fs(fs), allocator(allocator), file_handle(std::move(file_handle_p)), path(path_p), compression(compression), + reset_enabled(enable_reset) { + can_seek = file_handle->CanSeek(); + on_disk_file = file_handle->OnDiskFile(); + file_size = file_handle->GetFileSize(); +} + +unique_ptr CSVFileHandle::OpenFileHandle(FileSystem &fs, Allocator &allocator, const string &path, + FileCompressionType compression) { + auto file_handle = fs.OpenFile(path, FileFlags::FILE_FLAGS_READ, FileLockType::NO_LOCK, compression); + if (file_handle->CanSeek()) { + file_handle->Reset(); + } + return file_handle; +} + +unique_ptr CSVFileHandle::OpenFile(FileSystem &fs, Allocator &allocator, const string &path, + FileCompressionType compression, bool enable_reset) { + auto file_handle = CSVFileHandle::OpenFileHandle(fs, allocator, path, compression); + return make_uniq(fs, allocator, std::move(file_handle), path, compression, enable_reset); +} + +bool CSVFileHandle::CanSeek() { + return can_seek; +} + +void CSVFileHandle::Seek(idx_t position) { + if (!can_seek) { + throw InternalException("Cannot seek in this file"); + } + file_handle->Seek(position); +} + +idx_t CSVFileHandle::SeekPosition() { + if (!can_seek) { + throw InternalException("Cannot seek in this file"); + } + return file_handle->SeekPosition(); +} + +void CSVFileHandle::Reset() { + requested_bytes = 0; + read_position = 0; + if (can_seek) { + // we can seek - reset the file handle + file_handle->Reset(); + } else if (on_disk_file) { + // we cannot seek but it is an on-disk file - re-open the file + file_handle = CSVFileHandle::OpenFileHandle(fs, allocator, path, compression); + } else { + if (!reset_enabled) { + throw InternalException("Reset called but reset is not enabled for this CSV Handle"); + } + read_position = 0; + } +} +bool CSVFileHandle::OnDiskFile() { + return on_disk_file; +} + +idx_t CSVFileHandle::FileSize() { + return file_size; +} + +bool CSVFileHandle::FinishedReading() { + return requested_bytes >= file_size; +} + +idx_t CSVFileHandle::Read(void *buffer, idx_t nr_bytes) { + requested_bytes += nr_bytes; + if (on_disk_file || can_seek) { + // if this is a plain file source OR we can seek we are not caching anything + return file_handle->Read(buffer, nr_bytes); + } + // 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.IsSet()) { + // 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_ptr_cast(buffer) + result_offset, nr_bytes - result_offset); + file_size = file_handle->GetFileSize(); + 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 = allocator.Allocate(buffer_capacity); + if (buffer_size > 0) { + memcpy(new_buffer.get(), cached_buffer.get(), buffer_size); + } + cached_buffer = std::move(new_buffer); + } + memcpy(cached_buffer.get() + buffer_size, char_ptr_cast(buffer) + result_offset, bytes_read); + buffer_size += bytes_read; + } + + return result_offset + bytes_read; +} + +string CSVFileHandle::ReadLine() { + bool carriage_return = false; + string result; + char buffer[1]; + while (true) { + idx_t bytes_read = Read(buffer, 1); + if (bytes_read == 0) { + return result; + } + if (carriage_return) { + if (buffer[0] != '\n') { + if (!file_handle->CanSeek()) { + throw BinderException( + "Carriage return newlines not supported when reading CSV files in which we cannot seek"); + } + file_handle->Seek(file_handle->SeekPosition() - 1); + return result; + } + } + if (buffer[0] == '\n') { + return result; + } + if (buffer[0] != '\r') { + result += buffer[0]; + } else { + carriage_return = true; + } + } +} + +void CSVFileHandle::DisableReset() { + this->reset_enabled = false; +} + +} // namespace duckdb diff --git a/src/duckdb/src/execution/operator/persistent/csv_reader_options.cpp b/src/duckdb/src/execution/operator/persistent/csv_reader_options.cpp new file mode 100644 index 00000000..84df782a --- /dev/null +++ b/src/duckdb/src/execution/operator/persistent/csv_reader_options.cpp @@ -0,0 +1,280 @@ +#include "duckdb/execution/operator/persistent/csv_reader_options.hpp" +#include "duckdb/common/bind_helpers.hpp" +#include "duckdb/common/vector_size.hpp" +#include "duckdb/common/string_util.hpp" + +namespace duckdb { + +static bool ParseBoolean(const Value &value, const string &loption); + +static bool ParseBoolean(const vector &set, const string &loption) { + if (set.empty()) { + // no option specified: default to true + return true; + } + if (set.size() > 1) { + throw BinderException("\"%s\" expects a single argument as a boolean value (e.g. TRUE or 1)", loption); + } + return ParseBoolean(set[0], loption); +} + +static bool ParseBoolean(const Value &value, const string &loption) { + + if (value.type().id() == LogicalTypeId::LIST) { + auto &children = ListValue::GetChildren(value); + return ParseBoolean(children, loption); + } + if (value.type() == LogicalType::FLOAT || value.type() == LogicalType::DOUBLE || + value.type().id() == LogicalTypeId::DECIMAL) { + throw BinderException("\"%s\" expects a boolean value (e.g. TRUE or 1)", loption); + } + return BooleanValue::Get(value.DefaultCastAs(LogicalType::BOOLEAN)); +} + +static string ParseString(const Value &value, const string &loption) { + if (value.IsNull()) { + return string(); + } + if (value.type().id() == LogicalTypeId::LIST) { + auto &children = ListValue::GetChildren(value); + if (children.size() != 1) { + throw BinderException("\"%s\" expects a single argument as a string value", loption); + } + return ParseString(children[0], loption); + } + if (value.type().id() != LogicalTypeId::VARCHAR) { + throw BinderException("\"%s\" expects a string argument!", loption); + } + return value.GetValue(); +} + +static int64_t ParseInteger(const Value &value, const string &loption) { + if (value.type().id() == LogicalTypeId::LIST) { + auto &children = ListValue::GetChildren(value); + if (children.size() != 1) { + // no option specified or multiple options specified + throw BinderException("\"%s\" expects a single argument as an integer value", loption); + } + return ParseInteger(children[0], loption); + } + return value.GetValue(); +} + +void BufferedCSVReaderOptions::SetHeader(bool input) { + this->header = input; + this->has_header = true; +} + +void BufferedCSVReaderOptions::SetCompression(const string &compression_p) { + this->compression = FileCompressionTypeFromString(compression_p); +} + +void BufferedCSVReaderOptions::SetEscape(const string &input) { + this->escape = input; + this->has_escape = true; +} + +void BufferedCSVReaderOptions::SetDelimiter(const string &input) { + this->delimiter = StringUtil::Replace(input, "\\t", "\t"); + this->has_delimiter = true; + if (input.empty()) { + this->delimiter = string("\0", 1); + } +} + +void BufferedCSVReaderOptions::SetQuote(const string "e_p) { + this->quote = quote_p; + this->has_quote = true; +} + +void BufferedCSVReaderOptions::SetNewline(const string &input) { + if (input == "\\n" || input == "\\r") { + new_line = NewLineIdentifier::SINGLE; + } else if (input == "\\r\\n") { + new_line = NewLineIdentifier::CARRY_ON; + } else { + throw InvalidInputException("This is not accepted as a newline: " + input); + } + has_newline = true; +} + +void BufferedCSVReaderOptions::SetDateFormat(LogicalTypeId type, const string &format, bool read_format) { + string error; + if (read_format) { + error = StrTimeFormat::ParseFormatSpecifier(format, date_format[type]); + date_format[type].format_specifier = format; + } else { + error = StrTimeFormat::ParseFormatSpecifier(format, write_date_format[type]); + } + if (!error.empty()) { + throw InvalidInputException("Could not parse DATEFORMAT: %s", error.c_str()); + } + has_format[type] = true; +} + +void BufferedCSVReaderOptions::SetReadOption(const string &loption, const Value &value, + vector &expected_names) { + if (SetBaseOption(loption, value)) { + return; + } + if (loption == "auto_detect") { + auto_detect = ParseBoolean(value, loption); + } else if (loption == "sample_size") { + int64_t sample_size = ParseInteger(value, loption); + if (sample_size < 1 && sample_size != -1) { + throw BinderException("Unsupported parameter for SAMPLE_SIZE: cannot be smaller than 1"); + } + if (sample_size == -1) { + sample_chunks = std::numeric_limits::max(); + sample_chunk_size = STANDARD_VECTOR_SIZE; + } else if (sample_size <= STANDARD_VECTOR_SIZE) { + sample_chunk_size = sample_size; + sample_chunks = 1; + } else { + sample_chunk_size = STANDARD_VECTOR_SIZE; + sample_chunks = sample_size / STANDARD_VECTOR_SIZE + 1; + } + } else if (loption == "skip") { + skip_rows = ParseInteger(value, loption); + skip_rows_set = true; + } else if (loption == "max_line_size" || loption == "maximum_line_size") { + maximum_line_size = ParseInteger(value, loption); + } else if (loption == "sample_chunk_size") { + sample_chunk_size = ParseInteger(value, loption); + if (sample_chunk_size > STANDARD_VECTOR_SIZE) { + throw BinderException( + "Unsupported parameter for SAMPLE_CHUNK_SIZE: cannot be bigger than STANDARD_VECTOR_SIZE %d", + STANDARD_VECTOR_SIZE); + } else if (sample_chunk_size < 1) { + throw BinderException("Unsupported parameter for SAMPLE_CHUNK_SIZE: cannot be smaller than 1"); + } + } else if (loption == "sample_chunks") { + sample_chunks = ParseInteger(value, loption); + if (sample_chunks < 1) { + throw BinderException("Unsupported parameter for SAMPLE_CHUNKS: cannot be smaller than 1"); + } + } else if (loption == "force_not_null") { + force_not_null = ParseColumnList(value, expected_names, loption); + } else if (loption == "date_format" || loption == "dateformat") { + string format = ParseString(value, loption); + SetDateFormat(LogicalTypeId::DATE, format, true); + } else if (loption == "timestamp_format" || loption == "timestampformat") { + string format = ParseString(value, loption); + SetDateFormat(LogicalTypeId::TIMESTAMP, format, true); + } else if (loption == "ignore_errors") { + ignore_errors = ParseBoolean(value, loption); + } else if (loption == "buffer_size") { + buffer_size = ParseInteger(value, loption); + if (buffer_size == 0) { + throw InvalidInputException("Buffer Size option must be higher than 0"); + } + } else if (loption == "decimal_separator") { + decimal_separator = ParseString(value, loption); + if (decimal_separator != "." && decimal_separator != ",") { + throw BinderException("Unsupported parameter for DECIMAL_SEPARATOR: should be '.' or ','"); + } + } else if (loption == "null_padding") { + null_padding = ParseBoolean(value, loption); + } else if (loption == "allow_quoted_nulls") { + allow_quoted_nulls = ParseBoolean(value, loption); + } else if (loption == "parallel") { + parallel_mode = ParseBoolean(value, loption) ? ParallelMode::PARALLEL : ParallelMode::SINGLE_THREADED; + } else if (loption == "rejects_table") { + // skip, handled in SetRejectsOptions + auto table_name = ParseString(value, loption); + if (table_name.empty()) { + throw BinderException("REJECTS_TABLE option cannot be empty"); + } + rejects_table_name = table_name; + } else if (loption == "rejects_recovery_columns") { + // Get the list of columns to use as a recovery key + auto &children = ListValue::GetChildren(value); + for (auto &child : children) { + auto col_name = child.GetValue(); + rejects_recovery_columns.push_back(col_name); + } + } else if (loption == "rejects_limit") { + int64_t limit = ParseInteger(value, loption); + if (limit < 0) { + throw BinderException("Unsupported parameter for REJECTS_LIMIT: cannot be negative"); + } + rejects_limit = limit; + } else { + throw BinderException("Unrecognized option for CSV reader \"%s\"", loption); + } +} + +void BufferedCSVReaderOptions::SetWriteOption(const string &loption, const Value &value) { + if (loption == "new_line") { + // Steal this from SetBaseOption so we can write different newlines (e.g., format JSON ARRAY) + write_newline = ParseString(value, loption); + return; + } + + if (SetBaseOption(loption, value)) { + return; + } + + if (loption == "force_quote") { + force_quote = ParseColumnList(value, name_list, loption); + } else if (loption == "date_format" || loption == "dateformat") { + string format = ParseString(value, loption); + SetDateFormat(LogicalTypeId::DATE, format, false); + } else if (loption == "timestamp_format" || loption == "timestampformat") { + string format = ParseString(value, loption); + if (StringUtil::Lower(format) == "iso") { + format = "%Y-%m-%dT%H:%M:%S.%fZ"; + } + SetDateFormat(LogicalTypeId::TIMESTAMP, format, false); + SetDateFormat(LogicalTypeId::TIMESTAMP_TZ, format, false); + } else if (loption == "prefix") { + prefix = ParseString(value, loption); + } else if (loption == "suffix") { + suffix = ParseString(value, loption); + } else { + throw BinderException("Unrecognized option CSV writer \"%s\"", loption); + } +} + +bool BufferedCSVReaderOptions::SetBaseOption(const string &loption, const Value &value) { + // Make sure this function was only called after the option was turned into lowercase + D_ASSERT(!std::any_of(loption.begin(), loption.end(), ::isupper)); + + if (StringUtil::StartsWith(loption, "delim") || StringUtil::StartsWith(loption, "sep")) { + SetDelimiter(ParseString(value, loption)); + } else if (loption == "quote") { + SetQuote(ParseString(value, loption)); + } else if (loption == "new_line") { + SetNewline(ParseString(value, loption)); + } else if (loption == "escape") { + SetEscape(ParseString(value, loption)); + } else if (loption == "header") { + SetHeader(ParseBoolean(value, loption)); + } else if (loption == "null" || loption == "nullstr") { + null_str = ParseString(value, loption); + } else if (loption == "encoding") { + auto encoding = StringUtil::Lower(ParseString(value, loption)); + if (encoding != "utf8" && encoding != "utf-8") { + throw BinderException("Copy is only supported for UTF-8 encoded files, ENCODING 'UTF-8'"); + } + } else if (loption == "compression") { + SetCompression(ParseString(value, loption)); + } else { + // unrecognized option in base CSV + return false; + } + return true; +} + +std::string BufferedCSVReaderOptions::ToString() const { + return " file=" + file_path + "\n delimiter='" + delimiter + + (has_delimiter ? "'" : (auto_detect ? "' (auto detected)" : "' (default)")) + "\n quote='" + quote + + (has_quote ? "'" : (auto_detect ? "' (auto detected)" : "' (default)")) + "\n escape='" + escape + + (has_escape ? "'" : (auto_detect ? "' (auto detected)" : "' (default)")) + + "\n header=" + std::to_string(header) + + (has_header ? "" : (auto_detect ? " (auto detected)" : "' (default)")) + + "\n sample_size=" + std::to_string(sample_chunk_size * sample_chunks) + + "\n ignore_errors=" + std::to_string(ignore_errors) + "\n all_varchar=" + std::to_string(all_varchar); +} + +} // namespace duckdb diff --git a/src/duckdb/src/execution/operator/persistent/parallel_csv_reader.cpp b/src/duckdb/src/execution/operator/persistent/parallel_csv_reader.cpp new file mode 100644 index 00000000..6b2a5831 --- /dev/null +++ b/src/duckdb/src/execution/operator/persistent/parallel_csv_reader.cpp @@ -0,0 +1,666 @@ +#include "duckdb/execution/operator/persistent/parallel_csv_reader.hpp" + +#include "duckdb/catalog/catalog_entry/table_catalog_entry.hpp" +#include "duckdb/common/file_system.hpp" +#include "duckdb/common/string_util.hpp" +#include "duckdb/common/to_string.hpp" +#include "duckdb/common/types/cast_helpers.hpp" +#include "duckdb/common/vector_operations/unary_executor.hpp" +#include "duckdb/common/vector_operations/vector_operations.hpp" +#include "duckdb/function/scalar/strftime_format.hpp" +#include "duckdb/main/database.hpp" +#include "duckdb/parser/column_definition.hpp" +#include "duckdb/storage/data_table.hpp" +#include "utf8proc_wrapper.hpp" +#include "utf8proc.hpp" +#include "duckdb/parser/keyword_helper.hpp" +#include "duckdb/function/table/read_csv.hpp" +#include "duckdb/execution/operator/persistent/csv_line_info.hpp" + +#include +#include +#include +#include + +namespace duckdb { + +ParallelCSVReader::ParallelCSVReader(ClientContext &context, BufferedCSVReaderOptions options_p, + unique_ptr buffer_p, idx_t first_pos_first_buffer_p, + const vector &requested_types, idx_t file_idx_p) + : BaseCSVReader(context, std::move(options_p), requested_types), file_idx(file_idx_p), + first_pos_first_buffer(first_pos_first_buffer_p) { + Initialize(requested_types); + SetBufferRead(std::move(buffer_p)); + if (options.delimiter.size() > 1 || options.escape.size() > 1 || options.quote.size() > 1) { + throw InternalException("Parallel CSV reader cannot handle CSVs with multi-byte delimiters/escapes/quotes"); + } +} + +void ParallelCSVReader::Initialize(const vector &requested_types) { + return_types = requested_types; + InitParseChunk(return_types.size()); +} + +bool ParallelCSVReader::NewLineDelimiter(bool carry, bool carry_followed_by_nl, bool first_char) { + // Set the delimiter if not set yet. + SetNewLineDelimiter(carry, carry_followed_by_nl); + D_ASSERT(options.new_line == NewLineIdentifier::SINGLE || options.new_line == NewLineIdentifier::CARRY_ON); + if (options.new_line == NewLineIdentifier::SINGLE) { + return (!carry) || (carry && !carry_followed_by_nl); + } + return (carry && carry_followed_by_nl) || (!carry && first_char); +} + +void ParallelCSVReader::SkipEmptyLines() { + idx_t new_pos_buffer = position_buffer; + if (parse_chunk.data.size() == 1) { + // Empty lines are null data. + return; + } + for (; new_pos_buffer < end_buffer; new_pos_buffer++) { + if (StringUtil::CharacterIsNewline((*buffer)[new_pos_buffer])) { + bool carrier_return = (*buffer)[new_pos_buffer] == '\r'; + new_pos_buffer++; + if (carrier_return && new_pos_buffer < buffer_size && (*buffer)[new_pos_buffer] == '\n') { + position_buffer++; + } + if (new_pos_buffer > end_buffer) { + return; + } + position_buffer = new_pos_buffer; + } else if ((*buffer)[new_pos_buffer] != ' ') { + return; + } + } +} + +bool ParallelCSVReader::SetPosition() { + if (buffer->buffer->IsCSVFileFirstBuffer() && start_buffer == position_buffer && + start_buffer == first_pos_first_buffer) { + start_buffer = buffer->buffer->GetStart(); + position_buffer = start_buffer; + verification_positions.beginning_of_first_line = position_buffer; + verification_positions.end_of_last_line = position_buffer; + // First buffer doesn't need any setting + + if (options.header) { + for (; position_buffer < end_buffer; position_buffer++) { + if (StringUtil::CharacterIsNewline((*buffer)[position_buffer])) { + bool carrier_return = (*buffer)[position_buffer] == '\r'; + position_buffer++; + if (carrier_return && position_buffer < buffer_size && (*buffer)[position_buffer] == '\n') { + position_buffer++; + } + if (position_buffer > end_buffer) { + return false; + } + SkipEmptyLines(); + if (verification_positions.beginning_of_first_line == 0) { + verification_positions.beginning_of_first_line = position_buffer; + } + + verification_positions.end_of_last_line = position_buffer; + return true; + } + } + return false; + } + SkipEmptyLines(); + if (verification_positions.beginning_of_first_line == 0) { + verification_positions.beginning_of_first_line = position_buffer; + } + + verification_positions.end_of_last_line = position_buffer; + return true; + } + + // We have to move position up to next new line + idx_t end_buffer_real = end_buffer; + // Check if we already start in a valid line + string error_message; + bool successfully_read_first_line = false; + while (!successfully_read_first_line) { + DataChunk first_line_chunk; + first_line_chunk.Initialize(allocator, return_types); + // Ensure that parse_chunk has no gunk when trying to figure new line + parse_chunk.Reset(); + for (; position_buffer < end_buffer; position_buffer++) { + if (StringUtil::CharacterIsNewline((*buffer)[position_buffer])) { + bool carriage_return = (*buffer)[position_buffer] == '\r'; + bool carriage_return_followed = false; + position_buffer++; + if (position_buffer < end_buffer) { + if (carriage_return && (*buffer)[position_buffer] == '\n') { + carriage_return_followed = true; + position_buffer++; + } + } + if (NewLineDelimiter(carriage_return, carriage_return_followed, position_buffer - 1 == start_buffer)) { + break; + } + } + } + SkipEmptyLines(); + + if (position_buffer > buffer_size) { + break; + } + + if (position_buffer >= end_buffer && !StringUtil::CharacterIsNewline((*buffer)[position_buffer - 1])) { + break; + } + + if (position_buffer > end_buffer && options.new_line == NewLineIdentifier::CARRY_ON && + (*buffer)[position_buffer - 1] == '\n') { + break; + } + idx_t position_set = position_buffer; + start_buffer = position_buffer; + // We check if we can add this line + // disable the projection pushdown while reading the first line + // otherwise the first line parsing can be influenced by which columns we are reading + auto column_ids = std::move(reader_data.column_ids); + auto column_mapping = std::move(reader_data.column_mapping); + InitializeProjection(); + try { + successfully_read_first_line = TryParseSimpleCSV(first_line_chunk, error_message, true); + } catch (...) { + successfully_read_first_line = false; + } + // restore the projection pushdown + reader_data.column_ids = std::move(column_ids); + reader_data.column_mapping = std::move(column_mapping); + end_buffer = end_buffer_real; + start_buffer = position_set; + if (position_buffer >= end_buffer) { + if (successfully_read_first_line) { + position_buffer = position_set; + } + break; + } + position_buffer = position_set; + } + if (verification_positions.beginning_of_first_line == 0) { + verification_positions.beginning_of_first_line = position_buffer; + } + // Ensure that parse_chunk has no gunk when trying to figure new line + parse_chunk.Reset(); + + verification_positions.end_of_last_line = position_buffer; + finished = false; + return successfully_read_first_line; +} + +void ParallelCSVReader::SetBufferRead(unique_ptr buffer_read_p) { + if (!buffer_read_p->buffer) { + throw InternalException("ParallelCSVReader::SetBufferRead - CSVBufferRead does not have a buffer to read"); + } + position_buffer = buffer_read_p->buffer_start; + start_buffer = buffer_read_p->buffer_start; + end_buffer = buffer_read_p->buffer_end; + if (buffer_read_p->next_buffer) { + buffer_size = buffer_read_p->buffer->GetBufferSize() + buffer_read_p->next_buffer->GetBufferSize(); + } else { + buffer_size = buffer_read_p->buffer->GetBufferSize(); + } + buffer = std::move(buffer_read_p); + + reached_remainder_state = false; + verification_positions.beginning_of_first_line = 0; + verification_positions.end_of_last_line = 0; + finished = false; + D_ASSERT(end_buffer <= buffer_size); +} + +VerificationPositions ParallelCSVReader::GetVerificationPositions() { + verification_positions.beginning_of_first_line += buffer->buffer->GetCSVGlobalStart(); + verification_positions.end_of_last_line += buffer->buffer->GetCSVGlobalStart(); + return verification_positions; +} + +// If BufferRemainder returns false, it means we are done scanning this buffer and should go to the end_state +bool ParallelCSVReader::BufferRemainder() { + if (position_buffer >= end_buffer && !reached_remainder_state) { + // First time we finish the buffer piece we should scan here, we set the variables + // to allow this piece to be scanned up to the end of the buffer or the next new line + reached_remainder_state = true; + // end_buffer is allowed to go to buffer size to finish its last line + end_buffer = buffer_size; + } + if (position_buffer >= end_buffer) { + // buffer ends, return false + return false; + } + // we can still scan stuff, return true + return true; +} + +void ParallelCSVReader::VerifyLineLength(idx_t line_size) { + if (line_size > options.maximum_line_size) { + throw InvalidInputException("Error in file \"%s\" on line %s: Maximum line size of %llu bytes exceeded!", + options.file_path, + GetLineNumberStr(parse_chunk.size(), linenr_estimated, buffer->batch_index).c_str(), + options.maximum_line_size); + } +} + +bool AllNewLine(string_t value, idx_t column_amount) { + auto value_str = value.GetString(); + if (value_str.empty() && column_amount == 1) { + // This is a one column (empty) + return false; + } + for (idx_t i = 0; i < value.GetSize(); i++) { + if (!StringUtil::CharacterIsNewline(value_str[i])) { + return false; + } + } + return true; +} + +bool ParallelCSVReader::TryParseSimpleCSV(DataChunk &insert_chunk, string &error_message, bool try_add_line) { + // If line is not set, we have to figure it out, we assume whatever is in the first line + if (options.new_line == NewLineIdentifier::NOT_SET) { + idx_t cur_pos = position_buffer; + // we can start in the middle of a new line, so move a bit forward. + while (cur_pos < end_buffer) { + if (StringUtil::CharacterIsNewline((*buffer)[cur_pos])) { + cur_pos++; + } else { + break; + } + } + for (; cur_pos < end_buffer; cur_pos++) { + if (StringUtil::CharacterIsNewline((*buffer)[cur_pos])) { + bool carriage_return = (*buffer)[cur_pos] == '\r'; + bool carriage_return_followed = false; + cur_pos++; + if (cur_pos < end_buffer) { + if (carriage_return && (*buffer)[cur_pos] == '\n') { + carriage_return_followed = true; + cur_pos++; + } + } + SetNewLineDelimiter(carriage_return, carriage_return_followed); + break; + } + } + } + // used for parsing algorithm + if (start_buffer == buffer_size) { + // Nothing to read + finished = true; + return true; + } + D_ASSERT(end_buffer <= buffer_size); + bool finished_chunk = false; + idx_t column = 0; + idx_t offset = 0; + bool has_quotes = false; + + vector escape_positions; + if ((start_buffer == buffer->buffer_start || start_buffer == buffer->buffer_end) && !try_add_line) { + // First time reading this buffer piece + if (!SetPosition()) { + finished = true; + return true; + } + } + if (position_buffer == buffer_size) { + // Nothing to read + finished = true; + return true; + } + // Keep track of line size + idx_t line_start = position_buffer; + // start parsing the first value + goto value_start; + +value_start : { + /* state: value_start */ + if (!BufferRemainder()) { + goto final_state; + } + offset = 0; + + // this state parses the first character of a value + if ((*buffer)[position_buffer] == options.quote[0]) { + // quote: actual value starts in the next position + // move to in_quotes state + start_buffer = position_buffer + 1; + goto in_quotes; + } else { + // no quote, move to normal parsing state + start_buffer = position_buffer; + goto normal; + } +}; + +normal : { + /* state: normal parsing state */ + // this state parses the remainder of a non-quoted value until we reach a delimiter or newline + for (; position_buffer < end_buffer; position_buffer++) { + auto c = (*buffer)[position_buffer]; + if (c == options.delimiter[0]) { + // delimiter: end the value and add it to the chunk + goto add_value; + } else if (c == options.quote[0] && try_add_line) { + return false; + } else if (StringUtil::CharacterIsNewline(c)) { + // newline: add row + if (column > 0 || try_add_line || parse_chunk.data.size() == 1) { + goto add_row; + } + if (column == 0 && position_buffer == start_buffer) { + start_buffer++; + } + } + } + if (!BufferRemainder()) { + goto final_state; + } else { + goto normal; + } +}; + +add_value : { + /* state: Add value to string vector */ + AddValue(buffer->GetValue(start_buffer, position_buffer, offset), column, escape_positions, has_quotes, + buffer->local_batch_index); + // increase position by 1 and move start to the new position + offset = 0; + has_quotes = false; + start_buffer = ++position_buffer; + if (!BufferRemainder()) { + goto final_state; + } + goto value_start; +}; + +add_row : { + /* state: Add Row to Parse chunk */ + // check type of newline (\r or \n) + bool carriage_return = (*buffer)[position_buffer] == '\r'; + + AddValue(buffer->GetValue(start_buffer, position_buffer, offset), column, escape_positions, has_quotes, + buffer->local_batch_index); + if (try_add_line) { + bool success = column == insert_chunk.ColumnCount(); + if (success) { + idx_t cur_linenr = linenr; + AddRow(insert_chunk, column, error_message, buffer->local_batch_index); + success = Flush(insert_chunk, buffer->local_batch_index, true); + linenr = cur_linenr; + } + reached_remainder_state = false; + parse_chunk.Reset(); + return success; + } else { + VerifyLineLength(position_buffer - line_start); + line_start = position_buffer; + finished_chunk = AddRow(insert_chunk, column, error_message, buffer->local_batch_index); + } + // increase position by 1 and move start to the new position + offset = 0; + has_quotes = false; + position_buffer++; + start_buffer = position_buffer; + verification_positions.end_of_last_line = position_buffer; + if (carriage_return) { + // \r newline, go to special state that parses an optional \n afterwards + // optionally skips a newline (\n) character, which allows \r\n to be interpreted as a single line + if (!BufferRemainder()) { + goto final_state; + } + if ((*buffer)[position_buffer] == '\n') { + if (options.new_line == NewLineIdentifier::SINGLE) { + error_message = "Wrong NewLine Identifier. Expecting \\r\\n"; + return false; + } + // newline after carriage return: skip + // increase position by 1 and move start to the new position + start_buffer = ++position_buffer; + + SkipEmptyLines(); + verification_positions.end_of_last_line = position_buffer; + start_buffer = position_buffer; + if (reached_remainder_state) { + goto final_state; + } + } else { + if (options.new_line == NewLineIdentifier::CARRY_ON) { + error_message = "Wrong NewLine Identifier. Expecting \\r or \\n"; + return false; + } + } + if (!BufferRemainder()) { + goto final_state; + } + if (reached_remainder_state || finished_chunk) { + goto final_state; + } + goto value_start; + } else { + if (options.new_line == NewLineIdentifier::CARRY_ON) { + error_message = "Wrong NewLine Identifier. Expecting \\r or \\n"; + return false; + } + if (reached_remainder_state) { + goto final_state; + } + if (!BufferRemainder()) { + goto final_state; + } + SkipEmptyLines(); + verification_positions.end_of_last_line = position_buffer; + start_buffer = position_buffer; + // \n newline, move to value start + if (finished_chunk) { + goto final_state; + } + goto value_start; + } +} +in_quotes: + /* state: in_quotes this state parses the remainder of a quoted value*/ + has_quotes = true; + position_buffer++; + for (; position_buffer < end_buffer; position_buffer++) { + auto c = (*buffer)[position_buffer]; + if (c == options.quote[0]) { + // quote: move to unquoted state + goto unquote; + } else if (c == options.escape[0]) { + // escape: store the escaped position and move to handle_escape state + escape_positions.push_back(position_buffer - start_buffer); + goto handle_escape; + } + } + if (!BufferRemainder()) { + if (buffer->buffer->IsCSVFileLastBuffer()) { + if (try_add_line) { + return false; + } + // still in quoted state at the end of the file or at the end of a buffer when running multithreaded, error: + throw InvalidInputException("Error in file \"%s\" on line %s: unterminated quotes. (%s)", options.file_path, + GetLineNumberStr(linenr, linenr_estimated, buffer->local_batch_index).c_str(), + options.ToString()); + } else { + goto final_state; + } + } else { + position_buffer--; + goto in_quotes; + } + +unquote : { + /* state: unquote: this state handles the state directly after we unquote*/ + // + // in this state we expect either another quote (entering the quoted state again, and escaping the quote) + // or a delimiter/newline, ending the current value and moving on to the next value + position_buffer++; + if (!BufferRemainder()) { + offset = 1; + goto final_state; + } + auto c = (*buffer)[position_buffer]; + if (c == options.quote[0] && (options.escape.empty() || options.escape[0] == options.quote[0])) { + // escaped quote, return to quoted state and store escape position + escape_positions.push_back(position_buffer - start_buffer); + goto in_quotes; + } else if (c == options.delimiter[0]) { + // delimiter, add value + offset = 1; + goto add_value; + } else if (StringUtil::CharacterIsNewline(c)) { + offset = 1; + // FIXME: should this be an assertion? + D_ASSERT(try_add_line || (!try_add_line && column == parse_chunk.ColumnCount() - 1)); + goto add_row; + } else if (position_buffer >= end_buffer) { + // reached end of buffer + offset = 1; + goto final_state; + } else { + 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, buffer->local_batch_index).c_str(), + options.ToString()); + return false; + } +} +handle_escape : { + /* state: handle_escape */ + // escape should be followed by a quote or another escape character + position_buffer++; + if (!BufferRemainder()) { + goto final_state; + } + if (position_buffer >= buffer_size && buffer->buffer->IsCSVFileLastBuffer()) { + 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, buffer->local_batch_index).c_str(), options.ToString()); + return false; + } + if ((*buffer)[position_buffer] != options.quote[0] && (*buffer)[position_buffer] != 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, buffer->local_batch_index).c_str(), options.ToString()); + return false; + } + // escape was followed by quote or escape, go back to quoted state + goto in_quotes; +} +final_state : { + /* state: final_stage reached after we finished reading the end_buffer of the csv buffer */ + // reset end buffer + end_buffer = buffer->buffer_end; + if (position_buffer == end_buffer) { + reached_remainder_state = false; + } + if (finished_chunk) { + if (position_buffer >= end_buffer) { + if (position_buffer == end_buffer && StringUtil::CharacterIsNewline((*buffer)[position_buffer - 1]) && + position_buffer < buffer_size) { + // last position is a new line, we still have to go through one more line of this buffer + finished = false; + } else { + finished = true; + } + } + buffer->lines_read += insert_chunk.size(); + return true; + } + // If this is the last buffer, we have to read the last value + if (buffer->buffer->IsCSVFileLastBuffer() || (buffer->next_buffer && buffer->next_buffer->IsCSVFileLastBuffer())) { + if (column > 0 || start_buffer != position_buffer || try_add_line || + (insert_chunk.data.size() == 1 && start_buffer != position_buffer)) { + // remaining values to be added to the chunk + auto str_value = buffer->GetValue(start_buffer, position_buffer, offset); + if (!AllNewLine(str_value, insert_chunk.data.size()) || offset == 0) { + AddValue(str_value, column, escape_positions, has_quotes, buffer->local_batch_index); + if (try_add_line) { + bool success = column == return_types.size(); + if (success) { + auto cur_linenr = linenr; + AddRow(insert_chunk, column, error_message, buffer->local_batch_index); + success = Flush(insert_chunk, buffer->local_batch_index); + linenr = cur_linenr; + } + parse_chunk.Reset(); + reached_remainder_state = false; + return success; + } else { + VerifyLineLength(position_buffer - line_start); + line_start = position_buffer; + AddRow(insert_chunk, column, error_message, buffer->local_batch_index); + verification_positions.end_of_last_line = position_buffer; + } + } + } + } + // flush the parsed chunk and finalize parsing + if (mode == ParserMode::PARSING) { + Flush(insert_chunk, buffer->local_batch_index); + buffer->lines_read += insert_chunk.size(); + } + if (position_buffer - verification_positions.end_of_last_line > options.buffer_size) { + error_message = "Line does not fit in one buffer. Increase the buffer size."; + return false; + } + end_buffer = buffer_size; + SkipEmptyLines(); + end_buffer = buffer->buffer_end; + verification_positions.end_of_last_line = position_buffer; + if (position_buffer >= end_buffer) { + if (position_buffer >= end_buffer) { + if (position_buffer == end_buffer && StringUtil::CharacterIsNewline((*buffer)[position_buffer - 1]) && + position_buffer < buffer_size) { + // last position is a new line, we still have to go through one more line of this buffer + finished = false; + } else { + finished = true; + } + } + } + return true; +}; +} + +void ParallelCSVReader::ParseCSV(DataChunk &insert_chunk) { + string error_message; + if (!TryParseCSV(ParserMode::PARSING, insert_chunk, error_message)) { + throw InvalidInputException(error_message); + } +} + +idx_t ParallelCSVReader::GetLineError(idx_t line_error, idx_t buffer_idx, bool stop_at_first) { + while (true) { + if (buffer->line_info->CanItGetLine(file_idx, buffer_idx)) { + auto cur_start = verification_positions.beginning_of_first_line + buffer->buffer->GetCSVGlobalStart(); + return buffer->line_info->GetLine(buffer_idx, line_error, file_idx, cur_start, false, stop_at_first); + } + } +} + +bool ParallelCSVReader::TryParseCSV(ParserMode mode) { + DataChunk dummy_chunk; + string error_message; + return TryParseCSV(mode, dummy_chunk, error_message); +} + +void ParallelCSVReader::ParseCSV(ParserMode mode) { + DataChunk dummy_chunk; + string error_message; + if (!TryParseCSV(mode, dummy_chunk, error_message)) { + throw InvalidInputException(error_message); + } +} + +bool ParallelCSVReader::TryParseCSV(ParserMode parser_mode, DataChunk &insert_chunk, string &error_message) { + mode = parser_mode; + return TryParseSimpleCSV(insert_chunk, error_message); +} + +} // namespace duckdb diff --git a/src/duckdb/src/execution/operator/persistent/physical_export.cpp b/src/duckdb/src/execution/operator/persistent/physical_export.cpp index ccb9cd31..733b01f7 100644 --- a/src/duckdb/src/execution/operator/persistent/physical_export.cpp +++ b/src/duckdb/src/execution/operator/persistent/physical_export.cpp @@ -19,6 +19,12 @@ using std::stringstream; void ReorderTableEntries(catalog_entry_vector_t &tables); +PhysicalExport::PhysicalExport(vector types, CopyFunction function, unique_ptr info, + idx_t estimated_cardinality, unique_ptr exported_tables) + : PhysicalOperator(PhysicalOperatorType::EXPORT, std::move(types), estimated_cardinality), + function(std::move(function)), info(std::move(info)), exported_tables(std::move(exported_tables)) { +} + static void WriteCatalogEntries(stringstream &ss, catalog_entry_vector_t &entries) { for (auto &entry : entries) { if (entry.get().internal) { @@ -121,6 +127,10 @@ void PhysicalExport::ExtractEntries(ClientContext &context, vectordata.size(); i++) { + entries.tables.push_back(exported_tables->data[i].entry); } // order macro's by timestamp so nested macro's are imported nicely @@ -252,8 +262,8 @@ SourceResultType PhysicalExport::GetData(ExecutionContext &context, DataChunk &c // write the load.sql file // for every table, we write COPY INTO statement with the specified options stringstream load_ss; - for (idx_t i = 0; i < exported_tables.data.size(); i++) { - auto exported_table_info = exported_tables.data[i].table_data; + for (idx_t i = 0; i < exported_tables->data.size(); i++) { + auto exported_table_info = exported_tables->data[i].table_data; WriteCopyStatement(fs, load_ss, *info, exported_table_info, function); } WriteStringStreamToFile(fs, load_ss, fs.JoinPath(info->file_path, "load.sql")); diff --git a/src/duckdb/src/execution/operator/schema/physical_create_index.cpp b/src/duckdb/src/execution/operator/schema/physical_create_index.cpp new file mode 100644 index 00000000..f4e5f2ae --- /dev/null +++ b/src/duckdb/src/execution/operator/schema/physical_create_index.cpp @@ -0,0 +1,207 @@ +#include "duckdb/execution/operator/schema/physical_create_index.hpp" + +#include "duckdb/catalog/catalog_entry/duck_table_entry.hpp" +#include "duckdb/catalog/catalog_entry/table_catalog_entry.hpp" +#include "duckdb/catalog/catalog_entry/duck_index_entry.hpp" +#include "duckdb/main/client_context.hpp" +#include "duckdb/storage/index.hpp" +#include "duckdb/storage/storage_manager.hpp" +#include "duckdb/storage/table/append_state.hpp" +#include "duckdb/main/database_manager.hpp" +#include "duckdb/execution/index/art/art_key.hpp" +#include "duckdb/execution/index/art/node.hpp" +#include "duckdb/execution/index/art/leaf.hpp" + +namespace duckdb { + +PhysicalCreateIndex::PhysicalCreateIndex(LogicalOperator &op, TableCatalogEntry &table_p, + const vector &column_ids, unique_ptr info, + vector> unbound_expressions, + idx_t estimated_cardinality, const bool sorted) + : PhysicalOperator(PhysicalOperatorType::CREATE_INDEX, op.types, estimated_cardinality), + table(table_p.Cast()), info(std::move(info)), unbound_expressions(std::move(unbound_expressions)), + sorted(sorted) { + // convert virtual column ids to storage column ids + for (auto &column_id : column_ids) { + storage_ids.push_back(table.GetColumns().LogicalToPhysical(LogicalIndex(column_id)).index); + } +} + +//===--------------------------------------------------------------------===// +// Sink +//===--------------------------------------------------------------------===// + +class CreateIndexGlobalSinkState : public GlobalSinkState { +public: + //! Global index to be added to the table + unique_ptr global_index; +}; + +class CreateIndexLocalSinkState : public LocalSinkState { +public: + explicit CreateIndexLocalSinkState(ClientContext &context) : arena_allocator(Allocator::Get(context)) {}; + + unique_ptr local_index; + ArenaAllocator arena_allocator; + vector keys; + DataChunk key_chunk; + vector key_column_ids; +}; + +unique_ptr PhysicalCreateIndex::GetGlobalSinkState(ClientContext &context) const { + auto state = make_uniq(); + + // create the global index + switch (info->index_type) { + case IndexType::ART: { + auto &storage = table.GetStorage(); + state->global_index = make_uniq(storage_ids, TableIOManager::Get(storage), unbound_expressions, + info->constraint_type, storage.db); + break; + } + default: + throw InternalException("Unimplemented index type"); + } + return (std::move(state)); +} + +unique_ptr PhysicalCreateIndex::GetLocalSinkState(ExecutionContext &context) const { + auto state = make_uniq(context.client); + + // create the local index + switch (info->index_type) { + case IndexType::ART: { + auto &storage = table.GetStorage(); + state->local_index = make_uniq(storage_ids, TableIOManager::Get(storage), unbound_expressions, + info->constraint_type, storage.db); + break; + } + default: + throw InternalException("Unimplemented index type"); + } + state->keys = vector(STANDARD_VECTOR_SIZE); + state->key_chunk.Initialize(Allocator::Get(context.client), state->local_index->logical_types); + + for (idx_t i = 0; i < state->key_chunk.ColumnCount(); i++) { + state->key_column_ids.push_back(i); + } + return std::move(state); +} + +SinkResultType PhysicalCreateIndex::SinkUnsorted(Vector &row_identifiers, OperatorSinkInput &input) const { + + auto &l_state = input.local_state.Cast(); + auto count = l_state.key_chunk.size(); + + // get the corresponding row IDs + row_identifiers.Flatten(count); + auto row_ids = FlatVector::GetData(row_identifiers); + + // insert the row IDs + auto &art = l_state.local_index->Cast(); + for (idx_t i = 0; i < count; i++) { + if (!art.Insert(*art.tree, l_state.keys[i], 0, row_ids[i])) { + throw ConstraintException("Data contains duplicates on indexed column(s)"); + } + } + + return SinkResultType::NEED_MORE_INPUT; +} + +SinkResultType PhysicalCreateIndex::SinkSorted(Vector &row_identifiers, OperatorSinkInput &input) const { + + auto &l_state = input.local_state.Cast(); + auto &storage = table.GetStorage(); + auto &l_index = l_state.local_index; + + // create an ART from the chunk + auto art = make_uniq(l_index->column_ids, l_index->table_io_manager, l_index->unbound_expressions, + l_index->constraint_type, storage.db, l_index->Cast().allocators); + if (!art->ConstructFromSorted(l_state.key_chunk.size(), l_state.keys, row_identifiers)) { + throw ConstraintException("Data contains duplicates on indexed column(s)"); + } + + // merge into the local ART + if (!l_index->MergeIndexes(*art)) { + throw ConstraintException("Data contains duplicates on indexed column(s)"); + } + + return SinkResultType::NEED_MORE_INPUT; +} + +SinkResultType PhysicalCreateIndex::Sink(ExecutionContext &context, DataChunk &chunk, OperatorSinkInput &input) const { + + D_ASSERT(chunk.ColumnCount() >= 2); + + // generate the keys for the given input + auto &l_state = input.local_state.Cast(); + l_state.key_chunk.ReferenceColumns(chunk, l_state.key_column_ids); + l_state.arena_allocator.Reset(); + ART::GenerateKeys(l_state.arena_allocator, l_state.key_chunk, l_state.keys); + + // insert the keys and their corresponding row IDs + auto &row_identifiers = chunk.data[chunk.ColumnCount() - 1]; + if (sorted) { + return SinkSorted(row_identifiers, input); + } + return SinkUnsorted(row_identifiers, input); +} + +SinkCombineResultType PhysicalCreateIndex::Combine(ExecutionContext &context, OperatorSinkCombineInput &input) const { + + auto &gstate = input.global_state.Cast(); + auto &lstate = input.local_state.Cast(); + + // merge the local index into the global index + if (!gstate.global_index->MergeIndexes(*lstate.local_index)) { + throw ConstraintException("Data contains duplicates on indexed column(s)"); + } + + return SinkCombineResultType::FINISHED; +} + +SinkFinalizeType PhysicalCreateIndex::Finalize(Pipeline &pipeline, Event &event, ClientContext &context, + OperatorSinkFinalizeInput &input) const { + + // here, we set the resulting global index as the newly created index of the table + auto &state = input.global_state.Cast(); + + // vacuum excess memory and verify + state.global_index->Vacuum(); + D_ASSERT(!state.global_index->VerifyAndToString(true).empty()); + + auto &storage = table.GetStorage(); + if (!storage.IsRoot()) { + throw TransactionException("Transaction conflict: cannot add an index to a table that has been altered!"); + } + + auto &schema = table.schema; + auto index_entry = schema.CreateIndex(context, *info, table).get(); + if (!index_entry) { + D_ASSERT(info->on_conflict == OnCreateConflict::IGNORE_ON_CONFLICT); + // index already exists, but error ignored because of IF NOT EXISTS + return SinkFinalizeType::READY; + } + auto &index = index_entry->Cast(); + + index.index = state.global_index.get(); + index.info = storage.info; + for (auto &parsed_expr : info->parsed_expressions) { + index.parsed_expressions.push_back(parsed_expr->Copy()); + } + + // add index to storage + storage.info->indexes.AddIndex(std::move(state.global_index)); + return SinkFinalizeType::READY; +} + +//===--------------------------------------------------------------------===// +// Source +//===--------------------------------------------------------------------===// + +SourceResultType PhysicalCreateIndex::GetData(ExecutionContext &context, DataChunk &chunk, + OperatorSourceInput &input) const { + return SourceResultType::FINISHED; +} + +} // namespace duckdb diff --git a/src/duckdb/src/execution/partitionable_hashtable.cpp b/src/duckdb/src/execution/partitionable_hashtable.cpp new file mode 100644 index 00000000..6042932e --- /dev/null +++ b/src/duckdb/src/execution/partitionable_hashtable.cpp @@ -0,0 +1,207 @@ +#include "duckdb/execution/partitionable_hashtable.hpp" + +#include "duckdb/common/radix_partitioning.hpp" + +namespace duckdb { + +RadixPartitionInfo::RadixPartitionInfo(const idx_t n_partitions_upper_bound) + : n_partitions(PreviousPowerOfTwo(n_partitions_upper_bound)), + radix_bits(RadixPartitioning::RadixBits(n_partitions)), radix_mask(RadixPartitioning::Mask(radix_bits)), + radix_shift(RadixPartitioning::Shift(radix_bits)) { + + D_ASSERT(radix_bits <= RadixPartitioning::MAX_RADIX_BITS); + D_ASSERT(n_partitions > 0); + D_ASSERT(n_partitions == RadixPartitioning::NumberOfPartitions(radix_bits)); + D_ASSERT(IsPowerOfTwo(n_partitions)); +} + +PartitionableHashTable::PartitionableHashTable(ClientContext &context, Allocator &allocator, + RadixPartitionInfo &partition_info_p, vector group_types_p, + vector payload_types_p, + vector bindings_p) + : context(context), allocator(allocator), group_types(std::move(group_types_p)), + payload_types(std::move(payload_types_p)), bindings(std::move(bindings_p)), is_partitioned(false), + partition_info(partition_info_p), hashes(LogicalType::HASH), hashes_subset(LogicalType::HASH) { + + sel_vectors.resize(partition_info.n_partitions); + sel_vector_sizes.resize(partition_info.n_partitions); + group_subset.Initialize(allocator, group_types); + if (!payload_types.empty()) { + payload_subset.Initialize(allocator, payload_types); + } + + for (hash_t r = 0; r < partition_info.n_partitions; r++) { + sel_vectors[r].Initialize(); + } + + RowLayout layout; + layout.Initialize(group_types, AggregateObject::CreateAggregateObjects(bindings)); + tuple_size = layout.GetRowWidth(); +} + +HtEntryType PartitionableHashTable::GetHTEntrySize() { + // we need at least STANDARD_VECTOR_SIZE entries to fit in the hash table + if (GroupedAggregateHashTable::GetMaxCapacity(HtEntryType::HT_WIDTH_32, tuple_size) < STANDARD_VECTOR_SIZE) { + return HtEntryType::HT_WIDTH_64; + } + return HtEntryType::HT_WIDTH_32; +} + +bool OverMemoryLimit(ClientContext &context, const bool is_partitioned, const RadixPartitionInfo &partition_info, + const GroupedAggregateHashTable &ht) { + const auto n_partitions = is_partitioned ? partition_info.n_partitions : 1; + const auto max_memory = BufferManager::GetBufferManager(context).GetMaxMemory(); + const auto num_threads = TaskScheduler::GetScheduler(context).NumberOfThreads(); + const auto memory_per_partition = 0.6 * max_memory / num_threads / n_partitions; + return ht.TotalSize() > memory_per_partition; +} + +idx_t PartitionableHashTable::ListAddChunk(HashTableList &list, DataChunk &groups, Vector &group_hashes, + DataChunk &payload, const unsafe_vector &filter) { + // If this is false, a single AddChunk would overflow the max capacity + D_ASSERT(list.empty() || groups.size() <= list.back()->MaxCapacity()); + if (list.empty() || list.back()->Count() + groups.size() >= list.back()->MaxCapacity() || + OverMemoryLimit(context, is_partitioned, partition_info, *list.back())) { + idx_t new_capacity = GroupedAggregateHashTable::InitialCapacity(); + if (!list.empty()) { + new_capacity = list.back()->Capacity(); + // early release first part of ht and prevent adding of more data + list.back()->Finalize(); + } + list.push_back(make_uniq(context, allocator, group_types, payload_types, bindings, + GetHTEntrySize(), new_capacity)); + } + return list.back()->AddChunk(append_state, groups, group_hashes, payload, filter); +} + +idx_t PartitionableHashTable::AddChunk(DataChunk &groups, DataChunk &payload, bool do_partition, + const unsafe_vector &filter) { + groups.Hash(hashes); + + // we partition when we are asked to or when the unpartitioned ht runs out of space + if (!IsPartitioned() && do_partition) { + Partition(false); + } + + if (!IsPartitioned()) { + return ListAddChunk(unpartitioned_hts, groups, hashes, payload, filter); + } + + // makes no sense to do this with 1 partition + D_ASSERT(partition_info.n_partitions > 0); + + for (hash_t r = 0; r < partition_info.n_partitions; r++) { + sel_vector_sizes[r] = 0; + } + + hashes.Flatten(groups.size()); + auto hashes_ptr = FlatVector::GetData(hashes); + + // Determine for every partition how much data will be sinked into it + for (idx_t i = 0; i < groups.size(); i++) { + auto partition = partition_info.GetHashPartition(hashes_ptr[i]); + D_ASSERT(partition < partition_info.n_partitions); + sel_vectors[partition].set_index(sel_vector_sizes[partition]++, i); + } + +#ifdef DEBUG + // make sure we have lost no rows + idx_t total_count = 0; + for (idx_t r = 0; r < partition_info.n_partitions; r++) { + total_count += sel_vector_sizes[r]; + } + D_ASSERT(total_count == groups.size()); +#endif + idx_t group_count = 0; + for (hash_t r = 0; r < partition_info.n_partitions; r++) { + group_subset.Slice(groups, sel_vectors[r], sel_vector_sizes[r]); + if (!payload_types.empty()) { + payload_subset.Slice(payload, sel_vectors[r], sel_vector_sizes[r]); + } else { + payload_subset.SetCardinality(sel_vector_sizes[r]); + } + hashes_subset.Slice(hashes, sel_vectors[r], sel_vector_sizes[r]); + + group_count += ListAddChunk(radix_partitioned_hts[r], group_subset, hashes_subset, payload_subset, filter); + } + return group_count; +} + +void PartitionableHashTable::Partition(bool sink_done) { + D_ASSERT(!IsPartitioned()); + D_ASSERT(radix_partitioned_hts.empty()); + D_ASSERT(partition_info.n_partitions > 1); + + vector partition_hts(partition_info.n_partitions); + radix_partitioned_hts.resize(partition_info.n_partitions); + for (auto &unpartitioned_ht : unpartitioned_hts) { + for (idx_t r = 0; r < partition_info.n_partitions; r++) { + radix_partitioned_hts[r].push_back(make_uniq( + context, allocator, group_types, payload_types, bindings, GetHTEntrySize())); + partition_hts[r] = radix_partitioned_hts[r].back().get(); + } + unpartitioned_ht->Partition(partition_hts, partition_info.radix_bits, sink_done); + unpartitioned_ht.reset(); + } + unpartitioned_hts.clear(); + is_partitioned = true; +} + +bool PartitionableHashTable::IsPartitioned() { + return is_partitioned; +} + +HashTableList PartitionableHashTable::GetPartition(idx_t partition) { + D_ASSERT(IsPartitioned()); + D_ASSERT(partition < partition_info.n_partitions); + D_ASSERT(radix_partitioned_hts.size() > partition); + return std::move(radix_partitioned_hts[partition]); +} + +HashTableList PartitionableHashTable::GetUnpartitioned() { + D_ASSERT(!IsPartitioned()); + return std::move(unpartitioned_hts); +} + +idx_t PartitionableHashTable::GetPartitionCount(idx_t partition) const { + idx_t total_size = 0; + for (const auto &ht : radix_partitioned_hts[partition]) { + total_size += ht->Count(); + } + return total_size; +} + +idx_t PartitionableHashTable::GetPartitionSize(idx_t partition) const { + idx_t total_size = 0; + for (const auto &ht : radix_partitioned_hts[partition]) { + total_size += ht->DataSize(); + } + return total_size; +} + +void PartitionableHashTable::Finalize() { + if (IsPartitioned()) { + for (auto &ht_list : radix_partitioned_hts) { + for (auto &ht : ht_list) { + D_ASSERT(ht); + ht->Finalize(); + } + } + } else { + for (auto &ht : unpartitioned_hts) { + D_ASSERT(ht); + ht->Finalize(); + } + } +} + +void PartitionableHashTable::Append(GroupedAggregateHashTable &ht) { + if (unpartitioned_hts.empty()) { + unpartitioned_hts.push_back(make_uniq(context, allocator, group_types, payload_types, + bindings, GetHTEntrySize(), + GroupedAggregateHashTable::InitialCapacity())); + } + unpartitioned_hts.back()->Append(ht); +} + +} // namespace duckdb diff --git a/src/duckdb/src/execution/perfect_aggregate_hashtable.cpp b/src/duckdb/src/execution/perfect_aggregate_hashtable.cpp index 4fa6f08f..c378e61e 100644 --- a/src/duckdb/src/execution/perfect_aggregate_hashtable.cpp +++ b/src/duckdb/src/execution/perfect_aggregate_hashtable.cpp @@ -130,7 +130,12 @@ void PerfectAggregateHashTable::AddChunk(DataChunk &groups, DataChunk &payload) // compute the actual pointer to the data by adding it to the base HT pointer and multiplying by the tuple size for (idx_t i = 0; i < groups.size(); i++) { const auto group = address_data[i]; - D_ASSERT(group < total_groups); + if (group >= total_groups) { + throw InvalidInputException("Perfect hash aggregate: aggregate group %llu exceeded total groups %llu. This " + "likely means that the statistics in your data source are corrupt.\n* PRAGMA " + "disable_optimizer to disable optimizations that rely on correct statistics", + group, total_groups); + } group_is_set[group] = true; address_data[i] = uintptr_t(data) + group * tuple_size; } diff --git a/src/duckdb/src/execution/physical_plan/plan_comparison_join.cpp b/src/duckdb/src/execution/physical_plan/plan_comparison_join.cpp index 31fcf3ba..5a2345bc 100644 --- a/src/duckdb/src/execution/physical_plan/plan_comparison_join.cpp +++ b/src/duckdb/src/execution/physical_plan/plan_comparison_join.cpp @@ -117,10 +117,6 @@ void CheckForPerfectJoinOpt(LogicalComparisonJoin &op, PerfectHashJoinStats &joi if (join_state.build_range > MAX_BUILD_SIZE) { return; } - if (NumericStats::Min(stats_build) <= NumericStats::Min(stats_probe) && - NumericStats::Max(stats_probe) <= NumericStats::Max(stats_build)) { - join_state.is_probe_in_domain = true; - } join_state.is_build_small = true; return; } diff --git a/src/duckdb/src/execution/physical_plan/plan_create_index.cpp b/src/duckdb/src/execution/physical_plan/plan_create_index.cpp index abfcd628..a7e28444 100644 --- a/src/duckdb/src/execution/physical_plan/plan_create_index.cpp +++ b/src/duckdb/src/execution/physical_plan/plan_create_index.cpp @@ -1,24 +1,16 @@ #include "duckdb/catalog/catalog_entry/table_catalog_entry.hpp" -#include "duckdb/execution/operator/projection/physical_projection.hpp" #include "duckdb/execution/operator/filter/physical_filter.hpp" -#include "duckdb/execution/operator/scan/physical_table_scan.hpp" #include "duckdb/execution/operator/schema/physical_create_art_index.hpp" -#include "duckdb/execution/operator/order/physical_order.hpp" #include "duckdb/execution/physical_plan_generator.hpp" #include "duckdb/planner/operator/logical_create_index.hpp" -#include "duckdb/planner/operator/logical_get.hpp" -#include "duckdb/planner/expression/bound_operator_expression.hpp" -#include "duckdb/planner/expression/bound_reference_expression.hpp" -#include "duckdb/planner/table_filter.hpp" + +#include "duckdb/main/database.hpp" +#include "duckdb/execution/index/index_type.hpp" +#include "duckdb/execution/index/bound_index.hpp" namespace duckdb { unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalCreateIndex &op) { - // generate a physical plan for the parallel index creation which consists of the following operators - // table scan - projection (for expression execution) - filter (NOT NULL) - order (if applicable) - create index - - D_ASSERT(op.children.size() == 1); - auto table_scan = CreatePlan(*op.children[0]); // validate that all expressions contain valid scalar functions // e.g. get_current_timestamp(), random(), and sequence values are not allowed as index keys @@ -30,12 +22,14 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalCreateInde } } - // if we get here and the index type is not ART, we throw an exception - // because we don't support any other index type yet. However, an operator extension could have - // replaced this part of the plan with a different index creation operator. - if (op.info->index_type != ART::TYPE_NAME) { + // Do we have a valid index type? + const auto index_type = context.db->config.GetIndexTypes().FindByName(op.info->index_type); + if (!index_type) { throw BinderException("Unknown index type: " + op.info->index_type); } + if (!index_type->create_plan) { + throw InternalException("Index type '%s' is missing a create_plan function", op.info->index_type); + } // table scan operator for index key columns and row IDs dependencies.AddDependency(op.table); @@ -43,78 +37,11 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalCreateInde D_ASSERT(op.info->scan_types.size() - 1 <= op.info->names.size()); D_ASSERT(op.info->scan_types.size() - 1 <= op.info->column_ids.size()); - // projection to execute expressions on the key columns - - vector new_column_types; - vector> select_list; - for (idx_t i = 0; i < op.expressions.size(); i++) { - new_column_types.push_back(op.expressions[i]->return_type); - select_list.push_back(std::move(op.expressions[i])); - } - new_column_types.emplace_back(LogicalType::ROW_TYPE); - select_list.push_back(make_uniq(LogicalType::ROW_TYPE, op.info->scan_types.size() - 1)); - - auto projection = make_uniq(new_column_types, std::move(select_list), op.estimated_cardinality); - projection->children.push_back(std::move(table_scan)); - - // filter operator for IS_NOT_NULL on each key column - - vector filter_types; - vector> filter_select_list; - - for (idx_t i = 0; i < new_column_types.size() - 1; i++) { - filter_types.push_back(new_column_types[i]); - auto is_not_null_expr = - make_uniq(ExpressionType::OPERATOR_IS_NOT_NULL, LogicalType::BOOLEAN); - auto bound_ref = make_uniq(new_column_types[i], i); - is_not_null_expr->children.push_back(std::move(bound_ref)); - filter_select_list.push_back(std::move(is_not_null_expr)); - } - - auto null_filter = - make_uniq(std::move(filter_types), std::move(filter_select_list), op.estimated_cardinality); - null_filter->types.emplace_back(LogicalType::ROW_TYPE); - null_filter->children.push_back(std::move(projection)); - - // determine if we sort the data prior to index creation - // we don't sort, if either VARCHAR or compound key - auto perform_sorting = true; - if (op.unbound_expressions.size() > 1) { - perform_sorting = false; - } else if (op.unbound_expressions[0]->return_type.InternalType() == PhysicalType::VARCHAR) { - perform_sorting = false; - } - - // actual physical create index operator - - auto physical_create_index = - make_uniq(op, op.table, op.info->column_ids, std::move(op.info), - std::move(op.unbound_expressions), op.estimated_cardinality, perform_sorting); - - if (perform_sorting) { - - // optional order operator - vector orders; - vector projections; - for (idx_t i = 0; i < new_column_types.size() - 1; i++) { - auto col_expr = make_uniq_base(new_column_types[i], i); - orders.emplace_back(OrderType::ASCENDING, OrderByNullType::NULLS_FIRST, std::move(col_expr)); - projections.emplace_back(i); - } - projections.emplace_back(new_column_types.size() - 1); - - auto physical_order = make_uniq(new_column_types, std::move(orders), std::move(projections), - op.estimated_cardinality); - physical_order->children.push_back(std::move(null_filter)); - - physical_create_index->children.push_back(std::move(physical_order)); - } else { - - // no ordering - physical_create_index->children.push_back(std::move(null_filter)); - } + D_ASSERT(op.children.size() == 1); + auto table_scan = CreatePlan(*op.children[0]); - return std::move(physical_create_index); + PlanIndexInput input(context, op, table_scan); + return index_type->create_plan(input); } } // namespace duckdb diff --git a/src/duckdb/src/execution/physical_plan/plan_export.cpp b/src/duckdb/src/execution/physical_plan/plan_export.cpp index 3179ec6f..0f4237d9 100644 --- a/src/duckdb/src/execution/physical_plan/plan_export.cpp +++ b/src/duckdb/src/execution/physical_plan/plan_export.cpp @@ -11,7 +11,7 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalExport &op throw PermissionException("Export is disabled through configuration"); } auto export_node = make_uniq(op.types, op.function, std::move(op.copy_info), - op.estimated_cardinality, op.exported_tables); + op.estimated_cardinality, std::move(op.exported_tables)); // plan the underlying copy statements, if any if (!op.children.empty()) { auto plan = CreatePlan(*op.children[0]); diff --git a/src/duckdb/src/execution/physical_plan/plan_get.cpp b/src/duckdb/src/execution/physical_plan/plan_get.cpp index 056d291f..2f4c65d3 100644 --- a/src/duckdb/src/execution/physical_plan/plan_get.cpp +++ b/src/duckdb/src/execution/physical_plan/plan_get.cpp @@ -159,7 +159,7 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalGet &op) { vector> expressions; for (auto &column_id : column_ids) { if (column_id == COLUMN_IDENTIFIER_ROW_ID) { - types.emplace_back(LogicalType::BIGINT); + types.emplace_back(LogicalType::ROW_TYPE); expressions.push_back(make_uniq(Value::BIGINT(0))); } else { auto type = op.returned_types[column_id]; diff --git a/src/duckdb/src/execution/reservoir_sample.cpp b/src/duckdb/src/execution/reservoir_sample.cpp index eb20982b..284e03fa 100644 --- a/src/duckdb/src/execution/reservoir_sample.cpp +++ b/src/duckdb/src/execution/reservoir_sample.cpp @@ -79,7 +79,7 @@ unique_ptr ReservoirSample::GetChunk() { for (idx_t i = samples_remaining; i < collected_sample_count; i++) { sel.set_index(i - samples_remaining, i); } - ret->Initialize(allocator, reservoir_types.begin(), reservoir_types.end(), STANDARD_VECTOR_SIZE); + ret->Initialize(allocator, reservoir_types); ret->Slice(*reservoir_data_chunk, sel, STANDARD_VECTOR_SIZE); ret->SetCardinality(STANDARD_VECTOR_SIZE); // reduce capacity and cardinality of the sample data chunk diff --git a/src/duckdb/src/execution/window_executor.cpp b/src/duckdb/src/execution/window_executor.cpp index 56397f7a..93774105 100644 --- a/src/duckdb/src/execution/window_executor.cpp +++ b/src/duckdb/src/execution/window_executor.cpp @@ -1671,23 +1671,23 @@ void WindowLeadLagExecutor::EvaluateInternal(WindowExecutorGlobalState &gstate, // else offset is zero, so don't move. if (can_shift) { + const auto target_limit = MinValue(partition_end[i], row_end) - row_idx; if (!delta) { // Copy source[index:index+width] => result[i:] const auto index = NumericCast(val_idx); const auto source_limit = partition_end[i] - index; - const auto target_limit = MinValue(partition_end[i], row_end) - row_idx; const auto width = MinValue(source_limit, target_limit); auto &source = payload_collection.data[0]; VectorOperations::Copy(source, result, index + width, index, i); i += width; row_idx += width; } else if (wexpr.default_expr) { - const auto width = MinValue(delta, count - i); + const auto width = MinValue(delta, target_limit); llstate.leadlag_default.CopyCell(result, i, width); i += width; row_idx += width; } else { - for (idx_t nulls = MinValue(delta, count - i); nulls--; ++i, ++row_idx) { + for (idx_t nulls = MinValue(delta, target_limit); nulls--; ++i, ++row_idx) { FlatVector::SetNull(result, i, true); } } diff --git a/src/duckdb/src/function/pragma/pragma_queries.cpp b/src/duckdb/src/function/pragma/pragma_queries.cpp index cc52edba..39db1f12 100644 --- a/src/duckdb/src/function/pragma/pragma_queries.cpp +++ b/src/duckdb/src/function/pragma/pragma_queries.cpp @@ -145,7 +145,7 @@ string PragmaImportDatabase(ClientContext &context, const FunctionParameters &pa auto &fs = FileSystem::GetFileSystem(context); string final_query; - // read the "shema.sql" and "load.sql" files + // read the "schema.sql" and "load.sql" files vector files = {"schema.sql", "load.sql"}; for (auto &file : files) { auto file_path = fs.JoinPath(parameters.values[0].ToString(), file); diff --git a/src/duckdb/src/function/scalar/strftime_format.cpp b/src/duckdb/src/function/scalar/strftime_format.cpp index 3525519a..8ab46ace 100644 --- a/src/duckdb/src/function/scalar/strftime_format.cpp +++ b/src/duckdb/src/function/scalar/strftime_format.cpp @@ -1185,8 +1185,7 @@ bool StrpTimeFormat::Parse(const char *data, size_t size, ParseResult &result, b case StrTimeSpecifier::YEAR_WITHOUT_CENTURY_PADDED: case StrTimeSpecifier::YEAR_WITHOUT_CENTURY: case StrTimeSpecifier::YEAR_DECIMAL: - // Part of the offset - break; + // Switch to offset parsing case StrTimeSpecifier::WEEKDAY_DECIMAL: // First offset specifier offset_specifier = specifiers[i]; diff --git a/src/duckdb/src/function/scalar/string/concat.cpp b/src/duckdb/src/function/scalar/string/concat.cpp index 18619a5b..0f1d3509 100644 --- a/src/duckdb/src/function/scalar/string/concat.cpp +++ b/src/duckdb/src/function/scalar/string/concat.cpp @@ -45,7 +45,7 @@ static void StringConcatFunction(DataChunk &args, ExpressionState &state, Vector vector result_lengths(args.size(), 0); for (idx_t col_idx = 0; col_idx < args.ColumnCount(); col_idx++) { auto &input = args.data[col_idx]; - D_ASSERT(input.GetType().id() == LogicalTypeId::VARCHAR); + D_ASSERT(input.GetType().InternalType() == PhysicalType::VARCHAR); if (input.GetVectorType() == VectorType::CONSTANT_VECTOR) { if (ConstantVector::IsNull(input)) { // constant null, skip @@ -143,68 +143,60 @@ static void ConcatOperator(DataChunk &args, ExpressionState &state, Vector &resu }); } +struct ListConcatInputData { + ListConcatInputData(Vector &input, Vector &child_vec) : input(input), child_vec(child_vec) { + } + + UnifiedVectorFormat vdata; + Vector &input; + Vector &child_vec; + UnifiedVectorFormat child_vdata; + const list_entry_t *input_entries = nullptr; +}; + static void ListConcatFunction(DataChunk &args, ExpressionState &state, Vector &result) { - D_ASSERT(args.ColumnCount() == 2); auto count = args.size(); - Vector &lhs = args.data[0]; - Vector &rhs = args.data[1]; - if (lhs.GetType().id() == LogicalTypeId::SQLNULL) { - result.Reference(rhs); - return; - } - if (rhs.GetType().id() == LogicalTypeId::SQLNULL) { - result.Reference(lhs); - return; - } - - UnifiedVectorFormat lhs_data; - UnifiedVectorFormat rhs_data; - lhs.ToUnifiedFormat(count, lhs_data); - rhs.ToUnifiedFormat(count, rhs_data); - auto lhs_entries = UnifiedVectorFormat::GetData(lhs_data); - auto rhs_entries = UnifiedVectorFormat::GetData(rhs_data); - - auto lhs_list_size = ListVector::GetListSize(lhs); - auto rhs_list_size = ListVector::GetListSize(rhs); - auto &lhs_child = ListVector::GetEntry(lhs); - auto &rhs_child = ListVector::GetEntry(rhs); - UnifiedVectorFormat lhs_child_data; - UnifiedVectorFormat rhs_child_data; - lhs_child.ToUnifiedFormat(lhs_list_size, lhs_child_data); - rhs_child.ToUnifiedFormat(rhs_list_size, rhs_child_data); - - result.SetVectorType(VectorType::FLAT_VECTOR); auto result_entries = FlatVector::GetData(result); - auto &result_validity = FlatVector::Validity(result); + vector input_data; + for (auto &input : args.data) { + if (input.GetType().id() == LogicalTypeId::SQLNULL) { + // ignore NULL values + continue; + } + + auto &child_vec = ListVector::GetEntry(input); + ListConcatInputData data(input, child_vec); + input.ToUnifiedFormat(count, data.vdata); + + data.input_entries = UnifiedVectorFormat::GetData(data.vdata); + auto list_size = ListVector::GetListSize(input); + + child_vec.ToUnifiedFormat(list_size, data.child_vdata); + + input_data.push_back(std::move(data)); + } idx_t offset = 0; for (idx_t i = 0; i < count; i++) { - auto lhs_list_index = lhs_data.sel->get_index(i); - auto rhs_list_index = rhs_data.sel->get_index(i); - if (!lhs_data.validity.RowIsValid(lhs_list_index) && !rhs_data.validity.RowIsValid(rhs_list_index)) { - result_validity.SetInvalid(i); - continue; - } - result_entries[i].offset = offset; - result_entries[i].length = 0; - if (lhs_data.validity.RowIsValid(lhs_list_index)) { - const auto &lhs_entry = lhs_entries[lhs_list_index]; - result_entries[i].length += lhs_entry.length; - ListVector::Append(result, lhs_child, *lhs_child_data.sel, lhs_entry.offset + lhs_entry.length, - lhs_entry.offset); - } - if (rhs_data.validity.RowIsValid(rhs_list_index)) { - const auto &rhs_entry = rhs_entries[rhs_list_index]; - result_entries[i].length += rhs_entry.length; - ListVector::Append(result, rhs_child, *rhs_child_data.sel, rhs_entry.offset + rhs_entry.length, - rhs_entry.offset); + auto &result_entry = result_entries[i]; + result_entry.offset = offset; + result_entry.length = 0; + for (auto &data : input_data) { + auto list_index = data.vdata.sel->get_index(i); + if (!data.vdata.validity.RowIsValid(list_index)) { + continue; + } + const auto &list_entry = data.input_entries[list_index]; + result_entry.length += list_entry.length; + ListVector::Append(result, data.child_vec, *data.child_vdata.sel, list_entry.offset + list_entry.length, + list_entry.offset); } - offset += result_entries[i].length; + offset += result_entry.length; } - D_ASSERT(ListVector::GetListSize(result) == offset); + ListVector::SetListSize(result, offset); - if (lhs.GetVectorType() == VectorType::CONSTANT_VECTOR && rhs.GetVectorType() == VectorType::CONSTANT_VECTOR) { + if (args.AllConstant()) { result.SetVectorType(VectorType::CONSTANT_VECTOR); } } @@ -235,128 +227,103 @@ static void SetArgumentType(ScalarFunction &bound_function, const LogicalType &t bound_function.return_type = type; } -static void HandleArrayBinding(ClientContext &context, vector> &arguments) { - if (arguments[1]->return_type.id() != LogicalTypeId::ARRAY && - arguments[1]->return_type.id() != LogicalTypeId::SQLNULL) { - throw BinderException("Cannot concatenate types %s and %s", arguments[0]->return_type.ToString(), - arguments[1]->return_type.ToString()); - } - - // if either argument is an array, we cast it to a list - arguments[0] = BoundCastExpression::AddArrayCastToList(context, std::move(arguments[0])); - arguments[1] = BoundCastExpression::AddArrayCastToList(context, std::move(arguments[1])); -} - -static unique_ptr HandleListBinding(ClientContext &context, ScalarFunction &bound_function, - vector> &arguments, bool is_operator) { - // list_concat only accepts two arguments - D_ASSERT(arguments.size() == 2); - - auto &lhs = arguments[0]->return_type; - auto &rhs = arguments[1]->return_type; - - if (lhs.id() == LogicalTypeId::UNKNOWN || rhs.id() == LogicalTypeId::UNKNOWN) { - throw ParameterNotResolvedException(); - } else if (lhs.id() == LogicalTypeId::SQLNULL || rhs.id() == LogicalTypeId::SQLNULL) { - // we mimic postgres behaviour: list_concat(NULL, my_list) = my_list - auto return_type = rhs.id() == LogicalTypeId::SQLNULL ? lhs : rhs; - SetArgumentType(bound_function, return_type, is_operator); - return make_uniq(bound_function.return_type, is_operator); - } - if (lhs.id() != LogicalTypeId::LIST || rhs.id() != LogicalTypeId::LIST) { - throw BinderException("Cannot concatenate types %s and %s", lhs.ToString(), rhs.ToString()); - } - - // Resolve list type +static unique_ptr BindListConcat(ClientContext &context, ScalarFunction &bound_function, + vector> &arguments, bool is_operator) { LogicalType child_type = LogicalType::SQLNULL; - for (const auto &argument : arguments) { - auto &next_type = ListType::GetChildType(argument->return_type); + bool all_null = true; + for (auto &arg : arguments) { + auto &return_type = arg->return_type; + if (return_type == LogicalTypeId::SQLNULL) { + // we mimic postgres behaviour: list_concat(NULL, my_list) = my_list + continue; + } + all_null = false; + LogicalType next_type = LogicalTypeId::INVALID; + switch (return_type.id()) { + case LogicalTypeId::UNKNOWN: + throw ParameterNotResolvedException(); + case LogicalTypeId::LIST: + next_type = ListType::GetChildType(return_type); + break; + case LogicalTypeId::ARRAY: + next_type = ArrayType::GetChildType(return_type); + break; + default: { + string type_list; + for (idx_t arg_idx = 0; arg_idx < arguments.size(); arg_idx++) { + if (!type_list.empty()) { + if (arg_idx + 1 == arguments.size()) { + // last argument + type_list += " and "; + } else { + type_list += ", "; + } + } + type_list += arguments[arg_idx]->return_type.ToString(); + } + throw BinderException(*arg, "Cannot concatenate types %s - an explicit cast is required", type_list); + } + } if (!LogicalType::TryGetMaxLogicalType(context, child_type, next_type, child_type)) { - throw BinderException("Cannot concatenate lists of types %s[] and %s[] - an explicit cast is required", + throw BinderException(*arg, + "Cannot concatenate lists of types %s[] and %s[] - an explicit cast is required", child_type.ToString(), next_type.ToString()); } } + if (all_null) { + // all arguments are NULL + SetArgumentType(bound_function, LogicalTypeId::SQLNULL, is_operator); + return make_uniq(bound_function.return_type, is_operator); + } auto list_type = LogicalType::LIST(child_type); SetArgumentType(bound_function, list_type, is_operator); return make_uniq(bound_function.return_type, is_operator); } -static void FindFirstTwoArguments(vector> &arguments, LogicalTypeId &first_arg, - LogicalTypeId &second_arg) { - first_arg = arguments[0]->return_type.id(); - second_arg = first_arg; - if (arguments.size() > 1) { - second_arg = arguments[1]->return_type.id(); +static unique_ptr BindConcatFunctionInternal(ClientContext &context, ScalarFunction &bound_function, + vector> &arguments, + bool is_operator) { + bool list_concat = false; + // blob concat is only supported for the concat operator - regular concat converts to varchar + bool all_blob = is_operator ? true : false; + for (auto &arg : arguments) { + if (arg->return_type.id() == LogicalTypeId::UNKNOWN) { + throw ParameterNotResolvedException(); + } + if (arg->return_type.id() == LogicalTypeId::LIST || arg->return_type.id() == LogicalTypeId::ARRAY) { + list_concat = true; + } + if (arg->return_type.id() != LogicalTypeId::BLOB) { + all_blob = false; + } } + if (list_concat) { + return BindListConcat(context, bound_function, arguments, is_operator); + } + auto return_type = all_blob ? LogicalType::BLOB : LogicalType::VARCHAR; + + // we can now assume that the input is a string or castable to a string + SetArgumentType(bound_function, return_type, is_operator); + return make_uniq(bound_function.return_type, is_operator); } static unique_ptr BindConcatFunction(ClientContext &context, ScalarFunction &bound_function, vector> &arguments) { - LogicalTypeId first_arg; - LogicalTypeId second_arg; - FindFirstTwoArguments(arguments, first_arg, second_arg); - - if (arguments.size() > 2 && (first_arg == LogicalTypeId::ARRAY || first_arg == LogicalTypeId::LIST)) { - throw BinderException("list_concat only accepts two arguments"); - } - - if (first_arg == LogicalTypeId::ARRAY || second_arg == LogicalTypeId::ARRAY) { - HandleArrayBinding(context, arguments); - FindFirstTwoArguments(arguments, first_arg, second_arg); - } - - if (first_arg == LogicalTypeId::LIST || second_arg == LogicalTypeId::LIST) { - return HandleListBinding(context, bound_function, arguments, false); - } - - // we can now assume that the input is a string or castable to a string - SetArgumentType(bound_function, LogicalType::VARCHAR, false); - return make_uniq(bound_function.return_type, false); + return BindConcatFunctionInternal(context, bound_function, arguments, false); } static unique_ptr BindConcatOperator(ClientContext &context, ScalarFunction &bound_function, vector> &arguments) { - D_ASSERT(arguments.size() == 2); - - LogicalTypeId lhs; - LogicalTypeId rhs; - FindFirstTwoArguments(arguments, lhs, rhs); - - if (lhs == LogicalTypeId::UNKNOWN || rhs == LogicalTypeId::UNKNOWN) { - throw ParameterNotResolvedException(); - } - if (lhs == LogicalTypeId::ARRAY || rhs == LogicalTypeId::ARRAY) { - HandleArrayBinding(context, arguments); - FindFirstTwoArguments(arguments, lhs, rhs); - } - - if (lhs == LogicalTypeId::LIST || rhs == LogicalTypeId::LIST) { - return HandleListBinding(context, bound_function, arguments, true); - } - - LogicalType return_type; - if (lhs == LogicalTypeId::BLOB && rhs == LogicalTypeId::BLOB) { - return_type = LogicalType::BLOB; - } else { - return_type = LogicalType::VARCHAR; - } - - // we can now assume that the input is a string or castable to a string - SetArgumentType(bound_function, return_type, true); - return make_uniq(bound_function.return_type, true); + return BindConcatFunctionInternal(context, bound_function, arguments, true); } static unique_ptr ListConcatStats(ClientContext &context, FunctionStatisticsInput &input) { auto &child_stats = input.child_stats; - D_ASSERT(child_stats.size() == 2); - - auto &left_stats = child_stats[0]; - auto &right_stats = child_stats[1]; - - auto stats = left_stats.ToUnique(); - stats->Merge(right_stats); - + auto stats = child_stats[0].ToUnique(); + for (idx_t i = 1; i < child_stats.size(); i++) { + stats->Merge(child_stats[i]); + } return stats; } diff --git a/src/duckdb/src/function/table/arrow.cpp b/src/duckdb/src/function/table/arrow.cpp index 6c94cf32..634d6d71 100644 --- a/src/duckdb/src/function/table/arrow.cpp +++ b/src/duckdb/src/function/table/arrow.cpp @@ -99,6 +99,19 @@ static unique_ptr GetArrowExtensionType(const ArrowSchemaMetadata &ex auto type_info = make_uniq(ArrowVariableSizeType::SUPER_SIZE); return make_uniq(LogicalType::BIT, std::move(type_info)); + } else if (arrow_extension == "duckdb.varint") { + if (format != "z" && format != "Z") { + std::ostringstream error; + error << "duckdb.bit must be a blob (i.e., \'z\'). It is incorrectly defined as:" << format; + return make_uniq(error.str()); + } + unique_ptr type_info; + if (format == "z") { + type_info = make_uniq(ArrowVariableSizeType::NORMAL); + } else { + type_info = make_uniq(ArrowVariableSizeType::SUPER_SIZE); + } + return make_uniq(LogicalType::VARINT, std::move(type_info)); } else { std::ostringstream error; error << "Arrow Type with extension name: " << arrow_extension << " and format: " << format diff --git a/src/duckdb/src/function/table/arrow_conversion.cpp b/src/duckdb/src/function/table/arrow_conversion.cpp index b83bbf56..81b4344e 100644 --- a/src/duckdb/src/function/table/arrow_conversion.cpp +++ b/src/duckdb/src/function/table/arrow_conversion.cpp @@ -138,6 +138,12 @@ static ArrowListOffsetData ConvertArrowListOffsetsTemplated(Vector &vector, Arro auto &start_offset = result.start_offset; auto &list_size = result.list_size; + if (size == 0) { + start_offset = 0; + list_size = 0; + return result; + } + idx_t cur_offset = 0; auto offsets = ArrowBufferData(array, 1) + effective_offset; start_offset = offsets[0]; @@ -765,14 +771,12 @@ static void ColumnArrowToDuckDB(Vector &vector, ArrowArray &array, ArrowArraySca case LogicalTypeId::BOOLEAN: { //! Arrow bit-packs boolean values //! Lets first figure out where we are in the source array - auto src_ptr = ArrowBufferData(array, 1) + - GetEffectiveOffset(array, NumericCast(parent_offset), scan_state, nested_offset) / 8; + auto effective_offset = + GetEffectiveOffset(array, NumericCast(parent_offset), scan_state, nested_offset); + auto src_ptr = ArrowBufferData(array, 1) + effective_offset / 8; auto tgt_ptr = (uint8_t *)FlatVector::GetData(vector); int src_pos = 0; - idx_t cur_bit = scan_state.chunk_offset % 8; - if (nested_offset != -1) { - cur_bit = NumericCast(nested_offset % 8); - } + idx_t cur_bit = effective_offset % 8; for (idx_t row = 0; row < size; row++) { if ((src_ptr[src_pos] & (1 << cur_bit)) == 0) { tgt_ptr[row] = 0; @@ -1026,7 +1030,8 @@ static void ColumnArrowToDuckDB(Vector &vector, ArrowArray &array, ArrowArraySca break; } case LogicalTypeId::BLOB: - case LogicalTypeId::BIT: { + case LogicalTypeId::BIT: + case LogicalTypeId::VARINT: { ArrowToDuckDBBlob(vector, array, scan_state, size, arrow_type, nested_offset, NumericCast(parent_offset)); break; diff --git a/src/duckdb/src/function/table/copy_csv.cpp b/src/duckdb/src/function/table/copy_csv.cpp index b2c16a67..26d04f89 100644 --- a/src/duckdb/src/function/table/copy_csv.cpp +++ b/src/duckdb/src/function/table/copy_csv.cpp @@ -7,7 +7,7 @@ #include "duckdb/common/types/column/column_data_collection.hpp" #include "duckdb/common/types/string_type.hpp" #include "duckdb/common/vector_operations/vector_operations.hpp" -#include "duckdb/execution/operator/csv_scanner/csv_sniffer.hpp" +#include "duckdb/execution/operator/csv_scanner/sniffer/csv_sniffer.hpp" #include "duckdb/function/copy_function.hpp" #include "duckdb/function/scalar/string_functions.hpp" #include "duckdb/function/table/read_csv.hpp" diff --git a/src/duckdb/src/function/table/read_csv.cpp b/src/duckdb/src/function/table/read_csv.cpp index 58948af7..0c6dcf12 100644 --- a/src/duckdb/src/function/table/read_csv.cpp +++ b/src/duckdb/src/function/table/read_csv.cpp @@ -8,7 +8,7 @@ #include "duckdb/common/union_by_name.hpp" #include "duckdb/execution/operator/csv_scanner/global_csv_state.hpp" #include "duckdb/execution/operator/csv_scanner/csv_error.hpp" -#include "duckdb/execution/operator/csv_scanner/csv_sniffer.hpp" +#include "duckdb/execution/operator/csv_scanner/sniffer/csv_sniffer.hpp" #include "duckdb/execution/operator/persistent/csv_rejects_table.hpp" #include "duckdb/function/function_set.hpp" #include "duckdb/main/client_context.hpp" @@ -52,36 +52,9 @@ static unique_ptr ReadCSVBind(ClientContext &context, TableFunctio auto multi_file_list = multi_file_reader->CreateFileList(context, input.inputs[0]); options.FromNamedParameters(input.named_parameters, context); - if (options.rejects_table_name.IsSetByUser() && !options.store_rejects.GetValue() && - options.store_rejects.IsSetByUser()) { - throw BinderException("REJECTS_TABLE option is only supported when store_rejects is not manually set to false"); - } - if (options.rejects_scan_name.IsSetByUser() && !options.store_rejects.GetValue() && - options.store_rejects.IsSetByUser()) { - throw BinderException("REJECTS_SCAN option is only supported when store_rejects is not manually set to false"); - } - if (options.rejects_scan_name.IsSetByUser() || options.rejects_table_name.IsSetByUser()) { - // Ensure we set store_rejects to true automagically - options.store_rejects.Set(true, false); - } - // Validate rejects_table options - if (options.store_rejects.GetValue()) { - if (!options.ignore_errors.GetValue() && options.ignore_errors.IsSetByUser()) { - throw BinderException( - "STORE_REJECTS option is only supported when IGNORE_ERRORS is not manually set to false"); - } - // Ensure we set ignore errors to true automagically - options.ignore_errors.Set(true, false); - if (options.file_options.union_by_name) { - throw BinderException("REJECTS_TABLE option is not supported when UNION_BY_NAME is set to true"); - } - } - if (options.rejects_limit != 0 && !options.store_rejects.GetValue()) { - throw BinderException("REJECTS_LIMIT option is only supported when REJECTS_TABLE is set to a table name"); - } options.file_options.AutoDetectHivePartitioning(*multi_file_list, context); - + options.Verify(); if (!options.auto_detect) { if (!options.columns_set) { throw BinderException("read_csv requires columns to be specified through the 'columns' option. Use " @@ -291,7 +264,6 @@ void ReadCSVTableFunction::ReadCSVAddNamedParameters(TableFunction &table_functi table_function.named_parameters["types"] = LogicalType::ANY; table_function.named_parameters["names"] = LogicalType::LIST(LogicalType::VARCHAR); table_function.named_parameters["column_names"] = LogicalType::LIST(LogicalType::VARCHAR); - table_function.named_parameters["parallel"] = LogicalType::BOOLEAN; table_function.named_parameters["comment"] = LogicalType::VARCHAR; MultiFileReader::AddParameters(table_function); diff --git a/src/duckdb/src/function/table/sniff_csv.cpp b/src/duckdb/src/function/table/sniff_csv.cpp index 2a1d1b98..9c845bbf 100644 --- a/src/duckdb/src/function/table/sniff_csv.cpp +++ b/src/duckdb/src/function/table/sniff_csv.cpp @@ -1,7 +1,7 @@ #include "duckdb/function/built_in_functions.hpp" #include "duckdb/execution/operator/csv_scanner/csv_reader_options.hpp" #include "duckdb/common/types/data_chunk.hpp" -#include "duckdb/execution/operator/csv_scanner/csv_sniffer.hpp" +#include "duckdb/execution/operator/csv_scanner/sniffer/csv_sniffer.hpp" #include "duckdb/execution/operator/csv_scanner/csv_buffer_manager.hpp" #include "duckdb/function/table_function.hpp" #include "duckdb/main/client_context.hpp" @@ -50,6 +50,7 @@ static unique_ptr CSVSniffBind(ClientContext &context, TableFuncti input.named_parameters.erase("auto_detect"); } result->options.FromNamedParameters(input.named_parameters, context); + result->options.Verify(); // We want to return the whole CSV Configuration // 1. Delimiter return_types.emplace_back(LogicalType::VARCHAR); diff --git a/src/duckdb/src/function/table/system/duckdb_secrets.cpp b/src/duckdb/src/function/table/system/duckdb_secrets.cpp index 44557e34..6069344b 100644 --- a/src/duckdb/src/function/table/system/duckdb_secrets.cpp +++ b/src/duckdb/src/function/table/system/duckdb_secrets.cpp @@ -107,13 +107,21 @@ void DuckDBSecretsFunction(ClientContext &context, TableFunctionInput &data_p, D const auto &secret = *secret_entry.secret; - output.SetValue(0, count, secret.GetName()); - output.SetValue(1, count, Value(secret.GetType())); - output.SetValue(2, count, Value(secret.GetProvider())); - output.SetValue(3, count, Value(secret_entry.persist_type == SecretPersistType::PERSISTENT)); - output.SetValue(4, count, Value(secret_entry.storage_mode)); - output.SetValue(5, count, Value::LIST(LogicalType::VARCHAR, scope_value)); - output.SetValue(6, count, secret.ToString(bind_data.redact)); + idx_t i = 0; + // name + output.SetValue(i++, count, secret.GetName()); + // type + output.SetValue(i++, count, Value(secret.GetType())); + // provider + output.SetValue(i++, count, Value(secret.GetProvider())); + // persistent + output.SetValue(i++, count, Value(secret_entry.persist_type == SecretPersistType::PERSISTENT)); + // storage + output.SetValue(i++, count, Value(secret_entry.storage_mode)); + // scope + output.SetValue(i++, count, Value::LIST(LogicalType::VARCHAR, scope_value)); + // secret_string + output.SetValue(i++, count, secret.ToString(bind_data.redact)); data.offset++; count++; diff --git a/src/duckdb/src/function/table/version/pragma_version.cpp b/src/duckdb/src/function/table/version/pragma_version.cpp index 6d984ecc..04fac00b 100644 --- a/src/duckdb/src/function/table/version/pragma_version.cpp +++ b/src/duckdb/src/function/table/version/pragma_version.cpp @@ -1,5 +1,5 @@ #ifndef DUCKDB_PATCH_VERSION -#define DUCKDB_PATCH_VERSION "1" +#define DUCKDB_PATCH_VERSION "3" #endif #ifndef DUCKDB_MINOR_VERSION #define DUCKDB_MINOR_VERSION 1 @@ -8,10 +8,10 @@ #define DUCKDB_MAJOR_VERSION 1 #endif #ifndef DUCKDB_VERSION -#define DUCKDB_VERSION "v1.1.1" +#define DUCKDB_VERSION "v1.1.3" #endif #ifndef DUCKDB_SOURCE_ID -#define DUCKDB_SOURCE_ID "af39bd0dcf" +#define DUCKDB_SOURCE_ID "19864453f7" #endif #include "duckdb/function/table/system_functions.hpp" #include "duckdb/main/database.hpp" diff --git a/src/duckdb/src/include/duckdb.h b/src/duckdb/src/include/duckdb.h index ac085232..30b79fd9 100644 --- a/src/duckdb/src/include/duckdb.h +++ b/src/duckdb/src/include/duckdb.h @@ -626,12 +626,12 @@ typedef struct _duckdb_arrow_array { //===--------------------------------------------------------------------===// //! Passed to C API extension as parameter to the entrypoint struct duckdb_extension_access { - //! Indicate that an error has occured + //! Indicate that an error has occurred void (*set_error)(duckdb_extension_info info, const char *error); //! Fetch the database from duckdb to register extensions to duckdb_database *(*get_database)(duckdb_extension_info info); //! Fetch the API - void *(*get_api)(duckdb_extension_info info, const char *version); + const void *(*get_api)(duckdb_extension_info info, const char *version); }; //===--------------------------------------------------------------------===// diff --git a/src/duckdb/src/include/duckdb/catalog/catalog_entry_retriever.hpp b/src/duckdb/src/include/duckdb/catalog/catalog_entry_retriever.hpp index 28b3874c..14466cb3 100644 --- a/src/duckdb/src/include/duckdb/catalog/catalog_entry_retriever.hpp +++ b/src/duckdb/src/include/duckdb/catalog/catalog_entry_retriever.hpp @@ -64,7 +64,7 @@ class CatalogEntryRetriever { } private: - //! (optional) callback, called on every succesful entry retrieval + //! (optional) callback, called on every successful entry retrieval catalog_entry_callback_t callback = nullptr; ClientContext &context; }; diff --git a/src/duckdb/src/include/duckdb/common/atomic.hpp b/src/duckdb/src/include/duckdb/common/atomic.hpp index 4445b311..e86e6a69 100644 --- a/src/duckdb/src/include/duckdb/common/atomic.hpp +++ b/src/duckdb/src/include/duckdb/common/atomic.hpp @@ -11,5 +11,17 @@ #include namespace duckdb { + using std::atomic; -} + +//! NOTE: When repeatedly trying to atomically set a value in a loop, you can use as the loop condition: +//! * std::atomic_compare_exchange_weak +//! * std::atomic::compare_exchange_weak +//! If not used as a loop condition, use: +//! * std::atomic_compare_exchange_strong +//! * std::atomic::compare_exchange_strong +//! If this is not done correctly, we may get correctness issues when using older compiler versions (see: issue #14389) +//! Performance may be optimized using std::memory_order, but NOT at the cost of correctness. +//! For correct examples of this, see concurrentqueue.h + +} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/common/bitpacking.hpp b/src/duckdb/src/include/duckdb/common/bitpacking.hpp index 8aa0305b..06d12882 100644 --- a/src/duckdb/src/include/duckdb/common/bitpacking.hpp +++ b/src/duckdb/src/include/duckdb/common/bitpacking.hpp @@ -41,16 +41,15 @@ class BitpackingPrimitives { } } else { idx_t misaligned_count = count % BITPACKING_ALGORITHM_GROUP_SIZE; - T tmp_buffer[BITPACKING_ALGORITHM_GROUP_SIZE]; // TODO maybe faster on the heap? - count -= misaligned_count; - for (idx_t i = 0; i < count; i += BITPACKING_ALGORITHM_GROUP_SIZE) { PackGroup(dst + (i * width) / 8, src + i, width); } - // Input was not aligned to BITPACKING_ALGORITHM_GROUP_SIZE, we need a copy + // The input is not aligned to BITPACKING_ALGORITHM_GROUP_SIZE. + // Copy the unaligned count into a zero-initialized temporary group, and pack it. if (misaligned_count) { + T tmp_buffer[BITPACKING_ALGORITHM_GROUP_SIZE] = {0}; memcpy(tmp_buffer, src + count, misaligned_count * sizeof(T)); PackGroup(dst + (count * width) / 8, tmp_buffer, width); } diff --git a/src/duckdb/src/include/duckdb/common/enum_util.hpp b/src/duckdb/src/include/duckdb/common/enum_util.hpp index 7cae3772..3e6a235a 100644 --- a/src/duckdb/src/include/duckdb/common/enum_util.hpp +++ b/src/duckdb/src/include/duckdb/common/enum_util.hpp @@ -278,6 +278,8 @@ enum class SecretDisplayType : uint8_t; enum class SecretPersistType : uint8_t; +enum class SecretSerializationType : uint8_t; + enum class SequenceInfo : uint8_t; enum class SetOperationType : uint8_t; @@ -728,6 +730,9 @@ const char* EnumUtil::ToChars(SecretDisplayType value); template<> const char* EnumUtil::ToChars(SecretPersistType value); +template<> +const char* EnumUtil::ToChars(SecretSerializationType value); + template<> const char* EnumUtil::ToChars(SequenceInfo value); @@ -1218,6 +1223,9 @@ SecretDisplayType EnumUtil::FromString(const char *value); template<> SecretPersistType EnumUtil::FromString(const char *value); +template<> +SecretSerializationType EnumUtil::FromString(const char *value); + template<> SequenceInfo EnumUtil::FromString(const char *value); diff --git a/src/duckdb/src/include/duckdb/common/enums/metric_type.hpp b/src/duckdb/src/include/duckdb/common/enums/metric_type.hpp index fdea7faf..6510abbe 100644 --- a/src/duckdb/src/include/duckdb/common/enums/metric_type.hpp +++ b/src/duckdb/src/include/duckdb/common/enums/metric_type.hpp @@ -30,6 +30,8 @@ enum class MetricsType : uint8_t { CUMULATIVE_ROWS_SCANNED, OPERATOR_ROWS_SCANNED, OPERATOR_TIMING, + LATENCY, + ROWS_RETURNED, RESULT_SET_SIZE, ALL_OPTIMIZERS, CUMULATIVE_OPTIMIZER_TIMING, diff --git a/src/duckdb/src/include/duckdb/common/exception.hpp b/src/duckdb/src/include/duckdb/common/exception.hpp index dd6431c5..3bb60592 100644 --- a/src/duckdb/src/include/duckdb/common/exception.hpp +++ b/src/duckdb/src/include/duckdb/common/exception.hpp @@ -329,6 +329,16 @@ class InvalidInputException : public Exception { } }; +class ExecutorException : public Exception { +public: + DUCKDB_API explicit ExecutorException(const string &msg); + + template + explicit ExecutorException(const string &msg, ARGS... params) + : ExecutorException(ConstructMessage(msg, params...)) { + } +}; + class InvalidConfigurationException : public Exception { public: DUCKDB_API explicit InvalidConfigurationException(const string &msg); diff --git a/src/duckdb/src/include/duckdb/common/extra_type_info/enum_type_info.hpp b/src/duckdb/src/include/duckdb/common/extra_type_info/enum_type_info.hpp new file mode 100644 index 00000000..3949caa8 --- /dev/null +++ b/src/duckdb/src/include/duckdb/common/extra_type_info/enum_type_info.hpp @@ -0,0 +1,53 @@ +#pragma once + +#include "duckdb/common/extra_type_info.hpp" +#include "duckdb/common/serializer/deserializer.hpp" +#include "duckdb/common/string_map_set.hpp" + +namespace duckdb { + +template +struct EnumTypeInfoTemplated : public EnumTypeInfo { + explicit EnumTypeInfoTemplated(Vector &values_insert_order_p, idx_t size_p) + : EnumTypeInfo(values_insert_order_p, size_p) { + D_ASSERT(values_insert_order_p.GetType().InternalType() == PhysicalType::VARCHAR); + + UnifiedVectorFormat vdata; + values_insert_order.ToUnifiedFormat(size_p, vdata); + + auto data = UnifiedVectorFormat::GetData(vdata); + for (idx_t i = 0; i < size_p; i++) { + auto idx = vdata.sel->get_index(i); + if (!vdata.validity.RowIsValid(idx)) { + throw InternalException("Attempted to create ENUM type with NULL value"); + } + if (values.count(data[idx]) > 0) { + throw InvalidInputException("Attempted to create ENUM type with duplicate value %s", + data[idx].GetString()); + } + values[data[idx]] = UnsafeNumericCast(i); + } + } + + static shared_ptr Deserialize(Deserializer &deserializer, uint32_t size) { + Vector values_insert_order(LogicalType::VARCHAR, size); + auto strings = FlatVector::GetData(values_insert_order); + + deserializer.ReadList(201, "values", [&](Deserializer::List &list, idx_t i) { + strings[i] = StringVector::AddStringOrBlob(values_insert_order, list.ReadElement()); + }); + return make_shared_ptr(values_insert_order, size); + } + + const string_map_t &GetValues() const { + return values; + } + + EnumTypeInfoTemplated(const EnumTypeInfoTemplated &) = delete; + EnumTypeInfoTemplated &operator=(const EnumTypeInfoTemplated &) = delete; + +private: + string_map_t values; +}; + +} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/common/insertion_order_preserving_map.hpp b/src/duckdb/src/include/duckdb/common/insertion_order_preserving_map.hpp index 2f612631..d1ff0867 100644 --- a/src/duckdb/src/include/duckdb/common/insertion_order_preserving_map.hpp +++ b/src/duckdb/src/include/duckdb/common/insertion_order_preserving_map.hpp @@ -95,13 +95,13 @@ class InsertionOrderPreservingMap { map.resize(nz); } - void insert(const string &key, V &value) { // NOLINT: match stl API - map.push_back(make_pair(key, std::move(value))); + void insert(const string &key, V &&value) { // NOLINT: match stl API + map.emplace_back(key, std::move(value)); map_idx[key] = map.size() - 1; } - void insert(const string &key, V &&value) { // NOLINT: match stl API - map.push_back(make_pair(key, std::move(value))); + void insert(const string &key, const V &value) { // NOLINT: match stl API + map.emplace_back(key, value); map_idx[key] = map.size() - 1; } @@ -133,7 +133,7 @@ class InsertionOrderPreservingMap { V &operator[](const string &key) { if (!contains(key)) { auto v = V(); - insert(key, v); + insert(key, std::move(v)); } return map[map_idx[key]].second; } diff --git a/src/duckdb/src/include/duckdb/common/multi_file_reader.hpp b/src/duckdb/src/include/duckdb/common/multi_file_reader.hpp index 5186eaae..ad848187 100644 --- a/src/duckdb/src/include/duckdb/common/multi_file_reader.hpp +++ b/src/duckdb/src/include/duckdb/common/multi_file_reader.hpp @@ -255,6 +255,11 @@ struct MultiFileReader { static void PruneReaders(BIND_DATA &data, MultiFileList &file_list) { unordered_set file_set; + // Avoid materializing the file list if there's nothing to prune + if (!data.initial_reader && data.union_readers.empty()) { + return; + } + for (const auto &file : file_list.Files()) { file_set.insert(file); } diff --git a/src/duckdb/src/include/duckdb/common/types/bit.hpp b/src/duckdb/src/include/duckdb/common/types/bit.hpp index 5a1a8209..cbf59913 100644 --- a/src/duckdb/src/include/duckdb/common/types/bit.hpp +++ b/src/duckdb/src/include/duckdb/common/types/bit.hpp @@ -17,85 +17,88 @@ namespace duckdb { +using bitstring_t = duckdb::string_t; + //! The Bit class is a static class that holds helper functions for the BIT type. class Bit { public: //! Returns the number of bits in the bit string - DUCKDB_API static idx_t BitLength(string_t bits); + DUCKDB_API static idx_t BitLength(bitstring_t bits); //! Returns the number of set bits in the bit string - DUCKDB_API static idx_t BitCount(string_t bits); + DUCKDB_API static idx_t BitCount(bitstring_t bits); //! Returns the number of bytes in the bit string - DUCKDB_API static idx_t OctetLength(string_t bits); + DUCKDB_API static idx_t OctetLength(bitstring_t bits); //! Extracts the nth bit from bit string; the first (leftmost) bit is indexed 0 - DUCKDB_API static idx_t GetBit(string_t bit_string, idx_t n); + DUCKDB_API static idx_t GetBit(bitstring_t bit_string, idx_t n); //! Sets the nth bit in bit string to newvalue; the first (leftmost) bit is indexed 0 - DUCKDB_API static void SetBit(string_t &bit_string, idx_t n, idx_t new_value); + DUCKDB_API static void SetBit(bitstring_t &bit_string, idx_t n, idx_t new_value); //! Returns first starting index of the specified substring within bits, or zero if it's not present. - DUCKDB_API static idx_t BitPosition(string_t substring, string_t bits); + DUCKDB_API static idx_t BitPosition(bitstring_t substring, bitstring_t bits); //! Converts bits to a string, writing the output to the designated output string. //! The string needs to have space for at least GetStringSize(bits) bytes. - DUCKDB_API static void ToString(string_t bits, char *output); - DUCKDB_API static string ToString(string_t str); + DUCKDB_API static void ToString(bitstring_t bits, char *output); + DUCKDB_API static string ToString(bitstring_t bits); //! Returns the bit size of a string -> bit conversion DUCKDB_API static bool TryGetBitStringSize(string_t str, idx_t &result_size, string *error_message); //! Convert a string to a bit. This function should ONLY be called after calling GetBitSize, since it does NOT //! perform data validation. - DUCKDB_API static void ToBit(string_t str, string_t &output); + DUCKDB_API static void ToBit(string_t str, bitstring_t &output); DUCKDB_API static string ToBit(string_t str); //! output needs to have enough space allocated before calling this function (blob size + 1) - DUCKDB_API static void BlobToBit(string_t blob, string_t &output); + DUCKDB_API static void BlobToBit(string_t blob, bitstring_t &output); DUCKDB_API static string BlobToBit(string_t blob); //! output_str needs to have enough space allocated before calling this function (sizeof(T) + 1) template - static void NumericToBit(T numeric, string_t &output_str); + static void NumericToBit(T numeric, bitstring_t &output_str); template static string NumericToBit(T numeric); //! bit is expected to fit inside of output num (bit size <= sizeof(T) + 1) template - static void BitToNumeric(string_t bit, T &output_num); + static void BitToNumeric(bitstring_t bit, T &output_num); template - static T BitToNumeric(string_t bit); + static T BitToNumeric(bitstring_t bit); //! bit is expected to fit inside of output_blob (bit size = output_blob + 1) - static void BitToBlob(string_t bit, string_t &output_blob); + static void BitToBlob(bitstring_t bit, string_t &output_blob); - static string BitToBlob(string_t bit); + static string BitToBlob(bitstring_t bit); //! Creates a new bitstring of determined length - DUCKDB_API static void BitString(const string_t &input, const idx_t &len, string_t &result); - DUCKDB_API static void SetEmptyBitString(string_t &target, string_t &input); - DUCKDB_API static void SetEmptyBitString(string_t &target, idx_t len); + DUCKDB_API static void BitString(const string_t &input, idx_t len, bitstring_t &result); + DUCKDB_API static void ExtendBitString(const bitstring_t &input, idx_t bit_length, bitstring_t &result); + DUCKDB_API static void SetEmptyBitString(bitstring_t &target, string_t &input); + DUCKDB_API static void SetEmptyBitString(bitstring_t &target, idx_t len); DUCKDB_API static idx_t ComputeBitstringLen(idx_t len); - DUCKDB_API static void RightShift(const string_t &bit_string, const idx_t &shif, string_t &result); - DUCKDB_API static void LeftShift(const string_t &bit_string, const idx_t &shift, string_t &result); - DUCKDB_API static void BitwiseAnd(const string_t &rhs, const string_t &lhs, string_t &result); - DUCKDB_API static void BitwiseOr(const string_t &rhs, const string_t &lhs, string_t &result); - DUCKDB_API static void BitwiseXor(const string_t &rhs, const string_t &lhs, string_t &result); - DUCKDB_API static void BitwiseNot(const string_t &rhs, string_t &result); + DUCKDB_API static void RightShift(const bitstring_t &bit_string, idx_t shift, bitstring_t &result); + DUCKDB_API static void LeftShift(const bitstring_t &bit_string, idx_t shift, bitstring_t &result); + DUCKDB_API static void BitwiseAnd(const bitstring_t &rhs, const bitstring_t &lhs, bitstring_t &result); + DUCKDB_API static void BitwiseOr(const bitstring_t &rhs, const bitstring_t &lhs, bitstring_t &result); + DUCKDB_API static void BitwiseXor(const bitstring_t &rhs, const bitstring_t &lhs, bitstring_t &result); + DUCKDB_API static void BitwiseNot(const bitstring_t &rhs, bitstring_t &result); - DUCKDB_API static void Verify(const string_t &input); + DUCKDB_API static void Verify(const bitstring_t &input); private: - static void Finalize(string_t &str); - static idx_t GetBitInternal(string_t bit_string, idx_t n); - static void SetBitInternal(string_t &bit_string, idx_t n, idx_t new_value); + static void Finalize(bitstring_t &str); + static idx_t GetBitInternal(bitstring_t bit_string, idx_t n); + static void SetBitInternal(bitstring_t &bit_string, idx_t n, idx_t new_value); static idx_t GetBitIndex(idx_t n); - static uint8_t GetFirstByte(const string_t &str); + static uint8_t GetFirstByte(const bitstring_t &str); }; //===--------------------------------------------------------------------===// // Bit Template definitions //===--------------------------------------------------------------------===// template -void Bit::NumericToBit(T numeric, string_t &output_str) { +void Bit::NumericToBit(T numeric, bitstring_t &output_str) { D_ASSERT(output_str.GetSize() >= sizeof(T) + 1); auto output = output_str.GetDataWriteable(); @@ -113,20 +116,20 @@ template string Bit::NumericToBit(T numeric) { auto bit_len = sizeof(T) + 1; auto buffer = make_unsafe_uniq_array_uninitialized(bit_len); - string_t output_str(buffer.get(), UnsafeNumericCast(bit_len)); + bitstring_t output_str(buffer.get(), UnsafeNumericCast(bit_len)); Bit::NumericToBit(numeric, output_str); return output_str.GetString(); } template -T Bit::BitToNumeric(string_t bit) { +T Bit::BitToNumeric(bitstring_t bit) { T output; Bit::BitToNumeric(bit, output); return (output); } template -void Bit::BitToNumeric(string_t bit, T &output_num) { +void Bit::BitToNumeric(bitstring_t bit, T &output_num) { D_ASSERT(bit.GetSize() <= sizeof(T) + 1); output_num = 0; diff --git a/src/duckdb/src/include/duckdb/common/types/data_chunk.hpp b/src/duckdb/src/include/duckdb/common/types/data_chunk.hpp index 58f6aced..7433c93a 100644 --- a/src/duckdb/src/include/duckdb/common/types/data_chunk.hpp +++ b/src/duckdb/src/include/duckdb/common/types/data_chunk.hpp @@ -83,22 +83,19 @@ class DataChunk { //! Set the DataChunk to own the data of data chunk, destroying the other chunk in the process DUCKDB_API void Move(DataChunk &chunk); - //! Initializes the DataChunk with the specified types to an empty 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. + //! Initializes a DataChunk with the given types and without any vector data allocation. + DUCKDB_API void InitializeEmpty(const vector &types); + + //! Initializes a DataChunk with the given types. Then, if the corresponding boolean in the initialize-vector is + //! true, it initializes the vector for that data type. + DUCKDB_API void Initialize(ClientContext &context, const vector &types, + idx_t capacity = STANDARD_VECTOR_SIZE); DUCKDB_API void Initialize(Allocator &allocator, const vector &types, idx_t capacity = STANDARD_VECTOR_SIZE); - DUCKDB_API void Initialize(ClientContext &context, const vector &types, + DUCKDB_API void Initialize(ClientContext &context, const vector &types, const vector &initialize, + idx_t capacity = STANDARD_VECTOR_SIZE); + DUCKDB_API void Initialize(Allocator &allocator, const vector &types, const vector &initialize, idx_t capacity = STANDARD_VECTOR_SIZE); - //! Initializes an empty DataChunk with the given types. The vectors will *not* have any data allocated for them. - DUCKDB_API void InitializeEmpty(const vector &types); - - DUCKDB_API void InitializeEmpty(vector::const_iterator begin, vector::const_iterator end); - DUCKDB_API void Initialize(Allocator &allocator, vector::const_iterator begin, - vector::const_iterator end, idx_t capacity = STANDARD_VECTOR_SIZE); - DUCKDB_API void Initialize(ClientContext &context, vector::const_iterator begin, - vector::const_iterator end, idx_t capacity = STANDARD_VECTOR_SIZE); //! 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 diff --git a/src/duckdb/src/include/duckdb/common/types/uhugeint.hpp b/src/duckdb/src/include/duckdb/common/types/uhugeint.hpp index 335feef7..b38df8dd 100644 --- a/src/duckdb/src/include/duckdb/common/types/uhugeint.hpp +++ b/src/duckdb/src/include/duckdb/common/types/uhugeint.hpp @@ -76,7 +76,7 @@ class Uhugeint { template inline static uhugeint_t Divide(uhugeint_t lhs, uhugeint_t rhs) { - // division between two same-size unsigned intergers can only go wrong with division by zero + // division between two same-size unsigned integers can only go wrong with division by zero if (rhs == 0) { throw OutOfRangeException("Division of UHUGEINT by zero!"); } diff --git a/src/duckdb/src/include/duckdb/common/types/vector_cache.hpp b/src/duckdb/src/include/duckdb/common/types/vector_cache.hpp index 333950ce..490bcd14 100644 --- a/src/duckdb/src/include/duckdb/common/types/vector_cache.hpp +++ b/src/duckdb/src/include/duckdb/common/types/vector_cache.hpp @@ -16,18 +16,20 @@ namespace duckdb { class Allocator; class Vector; -//! The VectorCache holds cached data that allows for re-use of the same memory by vectors +//! The VectorCache holds cached vector data. +//! It enables re-using the same memory for different vectors. class VectorCache { public: - //! Instantiate a vector cache with the given type and capacity - DUCKDB_API explicit VectorCache(Allocator &allocator, const LogicalType &type, - idx_t capacity = STANDARD_VECTOR_SIZE); + //! Instantiate an empty vector cache. + DUCKDB_API VectorCache(); + //! Instantiate a vector cache with the given type and capacity. + DUCKDB_API VectorCache(Allocator &allocator, const LogicalType &type, const idx_t capacity = STANDARD_VECTOR_SIZE); +public: buffer_ptr buffer; public: void ResetFromCache(Vector &result) const; - const LogicalType &GetType() const; }; diff --git a/src/duckdb/src/include/duckdb/common/windows_undefs.hpp b/src/duckdb/src/include/duckdb/common/windows_undefs.hpp index 680c2a43..c991f32b 100644 --- a/src/duckdb/src/include/duckdb/common/windows_undefs.hpp +++ b/src/duckdb/src/include/duckdb/common/windows_undefs.hpp @@ -6,7 +6,8 @@ // //===----------------------------------------------------------------------===// -#pragma once +// Do not add a header inclusion guard to this file. Otherwise these Win32 macros +// may get defined and stomp on DuckDB symbols #ifdef WIN32 diff --git a/src/duckdb/src/include/duckdb/core_functions/aggregate/minmax_n_helpers.hpp b/src/duckdb/src/include/duckdb/core_functions/aggregate/minmax_n_helpers.hpp index 6dbdb8bc..55a7a150 100644 --- a/src/duckdb/src/include/duckdb/core_functions/aggregate/minmax_n_helpers.hpp +++ b/src/duckdb/src/include/duckdb/core_functions/aggregate/minmax_n_helpers.hpp @@ -40,6 +40,8 @@ struct HeapEntry { HeapEntry(HeapEntry &&other) noexcept { if (other.value.IsInlined()) { value = other.value; + capacity = 0; + allocated_data = nullptr; } else { capacity = other.capacity; allocated_data = other.allocated_data; diff --git a/src/duckdb/src/include/duckdb/core_functions/scalar/bit_functions.hpp b/src/duckdb/src/include/duckdb/core_functions/scalar/bit_functions.hpp index c114d72a..f66427b6 100644 --- a/src/duckdb/src/include/duckdb/core_functions/scalar/bit_functions.hpp +++ b/src/duckdb/src/include/duckdb/core_functions/scalar/bit_functions.hpp @@ -48,7 +48,7 @@ struct BitStringFun { static constexpr const char *Description = "Pads the bitstring until the specified length"; static constexpr const char *Example = "bitstring('1010'::BIT, 7)"; - static ScalarFunction GetFunction(); + static ScalarFunctionSet GetFunctions(); }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/core_functions/scalar/list_functions.hpp b/src/duckdb/src/include/duckdb/core_functions/scalar/list_functions.hpp index 9386278a..a5fbfdfe 100644 --- a/src/duckdb/src/include/duckdb/core_functions/scalar/list_functions.hpp +++ b/src/duckdb/src/include/duckdb/core_functions/scalar/list_functions.hpp @@ -330,12 +330,6 @@ struct ListNegativeDotProductFun { static constexpr const char *Name = "list_negative_dot_product"; }; -struct ListNegativeInnerProductFunAlias { - using ALIAS = ListNegativeInnerProductFun; - - static constexpr const char *Name = "<#>"; -}; - struct UnpivotListFun { static constexpr const char *Name = "unpivot_list"; static constexpr const char *Parameters = "any,..."; diff --git a/src/duckdb/src/include/duckdb/core_functions/scalar/math_functions.hpp b/src/duckdb/src/include/duckdb/core_functions/scalar/math_functions.hpp index 2e84f1d9..cb1125a1 100644 --- a/src/duckdb/src/include/duckdb/core_functions/scalar/math_functions.hpp +++ b/src/duckdb/src/include/duckdb/core_functions/scalar/math_functions.hpp @@ -427,7 +427,7 @@ struct AcoshFun { static constexpr const char *Name = "acosh"; static constexpr const char *Parameters = "x"; static constexpr const char *Description = "Computes the inverse hyperbolic cos of x"; - static constexpr const char *Example = "acosh(0.5)"; + static constexpr const char *Example = "acosh(2.3)"; static ScalarFunction GetFunction(); }; diff --git a/src/duckdb/src/include/duckdb/execution/expression_executor_state.hpp b/src/duckdb/src/include/duckdb/execution/expression_executor_state.hpp index c0802db2..780166fb 100644 --- a/src/duckdb/src/include/duckdb/execution/expression_executor_state.hpp +++ b/src/duckdb/src/include/duckdb/execution/expression_executor_state.hpp @@ -28,10 +28,11 @@ struct ExpressionState { vector> child_states; vector types; DataChunk intermediate_chunk; + vector initialize; public: - void AddChild(Expression *expr); - void Finalize(bool empty = false); + void AddChild(Expression &child_expr); + void Finalize(); Allocator &GetAllocator(); bool HasContext(); DUCKDB_API ClientContext &GetContext(); diff --git a/src/duckdb/src/include/duckdb/execution/index/art/art.hpp b/src/duckdb/src/include/duckdb/execution/index/art/art.hpp index 076a9356..00299952 100644 --- a/src/duckdb/src/include/duckdb/execution/index/art/art.hpp +++ b/src/duckdb/src/include/duckdb/execution/index/art/art.hpp @@ -55,6 +55,9 @@ class ART : public BoundIndex { return std::move(art); } + //! Plan index construction. + static unique_ptr CreatePlan(PlanIndexInput &input); + //! Root of the tree. Node tree = Node(); //! Fixed-size allocators holding the ART nodes. diff --git a/src/duckdb/src/include/duckdb/execution/index/index_type.hpp b/src/duckdb/src/include/duckdb/execution/index/index_type.hpp index 3417b15e..52d779f3 100644 --- a/src/duckdb/src/include/duckdb/execution/index/index_type.hpp +++ b/src/duckdb/src/include/duckdb/execution/index/index_type.hpp @@ -18,6 +18,8 @@ namespace duckdb { class BoundIndex; +class PhysicalOperator; +class LogicalCreateIndex; enum class IndexConstraintType : uint8_t; class Expression; class TableIOManager; @@ -43,7 +45,19 @@ struct CreateIndexInput { options(options) {}; }; +struct PlanIndexInput { + ClientContext &context; + LogicalCreateIndex &op; + unique_ptr &table_scan; + + PlanIndexInput(ClientContext &context_p, LogicalCreateIndex &op_p, unique_ptr &table_scan_p) + : context(context_p), op(op_p), table_scan(table_scan_p) { + } +}; + typedef unique_ptr (*index_create_function_t)(CreateIndexInput &input); +typedef unique_ptr (*index_plan_function_t)(PlanIndexInput &input); + //! A index "type" class IndexType { public: @@ -51,7 +65,8 @@ class IndexType { string name; // Callbacks - index_create_function_t create_instance; + index_plan_function_t create_plan = nullptr; + index_create_function_t create_instance = nullptr; }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_buffer_manager.hpp b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_buffer_manager.hpp index 396c60c9..5bcf0af6 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_buffer_manager.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_buffer_manager.hpp @@ -35,15 +35,15 @@ class CSVBufferManager { void UnpinBuffer(const idx_t cache_idx); //! Returns the buffer size set for this CSV buffer manager - idx_t GetBufferSize(); + idx_t GetBufferSize() const; //! Returns the number of buffers in the cached_buffers cache - idx_t BufferCount(); + idx_t BufferCount() const; //! If this buffer manager is done. In the context of a buffer manager it means that it read all buffers at least //! once. - bool Done(); + bool Done() const; void ResetBufferManager(); - string GetFilePath(); + string GetFilePath() const; ClientContext &context; idx_t skip_rows = 0; diff --git a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_reader_options.hpp b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_reader_options.hpp index 8b7cca02..fe05ff65 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_reader_options.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_reader_options.hpp @@ -168,8 +168,10 @@ struct CSVReaderOptions { void SetReadOption(const string &loption, const Value &value, vector &expected_names); void SetWriteOption(const string &loption, const Value &value); void SetDateFormat(LogicalTypeId type, const string &format, bool read_format); - void ToNamedParameters(named_parameter_map_t &out); - void FromNamedParameters(named_parameter_map_t &in, ClientContext &context); + void ToNamedParameters(named_parameter_map_t &out) const; + void FromNamedParameters(const named_parameter_map_t &in, ClientContext &context); + //! Verify options are not conflicting + void Verify(); string ToString(const string ¤t_file_path) const; //! If the type for column with idx i was manually set diff --git a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_schema.hpp b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_schema.hpp index cf56f75f..39e1b809 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_schema.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_schema.hpp @@ -9,6 +9,7 @@ #pragma once #include "duckdb/common/types.hpp" +#include "duckdb/execution/operator/csv_scanner/sniffer/sniff_result.hpp" namespace duckdb { //! Basic CSV Column Info @@ -23,8 +24,8 @@ struct CSVColumnInfo { struct CSVSchema { void Initialize(vector &names, vector &types, const string &file_path); bool Empty() const; - bool SchemasMatch(string &error_message, vector &names, vector &types, - const string &cur_file_path); + bool SchemasMatch(string &error_message, SnifferResult &sniffer_result, const string &cur_file_path, + bool is_minimal_sniffer) const; private: static bool CanWeCastIt(LogicalTypeId source, LogicalTypeId destination); diff --git a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/sniffer/csv_sniffer.hpp b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/sniffer/csv_sniffer.hpp index 3584b1e9..6de097de 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/sniffer/csv_sniffer.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/sniffer/csv_sniffer.hpp @@ -8,25 +8,50 @@ #pragma once -#include "duckdb/execution/operator/csv_scanner/state_machine/csv_state_machine.hpp" +#include "duckdb/execution/operator/csv_scanner/csv_state_machine.hpp" #include "duckdb/common/vector.hpp" -#include "duckdb/execution/operator/csv_scanner/sniffer/quote_rules.hpp" -#include "duckdb/execution/operator/csv_scanner/scanner/column_count_scanner.hpp" +#include "duckdb/execution/operator/csv_scanner/quote_rules.hpp" +#include "duckdb/execution/operator/csv_scanner/column_count_scanner.hpp" +#include "duckdb/execution/operator/csv_scanner/csv_schema.hpp" +#include "duckdb/execution/operator/csv_scanner/header_value.hpp" +#include "duckdb/execution/operator/csv_scanner/sniffer/sniff_result.hpp" namespace duckdb { struct DateTimestampSniffing { bool initialized = false; + bool had_match = false; vector format; + idx_t initial_size; }; -//! Struct to store the result of the Sniffer -struct SnifferResult { - SnifferResult(vector return_types_p, vector names_p) - : return_types(std::move(return_types_p)), names(std::move(names_p)) { - } - //! Return Types that were detected - vector return_types; - //! Column Names that were detected - vector names; + +//! All the options that will be used to sniff the dialect of the CSV file +struct DialectCandidates { + //! The constructor populates all of our the options that will be used in our sniffer search space + explicit DialectCandidates(const CSVStateMachineOptions &options); + + //! Static functions to get defaults of the search space + static vector GetDefaultDelimiter(); + + static vector> GetDefaultQuote(); + + static vector GetDefaultQuoteRule(); + + static vector> GetDefaultEscape(); + + static vector GetDefaultComment(); + + string Print(); + + //! Candidates for the delimiter + vector delim_candidates; + //! Candidates for the comment + vector comment_candidates; + //! Quote-Rule Candidates + vector quote_rule_candidates; + //! Candidates for the quote option + unordered_map> quote_candidates_map; + //! Candidates for the escape option + unordered_map> escape_candidates_map; }; //! This represents the data related to columns that have been set by the user @@ -45,12 +70,12 @@ struct SetColumns { //! Column Names that were detected const vector *names = nullptr; //! If columns are set - bool IsSet(); + bool IsSet() const; //! How many columns - idx_t Size(); + idx_t Size() const; //! Helper function that checks if candidate is acceptable based on the number of columns it produces - inline bool IsCandidateUnacceptable(idx_t num_cols, bool null_padding, bool ignore_errors, - bool last_value_always_empty) { + inline bool IsCandidateUnacceptable(const idx_t num_cols, bool null_padding, bool ignore_errors, + bool last_value_always_empty) const { if (!IsSet() || ignore_errors) { // We can't say its unacceptable if it's not set or if we ignore errors return false; @@ -74,11 +99,17 @@ struct SetColumns { } }; +//! Struct used to know if we have a date or timestamp type already identified in this CSV File +struct HasType { + bool date = false; + bool timestamp = false; +}; + //! Sniffer that detects Header, Dialect and Types of CSV Files class CSVSniffer { public: explicit CSVSniffer(CSVReaderOptions &options_p, shared_ptr buffer_manager_p, - CSVStateMachineCache &state_machine_cache, SetColumns set_columns = {}); + CSVStateMachineCache &state_machine_cache, bool default_null_to_varchar = true); //! Main method that sniffs the CSV file, returns the types, names and options as a result //! CSV Sniffing consists of five steps: @@ -89,8 +120,22 @@ class CSVSniffer { //! 5. Type Replacement: Replaces the types of the columns if the user specified them SnifferResult SniffCSV(bool force_match = false); + //! I call it adaptive, since that's a sexier term. + //! In practice this Function that only sniffs the first two rows, to verify if a header exists and what are the + //! data types It does this considering a priorly set CSV schema. If there is a mismatch of the schema it runs the + //! full on blazing all guns sniffer, if that still fails it tells the user to union_by_name. + //! It returns the projection order. + SnifferResult AdaptiveSniff(const CSVSchema &file_schema); + + //! Function that only sniffs the first two rows, to verify if a header exists and what are the data types + AdaptiveSnifferResult MinimalSniff(); + static NewLineIdentifier DetectNewLineDelimiter(CSVBufferManager &buffer_manager); + //! If a string_t value can be cast to a type + static bool CanYouCastIt(ClientContext &context, const string_t value, const LogicalType &type, + const DialectOptions &dialect_options, const bool is_null, const char decimal_separator); + private: //! CSV State Machine Cache CSVStateMachineCache &state_machine_cache; @@ -106,6 +151,7 @@ class CSVSniffer { SetColumns set_columns; shared_ptr error_handler; shared_ptr detection_error_handler; + //! Sets the result options void SetResultOptions(); @@ -115,42 +161,41 @@ class CSVSniffer { //! First phase of auto detection: detect CSV dialect (i.e. delimiter, quote rules, etc) void DetectDialect(); //! Functions called in the main DetectDialect(); function - //! 1. Generates the search space candidates for the dialect - void GenerateCandidateDetectionSearchSpace(vector &delim_candidates, vector "erule_candidates, - unordered_map> "e_candidates_map, - unordered_map> &escape_candidates_map); - //! 2. Generates the search space candidates for the state machines + //! 1. Generates the search space candidates for the state machines void GenerateStateMachineSearchSpace(vector> &column_count_scanners, - const vector &delimiter_candidates, - const vector "erule_candidates, - const unordered_map> "e_candidates_map, - const unordered_map> &escape_candidates_map); - //! 3. Analyzes if dialect candidate is a good candidate to be considered, if so, it adds it to the candidates + const DialectCandidates &dialect_candidates); + + //! 2. Analyzes if dialect candidate is a good candidate to be considered, if so, it adds it to the candidates void AnalyzeDialectCandidate(unique_ptr, idx_t &rows_read, idx_t &best_consistent_rows, - idx_t &prev_padding_count); - //! 4. Refine Candidates over remaining chunks + idx_t &prev_padding_count, idx_t &min_ignored_rows); + //! 3. Refine Candidates over remaining chunks void RefineCandidates(); //! Checks if candidate still produces good values for the next chunk - bool RefineCandidateNextChunk(ColumnCountScanner &candidate); + bool RefineCandidateNextChunk(ColumnCountScanner &candidate) const; //! ------------------------------------------------------// //! ------------------- Type Detection ------------------ // //! ------------------------------------------------------// - //! Second phase of auto detection: detect types, format template candidates + //! Second phase of auto-detection: detect types, format template candidates //! ordered by descending specificity (~ from high to low) void DetectTypes(); //! Change the date format for the type to the string //! Try to cast a string value to the specified sql type - bool TryCastValue(CSVStateMachine &candidate, const Value &value, const LogicalType &sql_type); - void SetDateFormat(CSVStateMachine &candidate, const string &format_specifier, const LogicalTypeId &sql_type); + static void SetDateFormat(CSVStateMachine &candidate, const string &format_specifier, + const LogicalTypeId &sql_type); //! Function that initialized the necessary variables used for date and timestamp detection void InitializeDateAndTimeStampDetection(CSVStateMachine &candidate, const string &separator, const LogicalType &sql_type); + //! Sets user defined date and time formats (if any) + void SetUserDefinedDateTimeFormat(CSVStateMachine &candidate) const; //! Functions that performs detection for date and timestamp formats void DetectDateAndTimeStampFormats(CSVStateMachine &candidate, const LogicalType &sql_type, const string &separator, - Value &dummy_val); + const string_t &dummy_val); + //! Sniffs the types from a data chunk + void SniffTypes(DataChunk &data_chunk, CSVStateMachine &state_machine, + unordered_map> &info_sql_types_candidates, idx_t start_idx_detection); //! Variables for Type Detection //! Format Candidates for Date and Timestamp Types @@ -163,9 +208,10 @@ class CSVSniffer { unordered_map> best_sql_types_candidates_per_column_idx; map> best_format_candidates; unique_ptr best_candidate; - vector best_header_row; + vector best_header_row; //! Variable used for sniffing date and timestamp map format_candidates; + map original_format_candidates; //! ------------------------------------------------------// //! ------------------ Type Refinement ------------------ // @@ -173,17 +219,26 @@ class CSVSniffer { void RefineTypes(); bool TryCastVector(Vector &parse_chunk_col, idx_t size, const LogicalType &sql_type); vector detected_types; - + //! If when finding a SQLNULL type in type detection we default it to varchar + const bool default_null_to_varchar; //! ------------------------------------------------------// //! ------------------ Header Detection ----------------- // //! ------------------------------------------------------// void DetectHeader(); + static bool DetectHeaderWithSetColumn(ClientContext &context, vector &best_header_row, + const SetColumns &set_columns, CSVReaderOptions &options); + static vector + DetectHeaderInternal(ClientContext &context, vector &best_header_row, CSVStateMachine &state_machine, + const SetColumns &set_columns, + unordered_map> &best_sql_types_candidates_per_column_idx, + CSVReaderOptions &options, CSVErrorHandler &error_handler); vector names; //! ------------------------------------------------------// //! ------------------ Type Replacement ----------------- // //! ------------------------------------------------------// void ReplaceTypes(); + vector manually_set; }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/sniffer/sniff_result.hpp b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/sniffer/sniff_result.hpp new file mode 100644 index 00000000..2a8e0de1 --- /dev/null +++ b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/sniffer/sniff_result.hpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/execution/operator/csv_scanner/sniffer/sniff_result.hpp +// +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "duckdb/execution/operator/csv_scanner/csv_state_machine.hpp" +#include "duckdb/common/vector.hpp" + +namespace duckdb { + +//! Struct to store the result of the Sniffer +struct SnifferResult { + SnifferResult(vector return_types_p, vector names_p) + : return_types(std::move(return_types_p)), names(std::move(names_p)) { + } + //! Return Types that were detected + vector return_types; + //! Column Names that were detected + vector names; +}; + +struct AdaptiveSnifferResult : SnifferResult { + AdaptiveSnifferResult(vector return_types_p, vector names_p, bool more_than_one_row_p) + : SnifferResult(std::move(return_types_p), std::move(names_p)), more_than_one_row(more_than_one_row_p) { + } + bool more_than_one_row; + SnifferResult ToSnifferResult() { + return {return_types, names}; + } +}; +} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/string_value_scanner.hpp b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/string_value_scanner.hpp index 20182b5e..e0047a66 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/string_value_scanner.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/string_value_scanner.hpp @@ -186,7 +186,7 @@ class StringValueResult : public ScannerResult { //! Internal Data Chunk used for flushing DataChunk parse_chunk; - idx_t number_of_rows = 0; + int64_t number_of_rows = 0; idx_t cur_col_id = 0; bool figure_out_new_line = false; //! Information to properly handle errors diff --git a/src/duckdb/src/include/duckdb/execution/operator/join/perfect_hash_join_executor.hpp b/src/duckdb/src/include/duckdb/execution/operator/join/perfect_hash_join_executor.hpp index 33fcb6a2..d5dd3e4a 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/join/perfect_hash_join_executor.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/join/perfect_hash_join_executor.hpp @@ -26,7 +26,6 @@ struct PerfectHashJoinStats { Value probe_max; bool is_build_small = false; bool is_build_dense = false; - bool is_probe_in_domain = false; idx_t build_range = 0; idx_t estimated_cardinality = 0; }; diff --git a/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_export.hpp b/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_export.hpp index 4032aea6..fd7f4981 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_export.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_export.hpp @@ -34,17 +34,14 @@ class PhysicalExport : public PhysicalOperator { public: PhysicalExport(vector types, CopyFunction function, unique_ptr info, - idx_t estimated_cardinality, BoundExportData exported_tables) - : PhysicalOperator(PhysicalOperatorType::EXPORT, std::move(types), estimated_cardinality), - function(std::move(function)), info(std::move(info)), exported_tables(std::move(exported_tables)) { - } + idx_t estimated_cardinality, unique_ptr exported_tables); //! The copy function to use to read the file CopyFunction function; //! The binding info containing the set of options for reading the file unique_ptr info; //! The table info for each table that will be exported - BoundExportData exported_tables; + unique_ptr exported_tables; public: // Source interface diff --git a/src/duckdb/src/include/duckdb/function/table_function.hpp b/src/duckdb/src/include/duckdb/function/table_function.hpp index 68883293..d15990d0 100644 --- a/src/duckdb/src/include/duckdb/function/table_function.hpp +++ b/src/duckdb/src/include/duckdb/function/table_function.hpp @@ -242,7 +242,7 @@ class TableFunction : public SimpleNamedParameterFunction { // NOLINT: work-arou //! The returned FunctionData object should be constant and should not be changed during execution. table_function_bind_t bind; //! (Optional) Bind replace function - //! This function is called before the regular bind function. It allows returning a TableRef will be used to + //! This function is called before the regular bind function. It allows returning a TableRef that will be used to //! to generate a logical plan that replaces the LogicalGet of a regularly bound TableFunction. The BindReplace can //! also return a nullptr to indicate a regular bind needs to be performed instead. table_function_bind_replace_t bind_replace; diff --git a/src/duckdb/src/include/duckdb/main/database.hpp b/src/duckdb/src/include/duckdb/main/database.hpp index 222a36c0..2a6fffa9 100644 --- a/src/duckdb/src/include/duckdb/main/database.hpp +++ b/src/duckdb/src/include/duckdb/main/database.hpp @@ -12,6 +12,7 @@ #include "duckdb/main/valid_checker.hpp" #include "duckdb/common/winapi.hpp" #include "duckdb/main/extension.hpp" +#include "duckdb/main/capi/extension_api.hpp" #include "duckdb/main/extension_install_info.hpp" #include "duckdb/main/settings.hpp" @@ -58,6 +59,8 @@ class DatabaseInstance : public enable_shared_from_this { DUCKDB_API ValidChecker &GetValidChecker(); DUCKDB_API void SetExtensionLoaded(const string &extension_name, ExtensionInstallInfo &install_info); + DUCKDB_API const duckdb_ext_api_v0 GetExtensionAPIV0(); + idx_t NumberOfThreads(); DUCKDB_API static DatabaseInstance &GetDatabase(ClientContext &context); @@ -91,6 +94,8 @@ class DatabaseInstance : public enable_shared_from_this { ValidChecker db_validity; unique_ptr db_file_system; shared_ptr db_cache_entry; + + duckdb_ext_api_v0 (*create_api_v0)(); }; //! The database object. This object holds the catalog and all the diff --git a/src/duckdb/src/include/duckdb/main/extension_entries.hpp b/src/duckdb/src/include/duckdb/main/extension_entries.hpp index 665b85fb..ae31c576 100644 --- a/src/duckdb/src/include/duckdb/main/extension_entries.hpp +++ b/src/duckdb/src/include/duckdb/main/extension_entries.hpp @@ -410,6 +410,7 @@ static constexpr ExtensionEntry EXTENSION_SETTINGS[] = { {"binary_as_string", "parquet"}, {"ca_cert_file", "httpfs"}, {"calendar", "icu"}, + {"enable_geoparquet_conversion", "parquet"}, {"enable_server_cert_verification", "httpfs"}, {"force_download", "httpfs"}, {"hf_max_per_page", "httpfs"}, diff --git a/src/duckdb/src/include/duckdb/main/profiling_info.hpp b/src/duckdb/src/include/duckdb/main/profiling_info.hpp index a5722351..5e9ee287 100644 --- a/src/duckdb/src/include/duckdb/main/profiling_info.hpp +++ b/src/duckdb/src/include/duckdb/main/profiling_info.hpp @@ -26,38 +26,36 @@ namespace duckdb { class ProfilingInfo { public: - // Enabling a metric adds it to this set. + //! Enabling a metric adds it to this set. profiler_settings_t settings; - // Contains all enabled metrics. + //! This set contains the expanded to-be-collected metrics, which can differ from 'settings'. + profiler_settings_t expanded_settings; + //! Contains all enabled metrics. profiler_metrics_t metrics; - // Additional metrics. + //! Additional metrics. // FIXME: move to metrics. InsertionOrderPreservingMap extra_info; public: ProfilingInfo() = default; - explicit ProfilingInfo(profiler_settings_t &n_settings, idx_t depth = 0) : settings(n_settings) { - if (depth == 0) { - settings.insert(MetricsType::QUERY_NAME); - } else { - settings.insert(MetricsType::OPERATOR_TYPE); - } - ResetMetrics(); - } + explicit ProfilingInfo(const profiler_settings_t &n_settings, const idx_t depth = 0); ProfilingInfo(ProfilingInfo &) = default; ProfilingInfo &operator=(ProfilingInfo const &) = default; public: static profiler_settings_t DefaultSettings(); + static profiler_settings_t DefaultRootSettings(); static profiler_settings_t DefaultOperatorSettings(); - static profiler_settings_t AllSettings(); public: void ResetMetrics(); - bool Enabled(const MetricsType setting) const; + //! Returns true, if the query profiler must collect this metric. + static bool Enabled(const profiler_settings_t &settings, const MetricsType metric); + //! Expand metrics depending on the collection of other metrics. + static void Expand(profiler_settings_t &settings, const MetricsType metric); public: - string GetMetricAsString(MetricsType setting) const; + string GetMetricAsString(const MetricsType metric) const; void WriteMetricsToJSON(duckdb_yyjson::yyjson_mut_doc *doc, duckdb_yyjson::yyjson_mut_val *destination); public: @@ -68,20 +66,20 @@ class ProfilingInfo { } template - void AddToMetric(const MetricsType setting, const Value &value) { - D_ASSERT(!metrics[setting].IsNull()); - if (metrics.find(setting) == metrics.end()) { - metrics[setting] = value; + void AddToMetric(const MetricsType type, const Value &value) { + D_ASSERT(!metrics[type].IsNull()); + if (metrics.find(type) == metrics.end()) { + metrics[type] = value; return; } - auto new_value = metrics[setting].GetValue() + value.GetValue(); - metrics[setting] = Value::CreateValue(new_value); + auto new_value = metrics[type].GetValue() + value.GetValue(); + metrics[type] = Value::CreateValue(new_value); } template - void AddToMetric(const MetricsType setting, const METRIC_TYPE &value) { + void AddToMetric(const MetricsType type, const METRIC_TYPE &value) { auto new_value = Value::CreateValue(value); - return AddToMetric(setting, new_value); + return AddToMetric(type, new_value); } }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/main/query_profiler.hpp b/src/duckdb/src/include/duckdb/main/query_profiler.hpp index 4a9ab9e7..24072912 100644 --- a/src/duckdb/src/include/duckdb/main/query_profiler.hpp +++ b/src/duckdb/src/include/duckdb/main/query_profiler.hpp @@ -64,7 +64,10 @@ class OperatorProfiler { public: DUCKDB_API explicit OperatorProfiler(ClientContext &context); + ~OperatorProfiler() { + } +public: DUCKDB_API void StartOperator(optional_ptr phys_op); DUCKDB_API void EndOperator(optional_ptr chunk); @@ -72,20 +75,14 @@ class OperatorProfiler { DUCKDB_API void Flush(const PhysicalOperator &phys_op); DUCKDB_API OperatorInformation &GetOperatorInfo(const PhysicalOperator &phys_op); - ~OperatorProfiler() { - } - +public: ClientContext &context; - bool HasOperatorSetting(const MetricsType &metric) const { - return operator_settings.find(metric) != operator_settings.end(); - } - private: //! Whether or not the profiler is enabled bool enabled; //! Sub-settings for the operator profiler - profiler_settings_t operator_settings; + profiler_settings_t settings; //! The timer used to time the execution time of the individual Physical Operators Profiler op; @@ -113,7 +110,8 @@ class QueryProfiler { using TreeMap = reference_map_t>; private: - unique_ptr CreateTree(const PhysicalOperator &root, profiler_settings_t settings, idx_t depth = 0); + unique_ptr CreateTree(const PhysicalOperator &root, const profiler_settings_t &settings, + const idx_t depth = 0); void Render(const ProfilingNode &node, std::ostream &str) const; public: diff --git a/src/duckdb/src/include/duckdb/main/secret/secret.hpp b/src/duckdb/src/include/duckdb/main/secret/secret.hpp index decd62ed..ee721d7f 100644 --- a/src/duckdb/src/include/duckdb/main/secret/secret.hpp +++ b/src/duckdb/src/include/duckdb/main/secret/secret.hpp @@ -80,6 +80,13 @@ struct SecretType { string default_provider; }; +enum class SecretSerializationType : uint8_t { + //! The secret is serialized with a custom serialization function + CUSTOM = 0, + //! The secret has been serialized as a KeyValueSecret + KEY_VALUE_SECRET = 1 +}; + //! Base class from which BaseSecret classes can be made. class BaseSecret { friend class SecretManager; @@ -187,7 +194,7 @@ class KeyValueSecret : public BaseSecret { for (const auto &entry : ListValue::GetChildren(secret_map_value)) { auto kv_struct = StructValue::GetChildren(entry); - result->secret_map[kv_struct[0].ToString()] = kv_struct[1].ToString(); + result->secret_map[kv_struct[0].ToString()] = kv_struct[1]; } Value redact_set_value; diff --git a/src/duckdb/src/include/duckdb/main/table_description.hpp b/src/duckdb/src/include/duckdb/main/table_description.hpp index 2a35b4f1..151592f4 100644 --- a/src/duckdb/src/include/duckdb/main/table_description.hpp +++ b/src/duckdb/src/include/duckdb/main/table_description.hpp @@ -13,12 +13,26 @@ namespace duckdb { struct TableDescription { +public: //! The schema of the table string schema; //! The table name of the table string table; //! The columns of the table vector columns; + +public: + idx_t PhysicalColumnCount() const { + idx_t count = 0; + for (auto &column : columns) { + if (column.Generated()) { + continue; + } + count++; + } + D_ASSERT(count != 0); + return count; + } }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/optimizer/unnest_rewriter.hpp b/src/duckdb/src/include/duckdb/optimizer/unnest_rewriter.hpp index 3798cbd4..842d5ef2 100644 --- a/src/duckdb/src/include/duckdb/optimizer/unnest_rewriter.hpp +++ b/src/duckdb/src/include/duckdb/optimizer/unnest_rewriter.hpp @@ -8,8 +8,8 @@ #pragma once -#include "duckdb/planner/logical_operator.hpp" #include "duckdb/common/pair.hpp" +#include "duckdb/planner/logical_operator.hpp" namespace duckdb { @@ -61,14 +61,14 @@ class UnnestRewriter { private: //! Find delim joins that contain an UNNEST - void FindCandidates(unique_ptr *op_ptr, vector *> &candidates); + void FindCandidates(unique_ptr &op, vector>> &candidates); //! Rewrite a delim join that contains an UNNEST - bool RewriteCandidate(unique_ptr *candidate); + bool RewriteCandidate(unique_ptr &candidate); //! Update the bindings of the RHS sequence of LOGICAL_PROJECTION(s) - void UpdateRHSBindings(unique_ptr *plan_ptr, unique_ptr *candidate, + void UpdateRHSBindings(unique_ptr &plan, unique_ptr &candidate, UnnestRewriterPlanUpdater &updater); //! Update the bindings of the BOUND_UNNEST expression of the LOGICAL_UNNEST - void UpdateBoundUnnestBindings(UnnestRewriterPlanUpdater &updater, unique_ptr *candidate); + void UpdateBoundUnnestBindings(UnnestRewriterPlanUpdater &updater, unique_ptr &candidate); //! Store all delim columns of the delim join void GetDelimColumns(LogicalOperator &op); diff --git a/src/duckdb/src/include/duckdb/parser/parsed_data/exported_table_data.hpp b/src/duckdb/src/include/duckdb/parser/parsed_data/exported_table_data.hpp index b3f26a9b..192def09 100644 --- a/src/duckdb/src/include/duckdb/parser/parsed_data/exported_table_data.hpp +++ b/src/duckdb/src/include/duckdb/parser/parsed_data/exported_table_data.hpp @@ -1,7 +1,7 @@ //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/parser/parsed_data/export_table_data.hpp +// duckdb/parser/parsed_data/exported_table_data.hpp // // //===----------------------------------------------------------------------===// @@ -28,16 +28,23 @@ struct ExportedTableData { string file_path; //! Not Null columns, if any vector not_null_columns; + + void Serialize(Serializer &serializer) const; + static ExportedTableData Deserialize(Deserializer &deserializer); }; struct ExportedTableInfo { - ExportedTableInfo(TableCatalogEntry &entry, ExportedTableData table_data_p, vector ¬_null_columns_p) - : entry(entry), table_data(std::move(table_data_p)) { - table_data.not_null_columns = not_null_columns_p; - } + ExportedTableInfo(TableCatalogEntry &entry, ExportedTableData table_data_p, vector ¬_null_columns_p); + ExportedTableInfo(ClientContext &context, ExportedTableData table_data); TableCatalogEntry &entry; ExportedTableData table_data; + + void Serialize(Serializer &serializer) const; + static ExportedTableInfo Deserialize(Deserializer &deserializer); + +private: + static TableCatalogEntry &GetEntry(ClientContext &context, const ExportedTableData &table_data); }; struct BoundExportData : public ParseInfo { @@ -49,6 +56,9 @@ struct BoundExportData : public ParseInfo { } vector data; + + void Serialize(Serializer &serializer) const override; + static unique_ptr Deserialize(Deserializer &deserializer); }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/parser/transformer.hpp b/src/duckdb/src/include/duckdb/parser/transformer.hpp index 760526b1..0125f2f1 100644 --- a/src/duckdb/src/include/duckdb/parser/transformer.hpp +++ b/src/duckdb/src/include/duckdb/parser/transformer.hpp @@ -323,6 +323,8 @@ class Transformer { //! Transform a range var into a (schema) qualified name QualifiedName TransformQualifiedName(duckdb_libpgquery::PGRangeVar &root); + //! Transform a Postgres TypeName string into a LogicalType (non-LIST types) + LogicalType TransformTypeNameInternal(duckdb_libpgquery::PGTypeName &name); //! Transform a Postgres TypeName string into a LogicalType LogicalType TransformTypeName(duckdb_libpgquery::PGTypeName &name); diff --git a/src/duckdb/src/include/duckdb/planner/expression_binder/order_binder.hpp b/src/duckdb/src/include/duckdb/planner/expression_binder/order_binder.hpp index df8365cc..b2838c19 100644 --- a/src/duckdb/src/include/duckdb/planner/expression_binder/order_binder.hpp +++ b/src/duckdb/src/include/duckdb/planner/expression_binder/order_binder.hpp @@ -37,6 +37,9 @@ class OrderBinder { unique_ptr CreateExtraReference(unique_ptr expr); + //! Sets the query component, for error messages + void SetQueryComponent(string component = string()); + private: unique_ptr CreateProjectionReference(ParsedExpression &expr, const idx_t index); unique_ptr BindConstant(ParsedExpression &expr); @@ -46,6 +49,7 @@ class OrderBinder { vector> binders; optional_ptr>> extra_list; SelectBindState &bind_state; + string query_component = "ORDER BY"; }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/planner/operator/logical_export.hpp b/src/duckdb/src/include/duckdb/planner/operator/logical_export.hpp index 28a3686f..2115f09f 100644 --- a/src/duckdb/src/include/duckdb/planner/operator/logical_export.hpp +++ b/src/duckdb/src/include/duckdb/planner/operator/logical_export.hpp @@ -20,26 +20,23 @@ class LogicalExport : public LogicalOperator { static constexpr const LogicalOperatorType TYPE = LogicalOperatorType::LOGICAL_EXPORT; public: - LogicalExport(CopyFunction function, unique_ptr copy_info, BoundExportData exported_tables) - : LogicalOperator(LogicalOperatorType::LOGICAL_EXPORT), function(std::move(function)), - copy_info(std::move(copy_info)), exported_tables(std::move(exported_tables)) { - } - CopyFunction function; + LogicalExport(CopyFunction function, unique_ptr copy_info, unique_ptr exported_tables); + unique_ptr copy_info; - BoundExportData exported_tables; + CopyFunction function; + unique_ptr exported_tables; - void Serialize(Serializer &serializer) const override { - throw NotImplementedException("FIXME: Serialize LogicalExport statement"); - } - unique_ptr Deserialize(Deserializer &deserializer) { - throw NotImplementedException("FIXME: Deserialize LogicalExport statement"); - } + void Serialize(Serializer &serializer) const override; + static unique_ptr Deserialize(Deserializer &deserializer); -public: protected: + LogicalExport(ClientContext &context, unique_ptr copy_info, unique_ptr exported_tables); + void ResolveTypes() override { types.emplace_back(LogicalType::BOOLEAN); } + + CopyFunction GetCopyFunction(ClientContext &context, CopyInfo &info); }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/planner/table_filter.hpp b/src/duckdb/src/include/duckdb/planner/table_filter.hpp index ab4d754c..edcb975c 100644 --- a/src/duckdb/src/include/duckdb/planner/table_filter.hpp +++ b/src/duckdb/src/include/duckdb/planner/table_filter.hpp @@ -45,6 +45,7 @@ class TableFilter { //! Returns true if the statistics indicate that the segment can contain values that satisfy that filter virtual FilterPropagateResult CheckStatistics(BaseStatistics &stats) = 0; virtual string ToString(const string &column_name) = 0; + string DebugToString(); virtual unique_ptr Copy() const = 0; virtual bool Equals(const TableFilter &other) const { return filter_type != other.filter_type; diff --git a/src/duckdb/src/include/duckdb/storage/metadata/metadata_manager.hpp b/src/duckdb/src/include/duckdb/storage/metadata/metadata_manager.hpp index ec10765b..28110ece 100644 --- a/src/duckdb/src/include/duckdb/storage/metadata/metadata_manager.hpp +++ b/src/duckdb/src/include/duckdb/storage/metadata/metadata_manager.hpp @@ -50,9 +50,9 @@ class MetadataManager { ~MetadataManager(); MetadataHandle AllocateHandle(); - MetadataHandle Pin(MetadataPointer pointer); + MetadataHandle Pin(const MetadataPointer &pointer); - MetaBlockPointer GetDiskPointer(MetadataPointer pointer, uint32_t offset = 0); + MetaBlockPointer GetDiskPointer(const MetadataPointer &pointer, uint32_t offset = 0); MetadataPointer FromDiskPointer(MetaBlockPointer pointer); MetadataPointer RegisterDiskPointer(MetaBlockPointer pointer); diff --git a/src/duckdb/src/include/duckdb/storage/standard_buffer_manager.hpp b/src/duckdb/src/include/duckdb/storage/standard_buffer_manager.hpp index e4de9608..383882be 100644 --- a/src/duckdb/src/include/duckdb/storage/standard_buffer_manager.hpp +++ b/src/duckdb/src/include/duckdb/storage/standard_buffer_manager.hpp @@ -76,7 +76,7 @@ class StandardBufferManager : public BufferManager { void SetMemoryLimit(idx_t limit = (idx_t)-1) final; void SetSwapLimit(optional_idx limit = optional_idx()) final; - //! Returns informaton about memory usage + //! Returns information about memory usage vector GetMemoryUsageInfo() const override; //! Returns a list of all temporary files diff --git a/src/duckdb/src/include/duckdb/storage/statistics/distinct_statistics.hpp b/src/duckdb/src/include/duckdb/storage/statistics/distinct_statistics.hpp index fc6eb890..5bfe6e20 100644 --- a/src/duckdb/src/include/duckdb/storage/statistics/distinct_statistics.hpp +++ b/src/duckdb/src/include/duckdb/storage/statistics/distinct_statistics.hpp @@ -52,8 +52,6 @@ class DistinctStatistics { static constexpr double INTEGRAL_SAMPLE_RATE = 0.3; //! For concurrent access mutable mutex lock; - //! Preallocated vector for hashes - Vector hash_vec; }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/storage/table/segment_tree.hpp b/src/duckdb/src/include/duckdb/storage/table/segment_tree.hpp index e267d2e3..218cdac9 100644 --- a/src/duckdb/src/include/duckdb/storage/table/segment_tree.hpp +++ b/src/duckdb/src/include/duckdb/storage/table/segment_tree.hpp @@ -145,6 +145,7 @@ class SegmentTree { } SegmentNode node; segment->index = nodes.size(); + segment->next = nullptr; node.row_start = segment->start; node.node = std::move(segment); nodes.push_back(std::move(node)); diff --git a/src/duckdb/src/include/duckdb/transaction/duck_transaction.hpp b/src/duckdb/src/include/duckdb/transaction/duck_transaction.hpp index 0ca93998..5399b2ef 100644 --- a/src/duckdb/src/include/duckdb/transaction/duck_transaction.hpp +++ b/src/duckdb/src/include/duckdb/transaction/duck_transaction.hpp @@ -102,8 +102,12 @@ class DuckTransaction : public Transaction { reference_map_t> updated_collections; //! Lock for the active_locks map mutex active_locks_lock; + struct ActiveTableLock { + mutex checkpoint_lock_mutex; // protects access to the checkpoint_lock field in this class + weak_ptr checkpoint_lock; + }; //! Active locks on tables - reference_map_t> active_locks; + reference_map_t> active_locks; }; } // namespace duckdb diff --git a/src/duckdb/src/main/appender.cpp b/src/duckdb/src/main/appender.cpp index ae360852..33ef17bf 100644 --- a/src/duckdb/src/main/appender.cpp +++ b/src/duckdb/src/main/appender.cpp @@ -62,6 +62,9 @@ Appender::Appender(Connection &con, const string &schema_name, const string &tab } vector> defaults; for (auto &column : description->columns) { + if (column.Generated()) { + continue; + } types.push_back(column.Type()); defaults.push_back(column.HasDefaultValue() ? &column.DefaultValue() : nullptr); } diff --git a/src/duckdb/src/main/capi/profiling_info-c.cpp b/src/duckdb/src/main/capi/profiling_info-c.cpp index 7e563dd0..4936aed4 100644 --- a/src/duckdb/src/main/capi/profiling_info-c.cpp +++ b/src/duckdb/src/main/capi/profiling_info-c.cpp @@ -30,7 +30,7 @@ duckdb_value duckdb_profiling_info_get_value(duckdb_profiling_info info, const c auto &node = *reinterpret_cast(info); auto &profiling_info = node.GetProfilingInfo(); auto key_enum = EnumUtil::FromString(duckdb::StringUtil::Upper(key)); - if (!profiling_info.Enabled(key_enum)) { + if (!profiling_info.Enabled(profiling_info.settings, key_enum)) { return nullptr; } @@ -46,10 +46,13 @@ duckdb_value duckdb_profiling_info_get_metrics(duckdb_profiling_info info) { auto &node = *reinterpret_cast(info); auto &profiling_info = node.GetProfilingInfo(); - // FIXME: filter between operator metrics and query node metrics. duckdb::unordered_map metrics_map; for (const auto &metric : profiling_info.metrics) { auto key = EnumUtil::ToString(metric.first); + if (!profiling_info.Enabled(profiling_info.settings, metric.first)) { + continue; + } + if (key == EnumUtil::ToString(MetricsType::OPERATOR_TYPE)) { auto type = duckdb::PhysicalOperatorType(metric.second.GetValue()); metrics_map[key] = EnumUtil::ToString(type); diff --git a/src/duckdb/src/main/client_context.cpp b/src/duckdb/src/main/client_context.cpp index 467f28da..90c029ab 100644 --- a/src/duckdb/src/main/client_context.cpp +++ b/src/duckdb/src/main/client_context.cpp @@ -1132,13 +1132,19 @@ void ClientContext::Append(TableDescription &description, ColumnDataCollection & auto &table_entry = Catalog::GetEntry(*this, INVALID_CATALOG, description.schema, description.table); // verify that the table columns and types match up - if (description.columns.size() != table_entry.GetColumns().PhysicalColumnCount()) { + if (description.PhysicalColumnCount() != table_entry.GetColumns().PhysicalColumnCount()) { throw InvalidInputException("Failed to append: table entry has different number of columns!"); } + idx_t table_entry_col_idx = 0; for (idx_t i = 0; i < description.columns.size(); i++) { - if (description.columns[i].Type() != table_entry.GetColumns().GetColumn(PhysicalIndex(i)).Type()) { + auto &column = description.columns[i]; + if (column.Generated()) { + continue; + } + if (column.Type() != table_entry.GetColumns().GetColumn(PhysicalIndex(table_entry_col_idx)).Type()) { throw InvalidInputException("Failed to append: table entry has different number of columns!"); } + table_entry_col_idx++; } auto binder = Binder::CreateBinder(*this); auto bound_constraints = binder->BindConstraints(table_entry); diff --git a/src/duckdb/src/main/connection.cpp b/src/duckdb/src/main/connection.cpp index 65f5f255..4dd7ad11 100644 --- a/src/duckdb/src/main/connection.cpp +++ b/src/duckdb/src/main/connection.cpp @@ -19,7 +19,7 @@ namespace duckdb { Connection::Connection(DatabaseInstance &database) - : context(make_shared_ptr(database.shared_from_this())) { + : context(make_shared_ptr(database.shared_from_this())), warning_cb(nullptr) { ConnectionManager::Get(database).AddConnection(*context); #ifdef DEBUG EnableProfiling(); diff --git a/src/duckdb/src/main/database.cpp b/src/duckdb/src/main/database.cpp index 4308c4a0..0a82e459 100644 --- a/src/duckdb/src/main/database.cpp +++ b/src/duckdb/src/main/database.cpp @@ -25,6 +25,7 @@ #include "duckdb/storage/storage_extension.hpp" #include "duckdb/storage/storage_manager.hpp" #include "duckdb/transaction/transaction_manager.hpp" +#include "duckdb/main/capi/extension_api.hpp" #ifndef DUCKDB_NO_THREADS #include "duckdb/common/thread.hpp" @@ -56,6 +57,7 @@ DBConfig::~DBConfig() { DatabaseInstance::DatabaseInstance() { config.is_user_config = false; + create_api_v0 = nullptr; } DatabaseInstance::~DatabaseInstance() { @@ -258,6 +260,10 @@ void DatabaseInstance::LoadExtensionSettings() { } } +static duckdb_ext_api_v0 CreateAPIv0Wrapper() { + return CreateAPIv0(); +} + void DatabaseInstance::Initialize(const char *database_path, DBConfig *user_config) { DBConfig default_config; DBConfig *config_ptr = &default_config; @@ -267,6 +273,8 @@ void DatabaseInstance::Initialize(const char *database_path, DBConfig *user_conf Configure(*config_ptr, database_path); + create_api_v0 = CreateAPIv0Wrapper; + if (user_config && !user_config->options.use_temporary_directory) { // temporary directories explicitly disabled config.options.temporary_directory = string(); @@ -504,6 +512,11 @@ ValidChecker &DatabaseInstance::GetValidChecker() { return db_validity; } +const duckdb_ext_api_v0 DatabaseInstance::GetExtensionAPIV0() { + D_ASSERT(create_api_v0); + return create_api_v0(); +} + ValidChecker &ValidChecker::Get(DatabaseInstance &db) { return db.GetValidChecker(); } diff --git a/src/duckdb/src/main/extension/extension_helper.cpp b/src/duckdb/src/main/extension/extension_helper.cpp index 49483241..0742b503 100644 --- a/src/duckdb/src/main/extension/extension_helper.cpp +++ b/src/duckdb/src/main/extension/extension_helper.cpp @@ -363,7 +363,7 @@ ExtensionUpdateResult ExtensionHelper::UpdateExtension(ClientContext &context, c throw InvalidInputException("Failed to update the extension '%s', the extension is not installed!", extension_name); } else if (update_result.tag == ExtensionUpdateResultTag::UNKNOWN) { - throw InternalException("Failed to update extension '%s', an unknown error ocurred", extension_name); + throw InternalException("Failed to update extension '%s', an unknown error occurred", extension_name); } return update_result; } diff --git a/src/duckdb/src/main/extension/extension_install.cpp b/src/duckdb/src/main/extension/extension_install.cpp index b0ca9fb7..1258d95e 100644 --- a/src/duckdb/src/main/extension/extension_install.cpp +++ b/src/duckdb/src/main/extension/extension_install.cpp @@ -358,7 +358,15 @@ static unique_ptr InstallFromHttpUrl(DatabaseInstance &db, { auto fs = FileSystem::CreateLocal(); if (fs->FileExists(local_extension_path + ".info")) { - install_info = ExtensionInstallInfo::TryReadInfoFile(*fs, local_extension_path + ".info", extension_name); + try { + install_info = + ExtensionInstallInfo::TryReadInfoFile(*fs, local_extension_path + ".info", extension_name); + } catch (...) { + if (!options.force_install) { + // We are going to rewrite the file anyhow, so this is fine + throw; + } + } } } diff --git a/src/duckdb/src/main/extension/extension_load.cpp b/src/duckdb/src/main/extension/extension_load.cpp index c0a37ea9..b0282a71 100644 --- a/src/duckdb/src/main/extension/extension_load.cpp +++ b/src/duckdb/src/main/extension/extension_load.cpp @@ -91,7 +91,7 @@ struct ExtensionAccess { } //! Called by the extension get a pointer the correctly versioned extension C API struct. - static void *GetAPI(duckdb_extension_info info, const char *version) { + static const void *GetAPI(duckdb_extension_info info, const char *version) { string version_string = version; idx_t major, minor, patch; @@ -106,7 +106,8 @@ struct ExtensionAccess { "Unsupported C CAPI version detected during extension initialization: " + string(version)); return nullptr; } - load_state.api_struct = CreateAPIv0(); + + load_state.api_struct = load_state.db.GetExtensionAPIV0(); return &load_state.api_struct; } }; diff --git a/src/duckdb/src/main/extension_install_info.cpp b/src/duckdb/src/main/extension_install_info.cpp index 933a4a96..8c9e69e0 100644 --- a/src/duckdb/src/main/extension_install_info.cpp +++ b/src/duckdb/src/main/extension_install_info.cpp @@ -100,7 +100,7 @@ unique_ptr ExtensionInstallInfo::TryReadInfoFile(FileSyste } catch (std::exception &ex) { ErrorData error(ex); throw IOException( - "Failed to read info file for '%s' extension: '%s'.\nA serialization error occured: '%s'\n%s", + "Failed to read info file for '%s' extension: '%s'.\nA serialization error occurred: '%s'\n%s", extension_name, info_file_path, error.RawMessage(), hint); } } diff --git a/src/duckdb/src/main/profiling_info.cpp b/src/duckdb/src/main/profiling_info.cpp index 53645782..0614747a 100644 --- a/src/duckdb/src/main/profiling_info.cpp +++ b/src/duckdb/src/main/profiling_info.cpp @@ -9,44 +9,53 @@ using namespace duckdb_yyjson; // NOLINT namespace duckdb { +ProfilingInfo::ProfilingInfo(const profiler_settings_t &n_settings, const idx_t depth) : settings(n_settings) { + // Expand. + if (depth == 0) { + settings.insert(MetricsType::QUERY_NAME); + } else { + settings.insert(MetricsType::OPERATOR_TYPE); + } + for (const auto &metric : settings) { + Expand(expanded_settings, metric); + } + + // Reduce. + if (depth == 0) { + auto op_metrics = DefaultOperatorSettings(); + for (const auto metric : op_metrics) { + settings.erase(metric); + } + } else { + auto root_metrics = DefaultRootSettings(); + for (const auto metric : root_metrics) { + settings.erase(metric); + } + } + ResetMetrics(); +} + profiler_settings_t ProfilingInfo::DefaultSettings() { return {MetricsType::QUERY_NAME, MetricsType::BLOCKED_THREAD_TIME, MetricsType::CPU_TIME, MetricsType::EXTRA_INFO, MetricsType::CUMULATIVE_CARDINALITY, MetricsType::OPERATOR_TYPE, MetricsType::OPERATOR_CARDINALITY, MetricsType::CUMULATIVE_ROWS_SCANNED, MetricsType::OPERATOR_ROWS_SCANNED, - MetricsType::OPERATOR_TIMING, MetricsType::RESULT_SET_SIZE}; + MetricsType::OPERATOR_TIMING, MetricsType::RESULT_SET_SIZE, MetricsType::LATENCY, + MetricsType::ROWS_RETURNED}; } -profiler_settings_t ProfilingInfo::DefaultOperatorSettings() { - return {MetricsType::OPERATOR_CARDINALITY, MetricsType::OPERATOR_ROWS_SCANNED, MetricsType::OPERATOR_TIMING, - MetricsType::RESULT_SET_SIZE}; +profiler_settings_t ProfilingInfo::DefaultRootSettings() { + return {MetricsType::QUERY_NAME, MetricsType::BLOCKED_THREAD_TIME, MetricsType::LATENCY, + MetricsType::ROWS_RETURNED}; } -profiler_settings_t ProfilingInfo::AllSettings() { - auto all_settings = DefaultSettings(); - auto optimizer_settings = MetricsUtils::GetOptimizerMetrics(); - auto phase_timings = MetricsUtils::GetPhaseTimingMetrics(); - - for (auto &setting : optimizer_settings) { - all_settings.insert(setting); - } - - for (auto &setting : phase_timings) { - all_settings.insert(setting); - } - - return all_settings; +profiler_settings_t ProfilingInfo::DefaultOperatorSettings() { + return {MetricsType::OPERATOR_CARDINALITY, MetricsType::OPERATOR_ROWS_SCANNED, MetricsType::OPERATOR_TIMING, + MetricsType::OPERATOR_TYPE}; } void ProfilingInfo::ResetMetrics() { metrics.clear(); - - auto all_settings = AllSettings(); - - for (auto &metric : all_settings) { - if (!Enabled(metric)) { - continue; - } - + for (auto &metric : expanded_settings) { if (MetricsUtils::IsOptimizerMetric(metric) || MetricsUtils::IsPhaseTimingMetric(metric)) { metrics[metric] = Value::CreateValue(0.0); continue; @@ -54,24 +63,25 @@ void ProfilingInfo::ResetMetrics() { switch (metric) { case MetricsType::QUERY_NAME: + metrics[metric] = Value::CreateValue(""); + break; + case MetricsType::LATENCY: case MetricsType::BLOCKED_THREAD_TIME: case MetricsType::CPU_TIME: - case MetricsType::OPERATOR_TIMING: { + case MetricsType::OPERATOR_TIMING: metrics[metric] = Value::CreateValue(0.0); break; - } - case MetricsType::OPERATOR_TYPE: { + case MetricsType::OPERATOR_TYPE: metrics[metric] = Value::CreateValue(0); break; - } + case MetricsType::ROWS_RETURNED: case MetricsType::RESULT_SET_SIZE: case MetricsType::CUMULATIVE_CARDINALITY: case MetricsType::OPERATOR_CARDINALITY: case MetricsType::CUMULATIVE_ROWS_SCANNED: - case MetricsType::OPERATOR_ROWS_SCANNED: { + case MetricsType::OPERATOR_ROWS_SCANNED: metrics[metric] = Value::CreateValue(0); break; - } case MetricsType::EXTRA_INFO: break; default: @@ -80,35 +90,45 @@ void ProfilingInfo::ResetMetrics() { } } -bool ProfilingInfo::Enabled(const MetricsType setting) const { - if (settings.find(setting) != settings.end()) { +bool ProfilingInfo::Enabled(const profiler_settings_t &settings, const MetricsType metric) { + if (settings.find(metric) != settings.end()) { return true; } + return false; +} - switch (setting) { - case MetricsType::OPERATOR_TIMING: - return Enabled(MetricsType::CPU_TIME); - case MetricsType::OPERATOR_CARDINALITY: - return Enabled(MetricsType::CUMULATIVE_CARDINALITY); - case MetricsType::OPERATOR_ROWS_SCANNED: - return Enabled(MetricsType::CUMULATIVE_ROWS_SCANNED); - default: - break; +void ProfilingInfo::Expand(profiler_settings_t &settings, const MetricsType metric) { + settings.insert(metric); + + switch (metric) { + case MetricsType::CPU_TIME: + settings.insert(MetricsType::OPERATOR_TIMING); + return; + case MetricsType::CUMULATIVE_CARDINALITY: + settings.insert(MetricsType::OPERATOR_CARDINALITY); + return; + case MetricsType::CUMULATIVE_ROWS_SCANNED: + settings.insert(MetricsType::OPERATOR_ROWS_SCANNED); + return; + case MetricsType::CUMULATIVE_OPTIMIZER_TIMING: + case MetricsType::ALL_OPTIMIZERS: { + auto optimizer_metrics = MetricsUtils::GetOptimizerMetrics(); + for (const auto optimizer_metric : optimizer_metrics) { + settings.insert(optimizer_metric); + } + return; } - - if (MetricsUtils::IsOptimizerMetric(setting)) { - return Enabled(MetricsType::CUMULATIVE_OPTIMIZER_TIMING); + default: + return; } - - return false; } -string ProfilingInfo::GetMetricAsString(MetricsType setting) const { - if (!Enabled(setting)) { - throw InternalException("Metric %s not enabled", EnumUtil::ToString(setting)); +string ProfilingInfo::GetMetricAsString(const MetricsType metric) const { + if (!Enabled(settings, metric)) { + throw InternalException("Metric %s not enabled", EnumUtil::ToString(metric)); } - if (setting == MetricsType::EXTRA_INFO) { + if (metric == MetricsType::EXTRA_INFO) { string result; for (auto &it : extra_info) { if (!result.empty()) { @@ -120,14 +140,12 @@ string ProfilingInfo::GetMetricAsString(MetricsType setting) const { } // The metric cannot be NULL and must be initialized. - D_ASSERT(!metrics.at(setting).IsNull()); - - if (setting == MetricsType::OPERATOR_TYPE) { - auto type = PhysicalOperatorType(metrics.at(setting).GetValue()); + D_ASSERT(!metrics.at(metric).IsNull()); + if (metric == MetricsType::OPERATOR_TYPE) { + auto type = PhysicalOperatorType(metrics.at(metric).GetValue()); return EnumUtil::ToString(type); } - - return metrics.at(setting).ToString(); + return metrics.at(metric).ToString(); } void ProfilingInfo::WriteMetricsToJSON(yyjson_mut_doc *doc, yyjson_mut_val *dest) { @@ -169,6 +187,7 @@ void ProfilingInfo::WriteMetricsToJSON(yyjson_mut_doc *doc, yyjson_mut_val *dest case MetricsType::QUERY_NAME: yyjson_mut_obj_add_strcpy(doc, dest, key_ptr, metrics[metric].GetValue().c_str()); break; + case MetricsType::LATENCY: case MetricsType::BLOCKED_THREAD_TIME: case MetricsType::CPU_TIME: case MetricsType::OPERATOR_TIMING: { @@ -179,6 +198,7 @@ void ProfilingInfo::WriteMetricsToJSON(yyjson_mut_doc *doc, yyjson_mut_val *dest yyjson_mut_obj_add_strcpy(doc, dest, key_ptr, GetMetricAsString(metric).c_str()); break; } + case MetricsType::ROWS_RETURNED: case MetricsType::RESULT_SET_SIZE: case MetricsType::CUMULATIVE_CARDINALITY: case MetricsType::OPERATOR_CARDINALITY: diff --git a/src/duckdb/src/main/query_profiler.cpp b/src/duckdb/src/main/query_profiler.cpp index 98b3bd10..4f91d46d 100644 --- a/src/duckdb/src/main/query_profiler.cpp +++ b/src/duckdb/src/main/query_profiler.cpp @@ -121,6 +121,7 @@ bool QueryProfiler::OperatorRequiresProfiling(PhysicalOperatorType op_type) { case PhysicalOperatorType::UNION: case PhysicalOperatorType::RECURSIVE_CTE: case PhysicalOperatorType::EMPTY_RESULT: + case PhysicalOperatorType::EXTENSION: return true; default: return false; @@ -134,9 +135,12 @@ void QueryProfiler::Finalize(ProfilingNode &node) { auto &info = node.GetProfilingInfo(); auto type = PhysicalOperatorType(info.GetMetricValue(MetricsType::OPERATOR_TYPE)); - if (type == PhysicalOperatorType::UNION && info.Enabled(MetricsType::OPERATOR_CARDINALITY)) { - info.AddToMetric(MetricsType::OPERATOR_CARDINALITY, - child->GetProfilingInfo().metrics[MetricsType::OPERATOR_CARDINALITY].GetValue()); + if (type == PhysicalOperatorType::UNION && + info.Enabled(info.expanded_settings, MetricsType::OPERATOR_CARDINALITY)) { + + auto &child_info = child->GetProfilingInfo(); + auto value = child_info.metrics[MetricsType::OPERATOR_CARDINALITY].GetValue(); + info.AddToMetric(MetricsType::OPERATOR_CARDINALITY, value); } } } @@ -147,12 +151,14 @@ void QueryProfiler::StartExplainAnalyze() { template static void GetCumulativeMetric(ProfilingNode &node, MetricsType cumulative_metric, MetricsType child_metric) { - node.GetProfilingInfo().metrics[cumulative_metric] = node.GetProfilingInfo().metrics[child_metric]; + auto &info = node.GetProfilingInfo(); + info.metrics[cumulative_metric] = info.metrics[child_metric]; + for (idx_t i = 0; i < node.GetChildCount(); i++) { auto child = node.GetChild(i); GetCumulativeMetric(*child, cumulative_metric, child_metric); - node.GetProfilingInfo().AddToMetric( - cumulative_metric, child->GetProfilingInfo().metrics[cumulative_metric].GetValue()); + auto value = child->GetProfilingInfo().metrics[cumulative_metric].GetValue(); + info.AddToMetric(cumulative_metric, value); } } @@ -174,51 +180,52 @@ void QueryProfiler::EndQuery() { } main_query.End(); - if (root && root->GetProfilingInfo().Enabled(MetricsType::OPERATOR_CARDINALITY)) { - Finalize(*root->GetChild(0)); + if (root) { + auto &info = root->GetProfilingInfo(); + if (info.Enabled(info.expanded_settings, MetricsType::OPERATOR_CARDINALITY)) { + Finalize(*root->GetChild(0)); + } } running = false; // Print or output the query profiling after query termination. // EXPLAIN ANALYZE output is not written by the profiler. if (IsEnabled() && !is_explain_analyze) { - // Expand the query info. if (root) { auto &info = root->GetProfilingInfo(); info = ProfilingInfo(ClientConfig::GetConfig(context).profiler_settings); + auto &child_info = root->children[0]->GetProfilingInfo(); info.metrics[MetricsType::QUERY_NAME] = query_info.query_name; - if (info.Enabled(MetricsType::BLOCKED_THREAD_TIME)) { + auto &settings = info.expanded_settings; + if (info.Enabled(settings, MetricsType::BLOCKED_THREAD_TIME)) { info.metrics[MetricsType::BLOCKED_THREAD_TIME] = query_info.blocked_thread_time; } - if (info.Enabled(MetricsType::OPERATOR_TIMING)) { - info.metrics[MetricsType::OPERATOR_TIMING] = main_query.Elapsed(); + if (info.Enabled(settings, MetricsType::LATENCY)) { + info.metrics[MetricsType::LATENCY] = main_query.Elapsed(); + } + if (info.Enabled(settings, MetricsType::ROWS_RETURNED)) { + info.metrics[MetricsType::ROWS_RETURNED] = child_info.metrics[MetricsType::OPERATOR_CARDINALITY]; } - if (info.Enabled(MetricsType::CPU_TIME)) { + if (info.Enabled(settings, MetricsType::CPU_TIME)) { GetCumulativeMetric(*root, MetricsType::CPU_TIME, MetricsType::OPERATOR_TIMING); } - if (info.Enabled(MetricsType::CUMULATIVE_CARDINALITY)) { + if (info.Enabled(settings, MetricsType::CUMULATIVE_CARDINALITY)) { GetCumulativeMetric(*root, MetricsType::CUMULATIVE_CARDINALITY, MetricsType::OPERATOR_CARDINALITY); } - if (info.Enabled(MetricsType::CUMULATIVE_ROWS_SCANNED)) { + if (info.Enabled(settings, MetricsType::CUMULATIVE_ROWS_SCANNED)) { GetCumulativeMetric(*root, MetricsType::CUMULATIVE_ROWS_SCANNED, MetricsType::OPERATOR_ROWS_SCANNED); } + if (info.Enabled(settings, MetricsType::RESULT_SET_SIZE)) { + info.metrics[MetricsType::RESULT_SET_SIZE] = child_info.metrics[MetricsType::RESULT_SET_SIZE]; + } MoveOptimizerPhasesToRoot(); - if (info.Enabled(MetricsType::CUMULATIVE_OPTIMIZER_TIMING)) { + if (info.Enabled(settings, MetricsType::CUMULATIVE_OPTIMIZER_TIMING)) { info.metrics.at(MetricsType::CUMULATIVE_OPTIMIZER_TIMING) = GetCumulativeOptimizers(*root); } - - if (info.Enabled(MetricsType::OPERATOR_TYPE)) { - info.settings.erase(MetricsType::OPERATOR_TYPE); - } - - if (info.Enabled(MetricsType::RESULT_SET_SIZE)) { - info.metrics[MetricsType::RESULT_SET_SIZE] = - root->children[0]->GetProfilingInfo().metrics[MetricsType::RESULT_SET_SIZE]; - } } string tree = ToString(); @@ -283,34 +290,20 @@ void QueryProfiler::EndPhase() { } } -bool SettingIsEnabled(const profiler_settings_t &settings, MetricsType metric) { - if (settings.find(metric) != settings.end()) { - return true; - } - - switch (metric) { - case MetricsType::OPERATOR_TIMING: - return SettingIsEnabled(settings, MetricsType::CPU_TIME); - case MetricsType::OPERATOR_CARDINALITY: - return SettingIsEnabled(settings, MetricsType::CUMULATIVE_CARDINALITY); - case MetricsType::OPERATOR_ROWS_SCANNED: - return SettingIsEnabled(settings, MetricsType::CUMULATIVE_ROWS_SCANNED); - default: - break; - } - - return false; -} - OperatorProfiler::OperatorProfiler(ClientContext &context) : context(context) { enabled = QueryProfiler::Get(context).IsEnabled(); - auto &settings = ClientConfig::GetConfig(context).profiler_settings; + auto &context_metrics = ClientConfig::GetConfig(context).profiler_settings; - profiler_settings_t op_metrics = ProfilingInfo::DefaultOperatorSettings(); - for (auto &metric : op_metrics) { - if (SettingIsEnabled(settings, metric)) { - operator_settings.insert(metric); - } + // Expand. + for (const auto metric : context_metrics) { + settings.insert(metric); + ProfilingInfo::Expand(settings, metric); + } + + // Reduce. + auto root_metrics = ProfilingInfo::DefaultRootSettings(); + for (const auto metric : root_metrics) { + settings.erase(metric); } } @@ -318,15 +311,13 @@ void OperatorProfiler::StartOperator(optional_ptr phys_o if (!enabled) { return; } - if (active_operator) { throw InternalException("OperatorProfiler: Attempting to call StartOperator while another operator is active"); } - active_operator = phys_op; - // start timing for current element - if (HasOperatorSetting(MetricsType::OPERATOR_TIMING)) { + // Start the timing of the current operator. + if (ProfilingInfo::Enabled(settings, MetricsType::OPERATOR_TIMING)) { op.Start(); } } @@ -335,26 +326,22 @@ void OperatorProfiler::EndOperator(optional_ptr chunk) { if (!enabled) { return; } - if (!active_operator) { throw InternalException("OperatorProfiler: Attempting to call EndOperator while another operator is active"); } - if (!operator_settings.empty()) { - // get the operator info for the current element - auto &curr_operator_info = GetOperatorInfo(*active_operator); - - // finish timing for the current element - if (HasOperatorSetting(MetricsType::OPERATOR_TIMING)) { + if (!settings.empty()) { + auto &info = GetOperatorInfo(*active_operator); + if (ProfilingInfo::Enabled(settings, MetricsType::OPERATOR_TIMING)) { op.End(); - curr_operator_info.AddTime(op.Elapsed()); + info.AddTime(op.Elapsed()); } - if (HasOperatorSetting(MetricsType::OPERATOR_CARDINALITY) && chunk) { - curr_operator_info.AddReturnedElements(chunk->size()); + if (ProfilingInfo::Enabled(settings, MetricsType::OPERATOR_CARDINALITY) && chunk) { + info.AddReturnedElements(chunk->size()); } - if (HasOperatorSetting(MetricsType::RESULT_SET_SIZE) && chunk) { - idx_t result_set_size = chunk->GetAllocationSize(); - curr_operator_info.AddResultSetSize(result_set_size); + if (ProfilingInfo::Enabled(settings, MetricsType::RESULT_SET_SIZE) && chunk) { + auto result_set_size = chunk->GetAllocationSize(); + info.AddResultSetSize(result_set_size); } } active_operator = nullptr; @@ -364,11 +351,10 @@ OperatorInformation &OperatorProfiler::GetOperatorInfo(const PhysicalOperator &p auto entry = timings.find(phys_op); if (entry != timings.end()) { return entry->second; - } else { - // add new entry - timings[phys_op] = OperatorInformation(); - return timings[phys_op]; } + // Add a new entry. + timings[phys_op] = OperatorInformation(); + return timings[phys_op]; } void OperatorProfiler::Flush(const PhysicalOperator &phys_op) { @@ -389,30 +375,31 @@ void QueryProfiler::Flush(OperatorProfiler &profiler) { auto &op = node.first.get(); auto entry = tree_map.find(op); D_ASSERT(entry != tree_map.end()); + auto &tree_node = entry->second.get(); + auto &info = tree_node.GetProfilingInfo(); - if (profiler.HasOperatorSetting(MetricsType::OPERATOR_TIMING)) { - tree_node.GetProfilingInfo().AddToMetric(MetricsType::OPERATOR_TIMING, node.second.time); + if (ProfilingInfo::Enabled(profiler.settings, MetricsType::OPERATOR_TIMING)) { + info.AddToMetric(MetricsType::OPERATOR_TIMING, node.second.time); } - if (profiler.HasOperatorSetting(MetricsType::OPERATOR_CARDINALITY)) { - tree_node.GetProfilingInfo().AddToMetric(MetricsType::OPERATOR_CARDINALITY, - node.second.elements_returned); + if (ProfilingInfo::Enabled(profiler.settings, MetricsType::OPERATOR_CARDINALITY)) { + info.AddToMetric(MetricsType::OPERATOR_CARDINALITY, node.second.elements_returned); } - if (profiler.HasOperatorSetting(MetricsType::OPERATOR_ROWS_SCANNED)) { + if (ProfilingInfo::Enabled(profiler.settings, MetricsType::OPERATOR_ROWS_SCANNED)) { if (op.type == PhysicalOperatorType::TABLE_SCAN) { auto &scan_op = op.Cast(); auto &bind_data = scan_op.bind_data; + if (bind_data && scan_op.function.cardinality) { auto cardinality = scan_op.function.cardinality(context, &(*bind_data)); if (cardinality && cardinality->has_estimated_cardinality) { - tree_node.GetProfilingInfo().AddToMetric(MetricsType::OPERATOR_ROWS_SCANNED, - cardinality->estimated_cardinality); + info.AddToMetric(MetricsType::OPERATOR_ROWS_SCANNED, cardinality->estimated_cardinality); } } } } - if (profiler.HasOperatorSetting(MetricsType::RESULT_SET_SIZE)) { - tree_node.GetProfilingInfo().AddToMetric(MetricsType::RESULT_SET_SIZE, node.second.result_set_size); + if (ProfilingInfo::Enabled(profiler.settings, MetricsType::RESULT_SET_SIZE)) { + info.AddToMetric(MetricsType::RESULT_SET_SIZE, node.second.result_set_size); } } profiler.timings.clear(); @@ -420,10 +407,15 @@ void QueryProfiler::Flush(OperatorProfiler &profiler) { void QueryProfiler::SetInfo(const double &blocked_thread_time) { lock_guard guard(flush_lock); - if (!IsEnabled() || !running || !root->GetProfilingInfo().Enabled(MetricsType::BLOCKED_THREAD_TIME)) { + if (!IsEnabled() || !running) { return; } + auto &info = root->GetProfilingInfo(); + auto metric_enabled = info.Enabled(info.expanded_settings, MetricsType::BLOCKED_THREAD_TIME); + if (!metric_enabled) { + return; + } query_info.blocked_thread_time = blocked_thread_time; } @@ -701,8 +693,8 @@ profiler_settings_t EraseQueryRootSettings(profiler_settings_t settings) { return settings; } -unique_ptr QueryProfiler::CreateTree(const PhysicalOperator &root_p, profiler_settings_t settings, - idx_t depth) { +unique_ptr QueryProfiler::CreateTree(const PhysicalOperator &root_p, const profiler_settings_t &settings, + const idx_t depth) { if (OperatorRequiresProfiling(root_p.type)) { query_requires_profiling = true; } @@ -718,11 +710,8 @@ unique_ptr QueryProfiler::CreateTree(const PhysicalOperator &root if (depth != 0) { info.AddToMetric(MetricsType::OPERATOR_TYPE, static_cast(root_p.type)); - if (info.Enabled(MetricsType::QUERY_NAME)) { - info.settings.erase(MetricsType::QUERY_NAME); - } } - if (info.Enabled(MetricsType::EXTRA_INFO)) { + if (info.Enabled(info.settings, MetricsType::EXTRA_INFO)) { info.extra_info = root_p.ParamsToString(); } @@ -769,10 +758,11 @@ void QueryProfiler::Print() { void QueryProfiler::MoveOptimizerPhasesToRoot() { auto &root_info = root->GetProfilingInfo(); auto &root_metrics = root_info.metrics; + for (auto &entry : phase_timings) { auto &phase = entry.first; auto &timing = entry.second; - if (root_info.Enabled(phase)) { + if (root_info.Enabled(root_info.expanded_settings, phase)) { root_metrics[phase] = Value::CreateValue(timing); } } diff --git a/src/duckdb/src/main/relation/read_csv_relation.cpp b/src/duckdb/src/main/relation/read_csv_relation.cpp index a23091ee..56eb0d6f 100644 --- a/src/duckdb/src/main/relation/read_csv_relation.cpp +++ b/src/duckdb/src/main/relation/read_csv_relation.cpp @@ -1,7 +1,7 @@ #include "duckdb/main/relation/read_csv_relation.hpp" #include "duckdb/execution/operator/csv_scanner/csv_buffer_manager.hpp" -#include "duckdb/execution/operator/csv_scanner/csv_sniffer.hpp" +#include "duckdb/execution/operator/csv_scanner/sniffer/csv_sniffer.hpp" #include "duckdb/parser/expression/columnref_expression.hpp" #include "duckdb/parser/expression/comparison_expression.hpp" #include "duckdb/parser/expression/constant_expression.hpp" diff --git a/src/duckdb/src/main/secret/secret.cpp b/src/duckdb/src/main/secret/secret.cpp index 8535ef63..9a39b717 100644 --- a/src/duckdb/src/main/secret/secret.cpp +++ b/src/duckdb/src/main/secret/secret.cpp @@ -87,7 +87,8 @@ void KeyValueSecret::Serialize(Serializer &serializer) const { map_values.push_back(Value::STRUCT(map_struct)); } - auto map_type = LogicalType::MAP(LogicalType::VARCHAR, LogicalType::VARCHAR); + // Warning: the secret map is serialized into a single MAP value with type ANY + auto map_type = LogicalType::MAP(LogicalType::VARCHAR, LogicalType::ANY); auto map = Value::MAP(ListType::GetChildType(map_type), map_values); serializer.WriteProperty(201, "secret_map", map); diff --git a/src/duckdb/src/main/secret/secret_manager.cpp b/src/duckdb/src/main/secret/secret_manager.cpp index 72f5b924..045d1efe 100644 --- a/src/duckdb/src/main/secret/secret_manager.cpp +++ b/src/duckdb/src/main/secret/secret_manager.cpp @@ -97,6 +97,20 @@ unique_ptr SecretManager::DeserializeSecret(Deserializer &deserializ vector scope; deserializer.ReadList(103, "scope", [&](Deserializer::List &list, idx_t i) { scope.push_back(list.ReadElement()); }); + auto serialization_type = + deserializer.ReadPropertyWithExplicitDefault(104, "serialization_type", SecretSerializationType::CUSTOM); + + switch (serialization_type) { + // This allows us to skip looking up the secret type for deserialization altogether + case SecretSerializationType::KEY_VALUE_SECRET: + return KeyValueSecret::Deserialize(deserializer, {scope, type, provider, name}); + // Continues below: we need to do a type lookup to find the secret deserialize method + case SecretSerializationType::CUSTOM: + break; + default: + throw IOException("Unrecognized secret serialization type found in secret '%s': %s", secret_path, + EnumUtil::ToString(serialization_type)); + } SecretType deserialized_type; if (!TryLookupTypeInternal(type, deserialized_type)) { diff --git a/src/duckdb/src/optimizer/cte_filter_pusher.cpp b/src/duckdb/src/optimizer/cte_filter_pusher.cpp index 01063caa..b930cae0 100644 --- a/src/duckdb/src/optimizer/cte_filter_pusher.cpp +++ b/src/duckdb/src/optimizer/cte_filter_pusher.cpp @@ -39,8 +39,10 @@ unique_ptr CTEFilterPusher::Optimize(unique_ptr().table_index), - make_uniq(op)); + auto key = to_string(op.Cast().table_index); + auto value = make_uniq(op); + + cte_info_map.insert(key, std::move(value)); } else if (op.type == LogicalOperatorType::LOGICAL_FILTER && op.children[0]->type == LogicalOperatorType::LOGICAL_CTE_REF) { // We encountered a filtered CTE ref, update the according CTE info diff --git a/src/duckdb/src/optimizer/deliminator.cpp b/src/duckdb/src/optimizer/deliminator.cpp index 2771222e..805e5660 100644 --- a/src/duckdb/src/optimizer/deliminator.cpp +++ b/src/duckdb/src/optimizer/deliminator.cpp @@ -81,13 +81,6 @@ unique_ptr Deliminator::Optimize(unique_ptr op if (candidate.joins.size() == candidate.delim_get_count && all_removed) { delim_join.type = LogicalOperatorType::LOGICAL_COMPARISON_JOIN; delim_join.duplicate_eliminated_columns.clear(); - if (all_equality_conditions) { - for (auto &cond : delim_join.conditions) { - if (IsEqualityJoinCondition(cond)) { - cond.comparison = ExpressionType::COMPARE_NOT_DISTINCT_FROM; - } - } - } } // Only DelimJoins are ever created as SINGLE joins, diff --git a/src/duckdb/src/optimizer/in_clause_rewriter.cpp b/src/duckdb/src/optimizer/in_clause_rewriter.cpp index 36ddb11b..880964f5 100644 --- a/src/duckdb/src/optimizer/in_clause_rewriter.cpp +++ b/src/duckdb/src/optimizer/in_clause_rewriter.cpp @@ -6,12 +6,19 @@ #include "duckdb/planner/expression/bound_operator_expression.hpp" #include "duckdb/planner/operator/logical_column_data_get.hpp" #include "duckdb/planner/operator/logical_comparison_join.hpp" +#include "duckdb/planner/operator/logical_get.hpp" #include "duckdb/execution/expression_executor.hpp" namespace duckdb { unique_ptr InClauseRewriter::Rewrite(unique_ptr op) { if (op->children.size() == 1) { + if (op->children[0]->type == LogicalOperatorType::LOGICAL_GET) { + auto &get = op->children[0]->Cast(); + if (get.function.to_string && get.function.to_string(get.bind_data.get()) == "REMOTE") { + return op; + } + } root = std::move(op->children[0]); VisitOperatorExpressions(*op); op->children[0] = std::move(root); diff --git a/src/duckdb/src/optimizer/pushdown/pushdown_left_join.cpp b/src/duckdb/src/optimizer/pushdown/pushdown_left_join.cpp index a20b8132..e142a1d7 100644 --- a/src/duckdb/src/optimizer/pushdown/pushdown_left_join.cpp +++ b/src/duckdb/src/optimizer/pushdown/pushdown_left_join.cpp @@ -31,7 +31,7 @@ static bool FilterRemovesNull(ClientContext &context, ExpressionRewriter &rewrit 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 + // replace all BoundColumnRef expressions from the RHS with NULL constants in the copied expression copy = ReplaceColRefWithNull(std::move(copy), right_bindings); // attempt to flatten the expression by running the expression rewriter on it @@ -97,6 +97,9 @@ unique_ptr FilterPushdown::PushdownLeftJoin(unique_ptrfilter.get(), right_bindings)) { // the filter removes NULL values, turn it into an inner join join.join_type = JoinType::INNER; diff --git a/src/duckdb/src/optimizer/unnest_rewriter.cpp b/src/duckdb/src/optimizer/unnest_rewriter.cpp index f5d91061..796a9338 100644 --- a/src/duckdb/src/optimizer/unnest_rewriter.cpp +++ b/src/duckdb/src/optimizer/unnest_rewriter.cpp @@ -1,13 +1,13 @@ #include "duckdb/optimizer/unnest_rewriter.hpp" #include "duckdb/common/pair.hpp" -#include "duckdb/planner/operator/logical_delim_get.hpp" +#include "duckdb/planner/expression/bound_columnref_expression.hpp" +#include "duckdb/planner/expression/bound_unnest_expression.hpp" #include "duckdb/planner/operator/logical_comparison_join.hpp" -#include "duckdb/planner/operator/logical_unnest.hpp" +#include "duckdb/planner/operator/logical_delim_get.hpp" #include "duckdb/planner/operator/logical_projection.hpp" +#include "duckdb/planner/operator/logical_unnest.hpp" #include "duckdb/planner/operator/logical_window.hpp" -#include "duckdb/planner/expression/bound_unnest_expression.hpp" -#include "duckdb/planner/expression/bound_columnref_expression.hpp" namespace duckdb { @@ -35,8 +35,8 @@ void UnnestRewriterPlanUpdater::VisitExpression(unique_ptr *expressi unique_ptr UnnestRewriter::Optimize(unique_ptr op) { UnnestRewriterPlanUpdater updater; - vector *> candidates; - FindCandidates(&op, candidates); + vector>> candidates; + FindCandidates(op, candidates); // rewrite the plan and update the bindings for (auto &candidate : candidates) { @@ -47,7 +47,7 @@ unique_ptr UnnestRewriter::Optimize(unique_ptr // update the bindings of the BOUND_UNNEST expression UpdateBoundUnnestBindings(updater, candidate); // update the sequence of LOGICAL_PROJECTION(s) - UpdateRHSBindings(&op, candidate, updater); + UpdateRHSBindings(op, candidate, updater); // reset delim_columns.clear(); lhs_bindings.clear(); @@ -57,12 +57,11 @@ unique_ptr UnnestRewriter::Optimize(unique_ptr return op; } -void UnnestRewriter::FindCandidates(unique_ptr *op_ptr, - vector *> &candidates) { - auto op = op_ptr->get(); +void UnnestRewriter::FindCandidates(unique_ptr &op, + vector>> &candidates) { // search children before adding, so that we add candidates bottom-up for (auto &child : op->children) { - FindCandidates(&child, candidates); + FindCandidates(child, candidates); } // search for operator that has a LOGICAL_DELIM_JOIN as its child @@ -100,14 +99,15 @@ void UnnestRewriter::FindCandidates(unique_ptr *op_ptr, curr_op = &curr_op->get()->children[0]; } - if (curr_op->get()->type == LogicalOperatorType::LOGICAL_UNNEST) { - candidates.push_back(op_ptr); + if (curr_op->get()->type == LogicalOperatorType::LOGICAL_UNNEST && + curr_op->get()->children[0]->type == LogicalOperatorType::LOGICAL_DELIM_GET) { + candidates.push_back(op); } } -bool UnnestRewriter::RewriteCandidate(unique_ptr *candidate) { +bool UnnestRewriter::RewriteCandidate(unique_ptr &candidate) { - auto &topmost_op = (LogicalOperator &)**candidate; + auto &topmost_op = *candidate; if (topmost_op.type != LogicalOperatorType::LOGICAL_PROJECTION && topmost_op.type != LogicalOperatorType::LOGICAL_WINDOW && topmost_op.type != LogicalOperatorType::LOGICAL_FILTER && @@ -158,10 +158,10 @@ bool UnnestRewriter::RewriteCandidate(unique_ptr *candidate) { return true; } -void UnnestRewriter::UpdateRHSBindings(unique_ptr *plan_ptr, unique_ptr *candidate, +void UnnestRewriter::UpdateRHSBindings(unique_ptr &plan, unique_ptr &candidate, UnnestRewriterPlanUpdater &updater) { - auto &topmost_op = (LogicalOperator &)**candidate; + auto &topmost_op = *candidate; idx_t shift = lhs_bindings.size(); vector *> path_to_unnest; @@ -189,7 +189,7 @@ void UnnestRewriter::UpdateRHSBindings(unique_ptr *plan_ptr, un } // update all bindings by shifting them - updater.VisitOperator(*plan_ptr->get()); + updater.VisitOperator(*plan); updater.replace_bindings.clear(); // update all bindings coming from the LHS to RHS bindings @@ -212,7 +212,7 @@ void UnnestRewriter::UpdateRHSBindings(unique_ptr *plan_ptr, un unnest.expressions.clear(); unnest.children.clear(); // update the bindings of the plan - updater.VisitOperator(*plan_ptr->get()); + updater.VisitOperator(*plan); updater.replace_bindings.clear(); // add the children again for (auto &temp_bound_unnest : temp_bound_unnests) { @@ -253,9 +253,9 @@ void UnnestRewriter::UpdateRHSBindings(unique_ptr *plan_ptr, un } void UnnestRewriter::UpdateBoundUnnestBindings(UnnestRewriterPlanUpdater &updater, - unique_ptr *candidate) { + unique_ptr &candidate) { - auto &topmost_op = (LogicalOperator &)**candidate; + auto &topmost_op = *candidate; // traverse LOGICAL_PROJECTION(s) auto curr_op = &topmost_op.children[0]; diff --git a/src/duckdb/src/parallel/task_scheduler.cpp b/src/duckdb/src/parallel/task_scheduler.cpp index 743a52e5..fd6671a3 100644 --- a/src/duckdb/src/parallel/task_scheduler.cpp +++ b/src/duckdb/src/parallel/task_scheduler.cpp @@ -335,8 +335,13 @@ idx_t TaskScheduler::GetEstimatedCPUId() { #elif defined(_GNU_SOURCE) auto cpu = sched_getcpu(); if (cpu < 0) { +#ifndef DUCKDB_NO_THREADS // fallback to thread id return (idx_t)std::hash()(std::this_thread::get_id()); +#else + + return 0; +#endif } return (idx_t)cpu; #elif defined(__aarch64__) && defined(__APPLE__) @@ -345,8 +350,12 @@ idx_t TaskScheduler::GetEstimatedCPUId() { asm volatile("mrs %x0, tpidrro_el0" : "=r"(c)::"memory"); return (idx_t)(c & (1 << 3) - 1); #else +#ifndef DUCKDB_NO_THREADS // fallback to thread id return (idx_t)std::hash()(std::this_thread::get_id()); +#else + return 0; +#endif #endif #endif } diff --git a/src/duckdb/src/parser/parsed_data/exported_table_data.cpp b/src/duckdb/src/parser/parsed_data/exported_table_data.cpp new file mode 100644 index 00000000..d3573bc0 --- /dev/null +++ b/src/duckdb/src/parser/parsed_data/exported_table_data.cpp @@ -0,0 +1,22 @@ +#include "duckdb/parser/parsed_data/exported_table_data.hpp" +#include "duckdb/catalog/catalog.hpp" + +namespace duckdb { + +ExportedTableInfo::ExportedTableInfo(TableCatalogEntry &entry, ExportedTableData table_data_p, + vector ¬_null_columns_p) + : entry(entry), table_data(std::move(table_data_p)) { + table_data.not_null_columns = not_null_columns_p; +} + +ExportedTableInfo::ExportedTableInfo(ClientContext &context, ExportedTableData table_data_p) + : entry(GetEntry(context, table_data_p)), table_data(std::move(table_data_p)) { +} + +TableCatalogEntry &ExportedTableInfo::GetEntry(ClientContext &context, const ExportedTableData &table_data) { + return Catalog::GetEntry(context, CatalogType::TABLE_ENTRY, table_data.database_name, table_data.schema_name, + table_data.table_name) + .Cast(); +} + +} // namespace duckdb diff --git a/src/duckdb/src/parser/parsed_expression_iterator.cpp b/src/duckdb/src/parser/parsed_expression_iterator.cpp index 6d807800..8b29ed7f 100644 --- a/src/duckdb/src/parser/parsed_expression_iterator.cpp +++ b/src/duckdb/src/parser/parsed_expression_iterator.cpp @@ -102,6 +102,9 @@ void ParsedExpressionIterator::EnumerateChildren( if (star_expr.expr) { callback(star_expr.expr); } + for (auto &item : star_expr.replace_list) { + callback(item.second); + } break; } case ExpressionClass::SUBQUERY: { diff --git a/src/duckdb/src/parser/statement/insert_statement.cpp b/src/duckdb/src/parser/statement/insert_statement.cpp index 4255ebb9..fc384232 100644 --- a/src/duckdb/src/parser/statement/insert_statement.cpp +++ b/src/duckdb/src/parser/statement/insert_statement.cpp @@ -98,8 +98,10 @@ string InsertStatement::ToString() const { auto values_list = GetValuesList(); if (values_list) { D_ASSERT(!default_values); + auto saved_alias = values_list->alias; values_list->alias = string(); result += values_list->ToString(); + values_list->alias = saved_alias; } else if (select_statement) { D_ASSERT(!default_values); result += select_statement->ToString(); @@ -154,7 +156,11 @@ string InsertStatement::ToString() const { if (i > 0) { result += ", "; } - result += returning_list[i]->ToString(); + auto column = returning_list[i]->ToString(); + if (!returning_list[i]->alias.empty()) { + column += StringUtil::Format(" AS %s", KeywordHelper::WriteOptionallyQuoted(returning_list[i]->alias)); + } + result += column; } } return result; diff --git a/src/duckdb/src/parser/transform/expression/transform_boolean_test.cpp b/src/duckdb/src/parser/transform/expression/transform_boolean_test.cpp index 3c96f4da..8a7e2341 100644 --- a/src/duckdb/src/parser/transform/expression/transform_boolean_test.cpp +++ b/src/duckdb/src/parser/transform/expression/transform_boolean_test.cpp @@ -11,7 +11,7 @@ static unique_ptr TransformBooleanTestInternal(unique_ptr(Value::BOOLEAN(comparison_value)); Transformer::SetQueryLocation(*bool_value, query_location); - // we cast the argument to bool to remove ambiguity wrt function binding on the comparision + // we cast the argument to bool to remove ambiguity wrt function binding on the comparison auto cast_argument = make_uniq(LogicalType::BOOLEAN, std::move(argument)); auto result = make_uniq(comparison_type, std::move(cast_argument), std::move(bool_value)); diff --git a/src/duckdb/src/parser/transform/helpers/transform_typename.cpp b/src/duckdb/src/parser/transform/helpers/transform_typename.cpp index e3cab920..bd6b97a1 100644 --- a/src/duckdb/src/parser/transform/helpers/transform_typename.cpp +++ b/src/duckdb/src/parser/transform/helpers/transform_typename.cpp @@ -71,12 +71,7 @@ vector Transformer::TransformTypeModifiers(duckdb_libpgquery::PGTypeName return type_mods; } -LogicalType Transformer::TransformTypeName(duckdb_libpgquery::PGTypeName &type_name) { - if (type_name.type != duckdb_libpgquery::T_PGTypeName) { - throw ParserException("Expected a type"); - } - auto stack_checker = StackCheck(); - +LogicalType Transformer::TransformTypeNameInternal(duckdb_libpgquery::PGTypeName &type_name) { if (type_name.names->length > 1) { // qualified typename vector names; @@ -85,24 +80,27 @@ LogicalType Transformer::TransformTypeName(duckdb_libpgquery::PGTypeName &type_n } vector type_mods = TransformTypeModifiers(type_name); switch (type_name.names->length) { - case 2: + case 2: { return LogicalType::USER(INVALID_CATALOG, std::move(names[0]), std::move(names[1]), std::move(type_mods)); - case 3: + } + case 3: { return LogicalType::USER(std::move(names[0]), std::move(names[1]), std::move(names[2]), std::move(type_mods)); + } default: throw ParserException( "Too many qualifications for type name - expected [catalog.schema.name] or [schema.name]"); } } + auto name = PGPointerCast(type_name.names->tail->data.ptr_value)->val.str; // transform it to the SQL type LogicalTypeId base_type = TransformStringToLogicalTypeId(name); - LogicalType result_type; if (base_type == LogicalTypeId::LIST) { throw ParserException("LIST is not valid as a stand-alone type"); - } else if (base_type == LogicalTypeId::ENUM) { + } + if (base_type == LogicalTypeId::ENUM) { if (!type_name.typmods || type_name.typmods->length == 0) { throw ParserException("Enum needs a set of entries"); } @@ -118,7 +116,8 @@ LogicalType Transformer::TransformTypeName(duckdb_libpgquery::PGTypeName &type_n string_data[pos++] = StringVector::AddString(enum_vector, constant_value->val.val.str); } return LogicalType::ENUM(enum_vector, NumericCast(type_name.typmods->length)); - } else if (base_type == LogicalTypeId::STRUCT) { + } + if (base_type == LogicalTypeId::STRUCT) { if (!type_name.typmods || type_name.typmods->length == 0) { throw ParserException("Struct needs a name and entries"); } @@ -148,9 +147,9 @@ LogicalType Transformer::TransformTypeName(duckdb_libpgquery::PGTypeName &type_n children.push_back(make_pair(entry_name, entry_type)); } D_ASSERT(!children.empty()); - result_type = LogicalType::STRUCT(children); - - } else if (base_type == LogicalTypeId::MAP) { + return LogicalType::STRUCT(children); + } + if (base_type == LogicalTypeId::MAP) { if (!type_name.typmods || type_name.typmods->length != 2) { throw ParserException("Map type needs exactly two entries, key and value type"); } @@ -159,8 +158,9 @@ LogicalType Transformer::TransformTypeName(duckdb_libpgquery::PGTypeName &type_n auto value_type = TransformTypeName(*PGPointerCast(type_name.typmods->tail->data.ptr_value)); - result_type = LogicalType::MAP(std::move(key_type), std::move(value_type)); - } else if (base_type == LogicalTypeId::UNION) { + return LogicalType::MAP(std::move(key_type), std::move(value_type)); + } + if (base_type == LogicalTypeId::UNION) { if (!type_name.typmods || type_name.typmods->length == 0) { throw ParserException("Union type needs at least one member"); } @@ -195,81 +195,83 @@ LogicalType Transformer::TransformTypeName(duckdb_libpgquery::PGTypeName &type_n children.push_back(make_pair(entry_name, entry_type)); } D_ASSERT(!children.empty()); - result_type = LogicalType::UNION(std::move(children)); - } else if (base_type == LogicalTypeId::USER) { + return LogicalType::UNION(std::move(children)); + } + if (base_type == LogicalTypeId::USER) { string user_type_name {name}; vector type_mods = TransformTypeModifiers(type_name); - result_type = LogicalType::USER(user_type_name, type_mods); - } else { - SizeModifiers modifiers = GetSizeModifiers(type_name, base_type); - switch (base_type) { - case LogicalTypeId::VARCHAR: - if (modifiers.count > 1) { - throw ParserException("VARCHAR only supports a single modifier"); - } - // FIXME: create CHECK constraint based on varchar width - modifiers.width = 0; - result_type = LogicalType::VARCHAR; - break; - case LogicalTypeId::DECIMAL: - if (modifiers.count > 2) { - throw ParserException("DECIMAL only supports a maximum of two modifiers"); - } - if (modifiers.count == 1) { - // only width is provided: set scale to 0 - modifiers.scale = 0; - } - if (modifiers.width <= 0 || modifiers.width > Decimal::MAX_WIDTH_DECIMAL) { - throw ParserException("Width must be between 1 and %d!", (int)Decimal::MAX_WIDTH_DECIMAL); - } - if (modifiers.scale > modifiers.width) { - throw ParserException("Scale cannot be bigger than width"); - } - result_type = - LogicalType::DECIMAL(NumericCast(modifiers.width), NumericCast(modifiers.scale)); - break; - case LogicalTypeId::INTERVAL: - if (modifiers.count > 1) { - throw ParserException("INTERVAL only supports a single modifier"); - } - modifiers.width = 0; - result_type = LogicalType::INTERVAL; - break; - case LogicalTypeId::BIT: - if (!modifiers.width && type_name.typmods) { - throw ParserException("Type %s does not support any modifiers!", LogicalType(base_type).ToString()); - } - result_type = LogicalType(base_type); - break; - case LogicalTypeId::TIMESTAMP: - if (modifiers.count == 0) { - result_type = LogicalType::TIMESTAMP; - } else { - if (modifiers.count > 1) { - throw ParserException("TIMESTAMP only supports a single modifier"); - } - if (modifiers.width > 10) { - throw ParserException("TIMESTAMP only supports until nano-second precision (9)"); - } - if (modifiers.width == 0) { - result_type = LogicalType::TIMESTAMP_S; - } else if (modifiers.width <= 3) { - result_type = LogicalType::TIMESTAMP_MS; - } else if (modifiers.width <= 6) { - result_type = LogicalType::TIMESTAMP; - } else { - result_type = LogicalType::TIMESTAMP_NS; - } - } - break; - default: - if (modifiers.count > 0) { - throw ParserException("Type %s does not support any modifiers!", LogicalType(base_type).ToString()); - } - result_type = LogicalType(base_type); - break; + return LogicalType::USER(user_type_name, type_mods); + } + + SizeModifiers modifiers = GetSizeModifiers(type_name, base_type); + switch (base_type) { + case LogicalTypeId::VARCHAR: + if (modifiers.count > 1) { + throw ParserException("VARCHAR only supports a single modifier"); + } + // FIXME: create CHECK constraint based on varchar width + modifiers.width = 0; + return LogicalType::VARCHAR; + case LogicalTypeId::DECIMAL: + if (modifiers.count > 2) { + throw ParserException("DECIMAL only supports a maximum of two modifiers"); + } + if (modifiers.count == 1) { + // only width is provided: set scale to 0 + modifiers.scale = 0; + } + if (modifiers.width <= 0 || modifiers.width > Decimal::MAX_WIDTH_DECIMAL) { + throw ParserException("Width must be between 1 and %d!", (int)Decimal::MAX_WIDTH_DECIMAL); + } + if (modifiers.scale > modifiers.width) { + throw ParserException("Scale cannot be bigger than width"); + } + return LogicalType::DECIMAL(NumericCast(modifiers.width), NumericCast(modifiers.scale)); + case LogicalTypeId::INTERVAL: + if (modifiers.count > 1) { + throw ParserException("INTERVAL only supports a single modifier"); + } + modifiers.width = 0; + return LogicalType::INTERVAL; + case LogicalTypeId::BIT: + if (!modifiers.width && type_name.typmods) { + throw ParserException("Type %s does not support any modifiers!", LogicalType(base_type).ToString()); + } + return LogicalType(base_type); + case LogicalTypeId::TIMESTAMP: + if (modifiers.count == 0) { + return LogicalType::TIMESTAMP; + } + if (modifiers.count > 1) { + throw ParserException("TIMESTAMP only supports a single modifier"); } + if (modifiers.width > 10) { + throw ParserException("TIMESTAMP only supports until nano-second precision (9)"); + } + if (modifiers.width == 0) { + return LogicalType::TIMESTAMP_S; + } + if (modifiers.width <= 3) { + return LogicalType::TIMESTAMP_MS; + } + if (modifiers.width <= 6) { + return LogicalType::TIMESTAMP; + } + return LogicalType::TIMESTAMP_NS; + default: + if (modifiers.count > 0) { + throw ParserException("Type %s does not support any modifiers!", LogicalType(base_type).ToString()); + } + return LogicalType(base_type); + } +} + +LogicalType Transformer::TransformTypeName(duckdb_libpgquery::PGTypeName &type_name) { + if (type_name.type != duckdb_libpgquery::T_PGTypeName) { + throw ParserException("Expected a type"); } + auto stack_checker = StackCheck(); + auto result_type = TransformTypeNameInternal(type_name); if (type_name.arrayBounds) { // array bounds: turn the type into a list idx_t extra_stack = 0; diff --git a/src/duckdb/src/parser/transform/statement/transform_pivot_stmt.cpp b/src/duckdb/src/parser/transform/statement/transform_pivot_stmt.cpp index fee41aad..8b798a83 100644 --- a/src/duckdb/src/parser/transform/statement/transform_pivot_stmt.cpp +++ b/src/duckdb/src/parser/transform/statement/transform_pivot_stmt.cpp @@ -15,6 +15,7 @@ #include "duckdb/parser/expression/function_expression.hpp" #include "duckdb/parser/result_modifier.hpp" #include "duckdb/parser/tableref/subqueryref.hpp" +#include "duckdb/common/types/uuid.hpp" namespace duckdb { @@ -168,7 +169,6 @@ unique_ptr Transformer::TransformPivotStatement(duckdb_libpgquery::PG // generate CREATE TYPE statements for each of the columns that do not have an IN list bool is_pivot = !pivot->unpivots; auto columns = TransformPivotList(*pivot->columns, is_pivot); - auto pivot_idx = PivotEntryCount(); for (idx_t c = 0; c < columns.size(); c++) { auto &col = columns[c]; if (!col.pivot_enum.empty() || !col.entries.empty()) { @@ -177,7 +177,7 @@ unique_ptr Transformer::TransformPivotStatement(duckdb_libpgquery::PG if (col.pivot_expressions.size() != 1) { throw InternalException("PIVOT statement with multiple names in pivot entry!?"); } - auto enum_name = "__pivot_enum_" + std::to_string(pivot_idx) + "_" + std::to_string(c); + auto enum_name = "__pivot_enum_" + UUID::ToString(UUID::GenerateRandomUUID()); auto new_select = make_uniq(); ExtractCTEsRecursive(new_select->cte_map); diff --git a/src/duckdb/src/planner/binder/expression/bind_macro_expression.cpp b/src/duckdb/src/planner/binder/expression/bind_macro_expression.cpp index caa6ba77..358dd5db 100644 --- a/src/duckdb/src/planner/binder/expression/bind_macro_expression.cpp +++ b/src/duckdb/src/planner/binder/expression/bind_macro_expression.cpp @@ -1,4 +1,5 @@ #include "duckdb/catalog/catalog_entry/scalar_macro_catalog_entry.hpp" +#include "duckdb/common/enums/expression_type.hpp" #include "duckdb/common/reference_map.hpp" #include "duckdb/common/string_util.hpp" #include "duckdb/function/scalar_macro_function.hpp" @@ -26,12 +27,8 @@ void ExpressionBinder::ReplaceMacroParametersInLambda(FunctionExpression &functi if (!error_message.empty()) { // Possibly a JSON function, replace both LHS and RHS. - ParsedExpressionIterator::EnumerateChildren(*lambda_expr.lhs, [&](unique_ptr &child) { - ReplaceMacroParameters(child, lambda_params); - }); - ParsedExpressionIterator::EnumerateChildren(*lambda_expr.expr, [&](unique_ptr &child) { - ReplaceMacroParameters(child, lambda_params); - }); + ReplaceMacroParameters(lambda_expr.lhs, lambda_params); + ReplaceMacroParameters(lambda_expr.expr, lambda_params); continue; } @@ -43,9 +40,7 @@ void ExpressionBinder::ReplaceMacroParametersInLambda(FunctionExpression &functi } // Only replace in the RHS of the expression. - ParsedExpressionIterator::EnumerateChildren(*lambda_expr.expr, [&](unique_ptr &child) { - ReplaceMacroParameters(child, lambda_params); - }); + ReplaceMacroParameters(lambda_expr.expr, lambda_params); lambda_params.pop_back(); } diff --git a/src/duckdb/src/planner/binder/query_node/bind_select_node.cpp b/src/duckdb/src/planner/binder/query_node/bind_select_node.cpp index f1bad4c3..d58b3868 100644 --- a/src/duckdb/src/planner/binder/query_node/bind_select_node.cpp +++ b/src/duckdb/src/planner/binder/query_node/bind_select_node.cpp @@ -140,6 +140,7 @@ void Binder::PrepareModifiers(OrderBinder &order_binder, QueryNode &statement, B make_uniq(Value::INTEGER(UnsafeNumericCast(1 + i)))); } } + order_binder.SetQueryComponent("DISTINCT ON"); for (auto &distinct_on_target : distinct.distinct_on_targets) { auto expr = BindOrderExpression(order_binder, std::move(distinct_on_target)); if (!expr) { @@ -147,10 +148,13 @@ void Binder::PrepareModifiers(OrderBinder &order_binder, QueryNode &statement, B } bound_distinct->target_distincts.push_back(std::move(expr)); } + order_binder.SetQueryComponent(); + bound_modifier = std::move(bound_distinct); break; } case ResultModifierType::ORDER_MODIFIER: { + auto &order = mod->Cast(); auto bound_order = make_uniq(); auto &config = DBConfig::GetConfig(context); diff --git a/src/duckdb/src/planner/binder/query_node/plan_setop.cpp b/src/duckdb/src/planner/binder/query_node/plan_setop.cpp index 12e1dcb0..1afca342 100644 --- a/src/duckdb/src/planner/binder/query_node/plan_setop.cpp +++ b/src/duckdb/src/planner/binder/query_node/plan_setop.cpp @@ -52,7 +52,7 @@ unique_ptr Binder::CastLogicalOperatorToTypes(vectorchildren[0]); } } } @@ -132,7 +132,7 @@ unique_ptr Binder::CreatePlan(BoundSetOperationNode &node) { node.right_binder->has_unplanned_dependent_joins; // create actual logical ops for setops - LogicalOperatorType logical_type; + LogicalOperatorType logical_type = LogicalOperatorType::LOGICAL_INVALID; switch (node.setop_type) { case SetOperationType::UNION: case SetOperationType::UNION_BY_NAME: diff --git a/src/duckdb/src/planner/binder/statement/bind_create_table.cpp b/src/duckdb/src/planner/binder/statement/bind_create_table.cpp index 01881508..7ffbaf23 100644 --- a/src/duckdb/src/planner/binder/statement/bind_create_table.cpp +++ b/src/duckdb/src/planner/binder/statement/bind_create_table.cpp @@ -228,7 +228,10 @@ void Binder::BindGeneratedColumns(BoundCreateTableInfo &info) { auto bound_expression = expr_binder.Bind(expression); D_ASSERT(bound_expression); - D_ASSERT(!bound_expression->HasSubquery()); + if (bound_expression->HasSubquery()) { + throw BinderException("Failed to bind generated column '%s' because the expression contains a subquery", + col.Name()); + } if (col.Type().id() == LogicalTypeId::ANY) { // Do this before changing the type, so we know it's the first time the type is set col.ChangeGeneratedExpressionType(bound_expression->return_type); diff --git a/src/duckdb/src/planner/binder/statement/bind_export.cpp b/src/duckdb/src/planner/binder/statement/bind_export.cpp index a183738a..924df011 100644 --- a/src/duckdb/src/planner/binder/statement/bind_export.cpp +++ b/src/duckdb/src/planner/binder/statement/bind_export.cpp @@ -192,7 +192,7 @@ BoundStatement Binder::Bind(ExportStatement &stmt) { // now generate the COPY statements for each of the tables auto &fs = FileSystem::GetFileSystem(context); - BoundExportData exported_tables; + auto exported_tables = make_uniq(); unordered_set table_name_index; vector> export_nodes; @@ -245,7 +245,7 @@ BoundStatement Binder::Bind(ExportStatement &stmt) { exported_data.file_path = info->file_path; ExportedTableInfo table_info(table, std::move(exported_data), not_null_columns); - exported_tables.data.push_back(table_info); + exported_tables->data.push_back(table_info); id++; // generate the copy statement and bind it @@ -270,7 +270,8 @@ BoundStatement Binder::Bind(ExportStatement &stmt) { stmt.info->catalog = catalog; // create the export node - auto export_node = make_uniq(copy_function.function, std::move(stmt.info), exported_tables); + auto export_node = + make_uniq(copy_function.function, std::move(stmt.info), std::move(exported_tables)); if (child_operator) { export_node->children.push_back(std::move(child_operator)); diff --git a/src/duckdb/src/planner/expression_binder.cpp b/src/duckdb/src/planner/expression_binder.cpp index 146f1790..7d36654e 100644 --- a/src/duckdb/src/planner/expression_binder.cpp +++ b/src/duckdb/src/planner/expression_binder.cpp @@ -169,7 +169,7 @@ static bool CombineMissingColumns(ErrorData ¤t, ErrorData new_error) { // get query location QueryErrorContext context; current_entry = current_info.find("position"); - new_entry = current_info.find("position"); + new_entry = new_info.find("position"); uint64_t position; if (current_entry != current_info.end() && TryCast::Operation(current_entry->second, position)) { diff --git a/src/duckdb/src/planner/expression_binder/order_binder.cpp b/src/duckdb/src/planner/expression_binder/order_binder.cpp index 4516df44..ff864bbb 100644 --- a/src/duckdb/src/planner/expression_binder/order_binder.cpp +++ b/src/duckdb/src/planner/expression_binder/order_binder.cpp @@ -61,8 +61,10 @@ optional_idx OrderBinder::TryGetProjectionReference(ParsedExpression &expr) cons // this is disabled by default (matching Postgres) - but we can control this with a setting auto &config = ClientConfig::GetConfig(binders[0].get().context); if (!config.order_by_non_integer_literal) { - throw BinderException(expr, "ORDER BY non-integer literal has no effect.\n* SET " - "order_by_non_integer_literal=true to allow this behavior."); + throw BinderException(expr, + "%s non-integer literal has no effect.\n* SET " + "order_by_non_integer_literal=true to allow this behavior.", + query_component); } break; } @@ -94,6 +96,14 @@ optional_idx OrderBinder::TryGetProjectionReference(ParsedExpression &expr) cons return optional_idx(); } +void OrderBinder::SetQueryComponent(string component) { + if (component.empty()) { + query_component = "ORDER BY"; + } else { + query_component = std::move(component); + } +} + unique_ptr OrderBinder::BindConstant(ParsedExpression &expr) { auto index = TryGetProjectionReference(expr); if (!index.IsValid()) { @@ -130,7 +140,7 @@ unique_ptr OrderBinder::Bind(unique_ptr expr) { break; } case ExpressionClass::PARAMETER: { - throw ParameterNotAllowedException("Parameter not supported in ORDER BY clause"); + throw ParameterNotAllowedException("Parameter not supported in %s clause", query_component); } case ExpressionClass::COLLATE: { auto &collation = expr->Cast(); diff --git a/src/duckdb/src/planner/operator/logical_export.cpp b/src/duckdb/src/planner/operator/logical_export.cpp new file mode 100644 index 00000000..046aff3e --- /dev/null +++ b/src/duckdb/src/planner/operator/logical_export.cpp @@ -0,0 +1,28 @@ +#include "duckdb/planner/operator/logical_export.hpp" +#include "duckdb/common/serializer/serializer.hpp" +#include "duckdb/catalog/catalog.hpp" +#include "duckdb/catalog/catalog_entry/copy_function_catalog_entry.hpp" + +namespace duckdb { + +LogicalExport::LogicalExport(CopyFunction function, unique_ptr copy_info, + unique_ptr exported_tables) + : LogicalOperator(LogicalOperatorType::LOGICAL_EXPORT), copy_info(std::move(copy_info)), + function(std::move(function)), exported_tables(std::move(exported_tables)) { +} + +LogicalExport::LogicalExport(ClientContext &context, unique_ptr copy_info_p, + unique_ptr exported_tables_p) + : LogicalOperator(LogicalOperatorType::LOGICAL_EXPORT), + copy_info(unique_ptr_cast(std::move(copy_info_p))), + function(GetCopyFunction(context, *copy_info)), + exported_tables(unique_ptr_cast(std::move(exported_tables_p))) { +} + +CopyFunction LogicalExport::GetCopyFunction(ClientContext &context, CopyInfo &info) { + auto ©_entry = + Catalog::GetEntry(context, INVALID_CATALOG, DEFAULT_SCHEMA, info.format); + return copy_entry.function; +} + +} // namespace duckdb diff --git a/src/duckdb/src/planner/table_binding.cpp b/src/duckdb/src/planner/table_binding.cpp index dff3de59..7b9e65bc 100644 --- a/src/duckdb/src/planner/table_binding.cpp +++ b/src/duckdb/src/planner/table_binding.cpp @@ -202,8 +202,7 @@ BindResult TableBinding::Bind(ColumnRefExpression &colref, idx_t depth) { // fetch the type of the column LogicalType col_type; if (column_index == COLUMN_IDENTIFIER_ROW_ID) { - // row id: BIGINT type - col_type = LogicalType::BIGINT; + col_type = LogicalType::ROW_TYPE; } else { // normal column: fetch type from base column col_type = types[column_index]; diff --git a/src/duckdb/src/planner/table_filter.cpp b/src/duckdb/src/planner/table_filter.cpp index 00559f39..636a7671 100644 --- a/src/duckdb/src/planner/table_filter.cpp +++ b/src/duckdb/src/planner/table_filter.cpp @@ -26,6 +26,10 @@ void TableFilterSet::PushFilter(idx_t column_index, unique_ptr filt } } +string TableFilter::DebugToString() { + return ToString("c0"); +} + void DynamicTableFilterSet::ClearFilters(const PhysicalOperator &op) { lock_guard l(lock); filters.erase(op); @@ -57,7 +61,7 @@ DynamicTableFilterSet::GetFinalTableFilters(const PhysicalTableScan &scan, auto result = make_uniq(); if (existing_filters) { for (auto &entry : existing_filters->filters) { - result->filters[entry.first] = entry.second->Copy(); + result->PushFilter(entry.first, entry.second->Copy()); } } for (auto &entry : filters) { @@ -66,7 +70,7 @@ DynamicTableFilterSet::GetFinalTableFilters(const PhysicalTableScan &scan, // skip row id filters continue; } - result->filters[filter.first] = filter.second->Copy(); + result->PushFilter(filter.first, filter.second->Copy()); } } if (result->filters.empty()) { diff --git a/src/duckdb/src/storage/buffer/buffer_pool.cpp b/src/duckdb/src/storage/buffer/buffer_pool.cpp index 9ed31f6f..30d6b648 100644 --- a/src/duckdb/src/storage/buffer/buffer_pool.cpp +++ b/src/duckdb/src/storage/buffer/buffer_pool.cpp @@ -342,7 +342,8 @@ idx_t BufferPool::PurgeAgedBlocksInternal(EvictionQueue &queue, uint32_t max_age bool is_fresh = handle->lru_timestamp_msec >= limit && handle->lru_timestamp_msec <= now; purged_bytes += handle->GetMemoryUsage(); handle->Unload(); - return is_fresh; + // Return false to stop iterating if the current block is_fresh + return !is_fresh; }); return purged_bytes; } diff --git a/src/duckdb/src/storage/checkpoint_manager.cpp b/src/duckdb/src/storage/checkpoint_manager.cpp index 9be59051..cd46862e 100644 --- a/src/duckdb/src/storage/checkpoint_manager.cpp +++ b/src/duckdb/src/storage/checkpoint_manager.cpp @@ -445,7 +445,7 @@ void CheckpointReader::ReadIndex(CatalogTransaction transaction, Deserializer &d auto &table = schema.GetEntry(transaction, CatalogType::TABLE_ENTRY, info.table)->Cast(); // we also need to make sure the index type is loaded - // backwards compatability: + // backwards compatibility: // if the index type is not specified, we default to ART if (info.index_type.empty()) { info.index_type = ART::TYPE_NAME; diff --git a/src/duckdb/src/storage/compression/bitpacking.cpp b/src/duckdb/src/storage/compression/bitpacking.cpp index aa1fd079..7561a260 100644 --- a/src/duckdb/src/storage/compression/bitpacking.cpp +++ b/src/duckdb/src/storage/compression/bitpacking.cpp @@ -264,10 +264,14 @@ struct BitpackingState { delta_required_bitwidth, static_cast(minimum_delta), delta_offset, compression_buffer, compression_buffer_idx, data_ptr); + // FOR (frame of reference). + total_size += sizeof(T); + // Aligned bitpacking width. + total_size += AlignValue(sizeof(bitpacking_width_t)); + // Delta offset. + total_size += sizeof(T); + // Compressed data size. total_size += BitpackingPrimitives::GetRequiredSize(compression_buffer_idx, delta_required_bitwidth); - total_size += sizeof(T); // FOR value - total_size += sizeof(T); // Delta offset value - total_size += AlignValue(sizeof(bitpacking_width_t)); // FOR value return true; } diff --git a/src/duckdb/src/storage/compression/dictionary_compression.cpp b/src/duckdb/src/storage/compression/dictionary_compression.cpp index 5fd859f7..64318a29 100644 --- a/src/duckdb/src/storage/compression/dictionary_compression.cpp +++ b/src/duckdb/src/storage/compression/dictionary_compression.cpp @@ -127,7 +127,7 @@ struct DictionaryCompressionStorage { // contains the offsets into the dictionary which are also used to determine the string lengths. Each value in the // dictionary gets a single unique index in the index buffer. Secondly, the selection buffer maps the tuples to an index // in the index buffer. The selection buffer is compressed with bitpacking. Finally, the dictionary contains simply all -// the unique strings without lenghts or null termination as we can deduce the lengths from the index buffer. The +// the unique strings without lengths or null termination as we can deduce the lengths from the index buffer. The // addition of the selection buffer is done for two reasons: firstly, to allow the scan to emit dictionary vectors by // scanning the whole dictionary at once and then scanning the selection buffer for each emitted vector. Secondly, it // allows for efficient bitpacking compression as the selection values should remain relatively small. diff --git a/src/duckdb/src/storage/metadata/metadata_manager.cpp b/src/duckdb/src/storage/metadata/metadata_manager.cpp index f29b61df..79e5bbd9 100644 --- a/src/duckdb/src/storage/metadata/metadata_manager.cpp +++ b/src/duckdb/src/storage/metadata/metadata_manager.cpp @@ -50,7 +50,7 @@ MetadataHandle MetadataManager::AllocateHandle() { return Pin(pointer); } -MetadataHandle MetadataManager::Pin(MetadataPointer pointer) { +MetadataHandle MetadataManager::Pin(const MetadataPointer &pointer) { D_ASSERT(pointer.index < METADATA_BLOCK_COUNT); auto &block = blocks[UnsafeNumericCast(pointer.block_index)]; @@ -111,7 +111,7 @@ void MetadataManager::AddAndRegisterBlock(MetadataBlock block) { AddBlock(std::move(block), true); } -MetaBlockPointer MetadataManager::GetDiskPointer(MetadataPointer pointer, uint32_t offset) { +MetaBlockPointer MetadataManager::GetDiskPointer(const MetadataPointer &pointer, uint32_t offset) { idx_t block_pointer = idx_t(pointer.block_index); block_pointer |= idx_t(pointer.index) << 56ULL; return MetaBlockPointer(block_pointer, offset); diff --git a/src/duckdb/src/storage/serialization/serialize_logical_operator.cpp b/src/duckdb/src/storage/serialization/serialize_logical_operator.cpp index 5bec4819..d8a4d83b 100644 --- a/src/duckdb/src/storage/serialization/serialize_logical_operator.cpp +++ b/src/duckdb/src/storage/serialization/serialize_logical_operator.cpp @@ -106,6 +106,9 @@ unique_ptr LogicalOperator::Deserialize(Deserializer &deseriali case LogicalOperatorType::LOGICAL_EXPLAIN: result = LogicalExplain::Deserialize(deserializer); break; + case LogicalOperatorType::LOGICAL_EXPORT: + result = LogicalExport::Deserialize(deserializer); + break; case LogicalOperatorType::LOGICAL_EXPRESSION_GET: result = LogicalExpressionGet::Deserialize(deserializer); break; @@ -442,6 +445,19 @@ unique_ptr LogicalExplain::Deserialize(Deserializer &deserializ return std::move(result); } +void LogicalExport::Serialize(Serializer &serializer) const { + LogicalOperator::Serialize(serializer); + serializer.WritePropertyWithDefault>(200, "copy_info", copy_info); + serializer.WritePropertyWithDefault>(201, "exported_tables", exported_tables); +} + +unique_ptr LogicalExport::Deserialize(Deserializer &deserializer) { + auto copy_info = deserializer.ReadPropertyWithDefault>(200, "copy_info"); + auto exported_tables = deserializer.ReadPropertyWithDefault>(201, "exported_tables"); + auto result = duckdb::unique_ptr(new LogicalExport(deserializer.Get(), std::move(copy_info), std::move(exported_tables))); + return std::move(result); +} + void LogicalExpressionGet::Serialize(Serializer &serializer) const { LogicalOperator::Serialize(serializer); serializer.WritePropertyWithDefault(200, "table_index", table_index); diff --git a/src/duckdb/src/storage/serialization/serialize_nodes.cpp b/src/duckdb/src/storage/serialization/serialize_nodes.cpp index 872e3a5b..7e6f7174 100644 --- a/src/duckdb/src/storage/serialization/serialize_nodes.cpp +++ b/src/duckdb/src/storage/serialization/serialize_nodes.cpp @@ -32,6 +32,7 @@ #include "duckdb/function/scalar/strftime_format.hpp" #include "duckdb/function/table/read_csv.hpp" #include "duckdb/common/types/interval.hpp" +#include "duckdb/parser/parsed_data/exported_table_data.hpp" namespace duckdb { @@ -343,6 +344,34 @@ CommonTableExpressionMap CommonTableExpressionMap::Deserialize(Deserializer &des return result; } +void ExportedTableData::Serialize(Serializer &serializer) const { + serializer.WritePropertyWithDefault(1, "table_name", table_name); + serializer.WritePropertyWithDefault(2, "schema_name", schema_name); + serializer.WritePropertyWithDefault(3, "database_name", database_name); + serializer.WritePropertyWithDefault(4, "file_path", file_path); + serializer.WritePropertyWithDefault>(5, "not_null_columns", not_null_columns); +} + +ExportedTableData ExportedTableData::Deserialize(Deserializer &deserializer) { + ExportedTableData result; + deserializer.ReadPropertyWithDefault(1, "table_name", result.table_name); + deserializer.ReadPropertyWithDefault(2, "schema_name", result.schema_name); + deserializer.ReadPropertyWithDefault(3, "database_name", result.database_name); + deserializer.ReadPropertyWithDefault(4, "file_path", result.file_path); + deserializer.ReadPropertyWithDefault>(5, "not_null_columns", result.not_null_columns); + return result; +} + +void ExportedTableInfo::Serialize(Serializer &serializer) const { + serializer.WriteProperty(1, "table_data", table_data); +} + +ExportedTableInfo ExportedTableInfo::Deserialize(Deserializer &deserializer) { + auto table_data = deserializer.ReadProperty(1, "table_data"); + ExportedTableInfo result(deserializer.Get(), table_data); + return result; +} + void HivePartitioningIndex::Serialize(Serializer &serializer) const { serializer.WritePropertyWithDefault(100, "value", value); serializer.WritePropertyWithDefault(101, "index", index); diff --git a/src/duckdb/src/storage/serialization/serialize_parse_info.cpp b/src/duckdb/src/storage/serialization/serialize_parse_info.cpp index 590c0954..e68acf36 100644 --- a/src/duckdb/src/storage/serialization/serialize_parse_info.cpp +++ b/src/duckdb/src/storage/serialization/serialize_parse_info.cpp @@ -19,6 +19,7 @@ #include "duckdb/parser/parsed_data/pragma_info.hpp" #include "duckdb/parser/parsed_data/transaction_info.hpp" #include "duckdb/parser/parsed_data/vacuum_info.hpp" +#include "duckdb/parser/parsed_data/exported_table_data.hpp" namespace duckdb { @@ -36,6 +37,9 @@ unique_ptr ParseInfo::Deserialize(Deserializer &deserializer) { case ParseInfoType::ATTACH_INFO: result = AttachInfo::Deserialize(deserializer); break; + case ParseInfoType::BOUND_EXPORT_DATA: + result = BoundExportData::Deserialize(deserializer); + break; case ParseInfoType::COPY_DATABASE_INFO: result = CopyDatabaseInfo::Deserialize(deserializer); break; @@ -225,6 +229,17 @@ unique_ptr AttachInfo::Deserialize(Deserializer &deserializer) { return std::move(result); } +void BoundExportData::Serialize(Serializer &serializer) const { + ParseInfo::Serialize(serializer); + serializer.WritePropertyWithDefault>(200, "data", data); +} + +unique_ptr BoundExportData::Deserialize(Deserializer &deserializer) { + auto result = duckdb::unique_ptr(new BoundExportData()); + deserializer.ReadPropertyWithDefault>(200, "data", result->data); + return std::move(result); +} + void ChangeColumnTypeInfo::Serialize(Serializer &serializer) const { AlterTableInfo::Serialize(serializer); serializer.WritePropertyWithDefault(400, "column_name", column_name); diff --git a/src/duckdb/src/storage/single_file_block_manager.cpp b/src/duckdb/src/storage/single_file_block_manager.cpp index 6939c72e..20f97ea9 100644 --- a/src/duckdb/src/storage/single_file_block_manager.cpp +++ b/src/duckdb/src/storage/single_file_block_manager.cpp @@ -376,8 +376,9 @@ void SingleFileBlockManager::MarkBlockAsUsed(block_id_t block_id) { } max_block++; } else if (free_list.find(block_id) != free_list.end()) { - // block is currently int he free list - erase + // block is currently in the free list - erase free_list.erase(block_id); + newly_freed_list.erase(block_id); } else { // block is already in use - increase reference count IncreaseBlockReferenceCountInternal(block_id); diff --git a/src/duckdb/src/storage/statistics/distinct_statistics.cpp b/src/duckdb/src/storage/statistics/distinct_statistics.cpp index 50098a32..6e5088cb 100644 --- a/src/duckdb/src/storage/statistics/distinct_statistics.cpp +++ b/src/duckdb/src/storage/statistics/distinct_statistics.cpp @@ -7,14 +7,11 @@ namespace duckdb { -DistinctStatistics::DistinctStatistics() - : log(make_uniq()), sample_count(0), total_count(0), - hash_vec(LogicalType::HASH, STANDARD_VECTOR_SIZE) { +DistinctStatistics::DistinctStatistics() : log(make_uniq()), sample_count(0), total_count(0) { } DistinctStatistics::DistinctStatistics(unique_ptr log, idx_t sample_count, idx_t total_count) - : log(std::move(log)), sample_count(sample_count), total_count(total_count), - hash_vec(LogicalType::HASH, STANDARD_VECTOR_SIZE) { + : log(std::move(log)), sample_count(sample_count), total_count(total_count) { } unique_ptr DistinctStatistics::Copy() const { @@ -41,6 +38,7 @@ void DistinctStatistics::Update(Vector &v, idx_t count, bool sample) { sample_count += count; lock_guard guard(lock); + Vector hash_vec(LogicalType::HASH, count); VectorOperations::Hash(v, hash_vec, count); UnifiedVectorFormat vdata; diff --git a/src/duckdb/src/storage/storage_info.cpp b/src/duckdb/src/storage/storage_info.cpp index e2b606b1..61939c46 100644 --- a/src/duckdb/src/storage/storage_info.cpp +++ b/src/duckdb/src/storage/storage_info.cpp @@ -28,13 +28,13 @@ static const StorageVersionInfo storage_version_info[] = { {"v0.3.0", 25}, {"v0.3.1", 27}, {"v0.3.2", 31}, {"v0.3.3", 33}, {"v0.3.4", 33}, {"v0.3.5", 33}, {"v0.4.0", 33}, {"v0.5.0", 38}, {"v0.5.1", 38}, {"v0.6.0", 39}, {"v0.6.1", 39}, {"v0.7.0", 43}, {"v0.7.1", 43}, {"v0.8.0", 51}, {"v0.8.1", 51}, {"v0.9.0", 64}, {"v0.9.1", 64}, {"v0.9.2", 64}, {"v0.10.0", 64}, {"v0.10.1", 64}, {"v0.10.2", 64}, - {"v0.10.3", 64}, {"v1.0.0", 64}, {"v1.1.0", 64}, {nullptr, 0}}; + {"v0.10.3", 64}, {"v1.0.0", 64}, {"v1.1.0", 64}, {"v1.1.1", 64}, {"v1.1.2", 64}, {"v1.1.3", 64}, {nullptr, 0}}; // END OF STORAGE VERSION INFO // START OF SERIALIZATION VERSION INFO -static const SerializationVersionInfo serialization_version_info[] = {{"v0.10.0", 1}, {"v0.10.1", 1}, {"v0.10.2", 1}, - {"v0.10.3", 2}, {"v1.0.0", 2}, {"v1.1.0", 3}, - {"latest", 3}, {nullptr, 0}}; +static const SerializationVersionInfo serialization_version_info[] = { + {"v0.10.0", 1}, {"v0.10.1", 1}, {"v0.10.2", 1}, {"v0.10.3", 2}, {"v1.0.0", 2}, {"v1.1.0", 3}, + {"v1.1.1", 3}, {"v1.1.2", 3}, {"v1.1.3", 3}, {"latest", 3}, {nullptr, 0}}; // END OF SERIALIZATION VERSION INFO optional_idx GetStorageVersion(const char *version_string) { diff --git a/src/duckdb/src/storage/table/row_group_collection.cpp b/src/duckdb/src/storage/table/row_group_collection.cpp index b0eb5022..4dfb1949 100644 --- a/src/duckdb/src/storage/table/row_group_collection.cpp +++ b/src/duckdb/src/storage/table/row_group_collection.cpp @@ -962,8 +962,8 @@ unique_ptr RowGroupCollection::GetCheckpointTask(CollectionCheck } void RowGroupCollection::Checkpoint(TableDataWriter &writer, TableStatistics &global_stats) { - auto segments = row_groups->MoveSegments(); auto l = row_groups->Lock(); + auto segments = row_groups->MoveSegments(l); CollectionCheckpointState checkpoint_state(*this, writer, segments, global_stats); diff --git a/src/duckdb/src/storage/table/row_version_manager.cpp b/src/duckdb/src/storage/table/row_version_manager.cpp index eebbc083..4a166f05 100644 --- a/src/duckdb/src/storage/table/row_version_manager.cpp +++ b/src/duckdb/src/storage/table/row_version_manager.cpp @@ -139,11 +139,15 @@ void RowVersionManager::CleanupAppend(transaction_t lowest_active_transaction, i for (idx_t vector_idx = start_vector_idx; vector_idx <= end_vector_idx; vector_idx++) { idx_t vcount = vector_idx == end_vector_idx ? row_group_end - end_vector_idx * STANDARD_VECTOR_SIZE : STANDARD_VECTOR_SIZE; - auto &info = *vector_info[vector_idx]; if (vcount != STANDARD_VECTOR_SIZE) { // not written fully - skip continue; } + if (!vector_info[vector_idx]) { + // already vacuumed - skip + continue; + } + auto &info = *vector_info[vector_idx]; // if we wrote the entire chunk info try to compress it unique_ptr new_info; auto cleanup = info.Cleanup(lowest_active_transaction, new_info); diff --git a/src/duckdb/src/storage/temporary_file_manager.cpp b/src/duckdb/src/storage/temporary_file_manager.cpp index 29cf1cf4..845f295e 100644 --- a/src/duckdb/src/storage/temporary_file_manager.cpp +++ b/src/duckdb/src/storage/temporary_file_manager.cpp @@ -72,7 +72,7 @@ void BlockIndexManager::SetMaxIndex(idx_t new_index) { auto difference = new_index - old; auto size_on_disk = difference * TEMP_FILE_BLOCK_SIZE; manager->IncreaseSizeOnDisk(size_on_disk); - // Increase can throw, so this is only updated after it was succesfully updated + // Increase can throw, so this is only updated after it was successfully updated max_index = new_index; } } diff --git a/src/duckdb/src/transaction/duck_transaction.cpp b/src/duckdb/src/transaction/duck_transaction.cpp index 21e7b58d..d47aee65 100644 --- a/src/duckdb/src/transaction/duck_transaction.cpp +++ b/src/duckdb/src/transaction/duck_transaction.cpp @@ -271,23 +271,24 @@ unique_ptr DuckTransaction::TryGetCheckpointLock() { } shared_ptr DuckTransaction::SharedLockTable(DataTableInfo &info) { - lock_guard l(active_locks_lock); + unique_lock transaction_lock(active_locks_lock); auto entry = active_locks.find(info); - if (entry != active_locks.end()) { - // found an existing lock - auto lock_weak_ptr = entry->second; - // check if it is expired - auto lock = lock_weak_ptr.lock(); - if (lock) { - // not expired - return it - return lock; - } + if (entry == active_locks.end()) { + entry = active_locks.insert(entry, make_pair(std::ref(info), make_uniq())); + } + auto &active_table_lock = *entry->second; + transaction_lock.unlock(); // release transaction-level lock before acquiring table-level lock + lock_guard table_lock(active_table_lock.checkpoint_lock_mutex); + auto checkpoint_lock = active_table_lock.checkpoint_lock.lock(); + // check if it is expired (or has never been acquired yet) + if (checkpoint_lock) { + // not expired - return it + return checkpoint_lock; } // no existing lock - obtain it - auto table_lock = info.GetSharedLock(); - auto checkpoint_lock = make_shared_ptr(std::move(table_lock)); - // insert it into the active locks and return it - active_locks.insert(make_pair(std::ref(info), checkpoint_lock)); + checkpoint_lock = make_shared_ptr(info.GetSharedLock()); + // store it for future reference + active_table_lock.checkpoint_lock = checkpoint_lock; return checkpoint_lock; } diff --git a/src/duckdb/third_party/brotli/common/brotli_platform.h b/src/duckdb/third_party/brotli/common/brotli_platform.h index e5fa77b4..b24bef2d 100644 --- a/src/duckdb/third_party/brotli/common/brotli_platform.h +++ b/src/duckdb/third_party/brotli/common/brotli_platform.h @@ -540,4 +540,4 @@ T __brotli_swap_tmp = (A)[(I)]; \ #endif } } -#endif /* BROTLI_COMMON_PLATFORM_H_ */ \ No newline at end of file +#endif /* BROTLI_COMMON_PLATFORM_H_ */ diff --git a/src/duckdb/third_party/brotli/dec/decode.cpp b/src/duckdb/third_party/brotli/dec/decode.cpp index 1ad9ac1a..2ee17d69 100644 --- a/src/duckdb/third_party/brotli/dec/decode.cpp +++ b/src/duckdb/third_party/brotli/dec/decode.cpp @@ -2755,4 +2755,4 @@ void InverseMoveToFrontTransformForTest(uint8_t *v, brotli_reg_t l, BrotliDecode } #endif -} \ No newline at end of file +} diff --git a/src/duckdb/third_party/brotli/enc/memory.cpp b/src/duckdb/third_party/brotli/enc/memory.cpp index a4c8b8db..8a5c6712 100644 --- a/src/duckdb/third_party/brotli/enc/memory.cpp +++ b/src/duckdb/third_party/brotli/enc/memory.cpp @@ -64,7 +64,7 @@ void duckdb_brotli::BrotliWipeOutMemoryManager(MemoryManager* m) { #else /* BROTLI_ENCODER_EXIT_ON_OOM */ -static void SortPointers(void** items, const size_t n) { +void SortPointers(void** items, const size_t n) { /* Shell sort. */ /* TODO(eustas): fine-tune for "many slots" case */ static const size_t gaps[] = {23, 10, 4, 1}; @@ -135,7 +135,7 @@ static void CollectGarbagePointers(MemoryManager* m) { } } -void* BrotliAllocate(MemoryManager* m, size_t n) { +void* duckdb_brotli::BrotliAllocate(MemoryManager* m, size_t n) { void* result = m->alloc_func(m->opaque, n); if (!result) { m->is_oom = BROTLI_TRUE; @@ -146,14 +146,14 @@ void* BrotliAllocate(MemoryManager* m, size_t n) { return result; } -void BrotliFree(MemoryManager* m, void* p) { +void duckdb_brotli::BrotliFree(MemoryManager* m, void* p) { if (!p) return; m->free_func(m->opaque, p); if (m->new_freed == MAX_NEW_FREED) CollectGarbagePointers(m); m->pointers[NEW_FREED_OFFSET + (m->new_freed++)] = p; } -void BrotliWipeOutMemoryManager(MemoryManager* m) { +void duckdb_brotli::BrotliWipeOutMemoryManager(MemoryManager* m) { size_t i; CollectGarbagePointers(m); /* Now all unfreed pointers are in perm-allocated list. */ diff --git a/src/duckdb/third_party/fsst/libfsst.cpp b/src/duckdb/third_party/fsst/libfsst.cpp index 684471de..802aff55 100644 --- a/src/duckdb/third_party/fsst/libfsst.cpp +++ b/src/duckdb/third_party/fsst/libfsst.cpp @@ -503,4 +503,4 @@ extern "C" duckdb_fsst_decoder_t duckdb_fsst_decoder(duckdb_fsst_encoder_t *enco u32 cnt2 = duckdb_fsst_import(&decoder, buf); assert(cnt1 == cnt2); (void) cnt1; (void) cnt2; return decoder; -} \ No newline at end of file +} diff --git a/src/duckdb/third_party/hyperloglog/sds.cpp b/src/duckdb/third_party/hyperloglog/sds.cpp index fa402a69..4bb827ea 100644 --- a/src/duckdb/third_party/hyperloglog/sds.cpp +++ b/src/duckdb/third_party/hyperloglog/sds.cpp @@ -1112,4 +1112,4 @@ void *sdmalloc(size_t size) { return malloc(size); } void *sdrealloc(void *ptr, size_t size) { return realloc(ptr,size); } void sdfree(void *ptr) { free(ptr); } -} \ No newline at end of file +} diff --git a/src/duckdb/third_party/hyperloglog/sds.hpp b/src/duckdb/third_party/hyperloglog/sds.hpp index 274e4b1c..69d6be7a 100644 --- a/src/duckdb/third_party/hyperloglog/sds.hpp +++ b/src/duckdb/third_party/hyperloglog/sds.hpp @@ -281,4 +281,4 @@ int sdsTest(int argc, char *argv[]); } -#endif \ No newline at end of file +#endif diff --git a/src/duckdb/third_party/libpg_query/include/common/keywords.hpp b/src/duckdb/third_party/libpg_query/include/common/keywords.hpp index ba5f6095..bfd13c5b 100644 --- a/src/duckdb/third_party/libpg_query/include/common/keywords.hpp +++ b/src/duckdb/third_party/libpg_query/include/common/keywords.hpp @@ -31,4 +31,4 @@ typedef struct PGScanKeyword { } PGScanKeyword; const PGScanKeyword *ScanKeywordLookup(const char *text, const PGScanKeyword *keywords, int num_keywords); -} \ No newline at end of file +} diff --git a/src/duckdb/third_party/libpg_query/include/datatype/timestamp.hpp b/src/duckdb/third_party/libpg_query/include/datatype/timestamp.hpp index caba3137..f05071b0 100644 --- a/src/duckdb/third_party/libpg_query/include/datatype/timestamp.hpp +++ b/src/duckdb/third_party/libpg_query/include/datatype/timestamp.hpp @@ -48,4 +48,4 @@ typedef struct { int32_t day; /* days, after time for alignment */ int32_t month; /* months and years, after time for alignment */ } PGInterval; -} \ No newline at end of file +} diff --git a/src/duckdb/third_party/libpg_query/include/mb/pg_wchar.hpp b/src/duckdb/third_party/libpg_query/include/mb/pg_wchar.hpp index fc17c61b..8110dd7f 100644 --- a/src/duckdb/third_party/libpg_query/include/mb/pg_wchar.hpp +++ b/src/duckdb/third_party/libpg_query/include/mb/pg_wchar.hpp @@ -25,4 +25,4 @@ */ namespace duckdb_libpgquery { typedef unsigned int pg_wchar; -} \ No newline at end of file +} diff --git a/src/duckdb/third_party/libpg_query/include/nodes/bitmapset.hpp b/src/duckdb/third_party/libpg_query/include/nodes/bitmapset.hpp index 3f5859d4..109171bc 100644 --- a/src/duckdb/third_party/libpg_query/include/nodes/bitmapset.hpp +++ b/src/duckdb/third_party/libpg_query/include/nodes/bitmapset.hpp @@ -99,4 +99,4 @@ int bms_next_member(const PGBitmapset *a, int prevbit); /* support for hashtables using Bitmapsets as keys: */ uint32_t bms_hash_value(const PGBitmapset *a); -} \ No newline at end of file +} diff --git a/src/duckdb/third_party/libpg_query/include/nodes/lockoptions.hpp b/src/duckdb/third_party/libpg_query/include/nodes/lockoptions.hpp index 4c878839..2058e94d 100644 --- a/src/duckdb/third_party/libpg_query/include/nodes/lockoptions.hpp +++ b/src/duckdb/third_party/libpg_query/include/nodes/lockoptions.hpp @@ -41,4 +41,4 @@ typedef enum PGLockWaitPolicy { LockWaitError } PGLockWaitPolicy; -} \ No newline at end of file +} diff --git a/src/duckdb/third_party/libpg_query/include/nodes/makefuncs.hpp b/src/duckdb/third_party/libpg_query/include/nodes/makefuncs.hpp index 09b99283..b2aeeebf 100644 --- a/src/duckdb/third_party/libpg_query/include/nodes/makefuncs.hpp +++ b/src/duckdb/third_party/libpg_query/include/nodes/makefuncs.hpp @@ -66,4 +66,4 @@ PGDefElem *makeDefElemExtended(const char *nameSpace, const char *name, PGNode * PGGroupingSet *makeGroupingSet(GroupingSetKind kind, PGList *content, int location); -} \ No newline at end of file +} diff --git a/src/duckdb/third_party/libpg_query/include/nodes/pg_list.hpp b/src/duckdb/third_party/libpg_query/include/nodes/pg_list.hpp index 80ec889f..4d06c853 100644 --- a/src/duckdb/third_party/libpg_query/include/nodes/pg_list.hpp +++ b/src/duckdb/third_party/libpg_query/include/nodes/pg_list.hpp @@ -336,4 +336,4 @@ PGList *list_copy_tail(const PGList *list, int nskip); int length(PGList *list); #endif /* ENABLE_LIST_COMPAT */ -} \ No newline at end of file +} diff --git a/src/duckdb/third_party/libpg_query/include/nodes/value.hpp b/src/duckdb/third_party/libpg_query/include/nodes/value.hpp index 18f74aea..45feca2e 100644 --- a/src/duckdb/third_party/libpg_query/include/nodes/value.hpp +++ b/src/duckdb/third_party/libpg_query/include/nodes/value.hpp @@ -57,4 +57,4 @@ PGValue *makeFloat(char *numericStr); PGValue *makeString(const char *str); PGValue *makeBitString(char *str); -} \ No newline at end of file +} diff --git a/src/duckdb/third_party/libpg_query/include/parser/gramparse.hpp b/src/duckdb/third_party/libpg_query/include/parser/gramparse.hpp index d50f7df7..e374dcf8 100644 --- a/src/duckdb/third_party/libpg_query/include/parser/gramparse.hpp +++ b/src/duckdb/third_party/libpg_query/include/parser/gramparse.hpp @@ -65,4 +65,4 @@ int base_yylex(YYSTYPE *lvalp, YYLTYPE *llocp, core_yyscan_t yyscanner); void parser_init(base_yy_extra_type *yyext); int base_yyparse(core_yyscan_t yyscanner); -} \ No newline at end of file +} diff --git a/src/duckdb/third_party/libpg_query/include/parser/parser.hpp b/src/duckdb/third_party/libpg_query/include/parser/parser.hpp index 4aa29a89..3c3bf24c 100644 --- a/src/duckdb/third_party/libpg_query/include/parser/parser.hpp +++ b/src/duckdb/third_party/libpg_query/include/parser/parser.hpp @@ -37,4 +37,4 @@ std::vector tokenize(const char *str); PGList *SystemFuncName(const char *name); PGTypeName *SystemTypeName(const char *name); -} \ No newline at end of file +} diff --git a/src/duckdb/third_party/libpg_query/include/parser/scanner.hpp b/src/duckdb/third_party/libpg_query/include/parser/scanner.hpp index 3c4224d0..2813b1b6 100644 --- a/src/duckdb/third_party/libpg_query/include/parser/scanner.hpp +++ b/src/duckdb/third_party/libpg_query/include/parser/scanner.hpp @@ -124,4 +124,4 @@ int core_yylex(core_YYSTYPE *lvalp, YYLTYPE *llocp, core_yyscan_t yyscanner); int scanner_errposition(int location, core_yyscan_t yyscanner); void scanner_yyerror(const char *message, core_yyscan_t yyscanner); -} \ No newline at end of file +} diff --git a/src/duckdb/third_party/libpg_query/include/parser/scansup.hpp b/src/duckdb/third_party/libpg_query/include/parser/scansup.hpp index 4c87ad44..d449e863 100644 --- a/src/duckdb/third_party/libpg_query/include/parser/scansup.hpp +++ b/src/duckdb/third_party/libpg_query/include/parser/scansup.hpp @@ -27,4 +27,4 @@ bool scanner_isspace(char ch); void set_preserve_identifier_case(bool downcase); bool get_preserve_identifier_case(); -} \ No newline at end of file +} diff --git a/src/duckdb/third_party/libpg_query/include/pg_functions.hpp b/src/duckdb/third_party/libpg_query/include/pg_functions.hpp index 5c4a2c68..bb591f75 100644 --- a/src/duckdb/third_party/libpg_query/include/pg_functions.hpp +++ b/src/duckdb/third_party/libpg_query/include/pg_functions.hpp @@ -60,4 +60,4 @@ PGDefElem *defWithOids(bool value); typedef unsigned int pg_wchar; unsigned char *unicode_to_utf8(pg_wchar c, unsigned char *utf8string); -} \ No newline at end of file +} diff --git a/src/duckdb/third_party/libpg_query/pg_functions.cpp b/src/duckdb/third_party/libpg_query/pg_functions.cpp index d3af77cf..8719b11a 100644 --- a/src/duckdb/third_party/libpg_query/pg_functions.cpp +++ b/src/duckdb/third_party/libpg_query/pg_functions.cpp @@ -274,4 +274,4 @@ PGNode *newNode(size_t size, PGNodeTag type) { result->type = type; return result; } -} \ No newline at end of file +} diff --git a/src/duckdb/third_party/libpg_query/src_backend_nodes_list.cpp b/src/duckdb/third_party/libpg_query/src_backend_nodes_list.cpp index 424075d1..0de79132 100644 --- a/src/duckdb/third_party/libpg_query/src_backend_nodes_list.cpp +++ b/src/duckdb/third_party/libpg_query/src_backend_nodes_list.cpp @@ -537,4 +537,4 @@ list_copy_tail(const PGList *oldlist, int nskip) int length(const PGList *list); -} \ No newline at end of file +} diff --git a/src/duckdb/third_party/libpg_query/src_backend_nodes_makefuncs.cpp b/src/duckdb/third_party/libpg_query/src_backend_nodes_makefuncs.cpp index f5299bdb..b19b40d7 100644 --- a/src/duckdb/third_party/libpg_query/src_backend_nodes_makefuncs.cpp +++ b/src/duckdb/third_party/libpg_query/src_backend_nodes_makefuncs.cpp @@ -302,4 +302,4 @@ PGGroupingSet *makeGroupingSet(GroupingSetKind kind, PGList *content, int locati n->location = location; return n; } -} \ No newline at end of file +} diff --git a/src/duckdb/third_party/libpg_query/src_backend_nodes_value.cpp b/src/duckdb/third_party/libpg_query/src_backend_nodes_value.cpp index e8674275..487103fd 100644 --- a/src/duckdb/third_party/libpg_query/src_backend_nodes_value.cpp +++ b/src/duckdb/third_party/libpg_query/src_backend_nodes_value.cpp @@ -71,4 +71,4 @@ PGValue *makeString(const char *str) { * Caller is responsible for passing a palloc'd string. */ -} \ No newline at end of file +} diff --git a/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp b/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp index 32b6aa4d..8da0cbf8 100644 --- a/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp +++ b/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp @@ -1633,7 +1633,7 @@ union yyalloc /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 474 /* YYNRULES -- Number of rules. */ -#define YYNRULES 2156 +#define YYNRULES 2155 /* YYNRULES -- Number of states. */ #define YYNSTATES 3579 @@ -1804,149 +1804,149 @@ static const yytype_uint16 yyprhs[] = 2420, 2424, 2427, 2428, 2430, 2433, 2434, 2439, 2445, 2447, 2450, 2453, 2454, 2456, 2460, 2462, 2465, 2469, 2473, 2477, 2481, 2485, 2489, 2491, 2496, 2506, 2516, 2520, 2521, 2524, - 2527, 2528, 2534, 2538, 2539, 2541, 2543, 2547, 2553, 2557, - 2559, 2562, 2564, 2568, 2574, 2576, 2579, 2583, 2588, 2594, - 2599, 2605, 2610, 2617, 2623, 2628, 2634, 2640, 2646, 2649, - 2654, 2656, 2658, 2659, 2661, 2666, 2672, 2677, 2678, 2681, - 2684, 2687, 2689, 2691, 2693, 2695, 2696, 2701, 2704, 2706, - 2709, 2712, 2717, 2720, 2727, 2730, 2732, 2736, 2741, 2742, - 2745, 2746, 2749, 2750, 2752, 2756, 2760, 2763, 2764, 2767, - 2772, 2774, 2776, 2778, 2779, 2782, 2786, 2792, 2799, 2802, - 2806, 2808, 2814, 2820, 2826, 2830, 2834, 2838, 2843, 2844, - 2846, 2848, 2850, 2852, 2854, 2857, 2862, 2864, 2866, 2868, - 2870, 2873, 2877, 2878, 2880, 2882, 2884, 2886, 2888, 2891, - 2894, 2897, 2900, 2903, 2905, 2909, 2910, 2912, 2914, 2916, - 2918, 2924, 2927, 2929, 2931, 2933, 2935, 2940, 2942, 2945, - 2948, 2950, 2954, 2958, 2961, 2963, 2964, 2970, 2973, 2979, - 2982, 2984, 2988, 2992, 2993, 2995, 2997, 2999, 3001, 3003, - 3005, 3007, 3009, 3011, 3013, 3015, 3017, 3019, 3021, 3023, - 3025, 3027, 3029, 3031, 3033, 3035, 3037, 3039, 3041, 3043, - 3045, 3047, 3049, 3051, 3053, 3055, 3057, 3059, 3061, 3063, - 3065, 3067, 3069, 3071, 3075, 3079, 3083, 3087, 3091, 3095, - 3099, 3100, 3102, 3106, 3110, 3116, 3119, 3122, 3126, 3130, - 3134, 3138, 3142, 3146, 3150, 3154, 3158, 3162, 3166, 3170, - 3174, 3178, 3182, 3185, 3188, 3192, 3196, 3199, 3202, 3206, - 3210, 3216, 3221, 3228, 3232, 3238, 3243, 3250, 3255, 3262, - 3268, 3276, 3280, 3283, 3288, 3292, 3295, 3299, 3303, 3307, - 3311, 3316, 3320, 3325, 3329, 3334, 3340, 3347, 3354, 3362, - 3369, 3377, 3384, 3392, 3396, 3401, 3406, 3413, 3415, 3421, - 3426, 3430, 3436, 3438, 3442, 3445, 3448, 3452, 3456, 3460, - 3464, 3468, 3472, 3476, 3480, 3484, 3488, 3492, 3496, 3500, - 3504, 3508, 3511, 3514, 3520, 3527, 3534, 3542, 3544, 3547, - 3549, 3551, 3553, 3556, 3559, 3564, 3568, 3570, 3572, 3574, - 3576, 3578, 3580, 3582, 3584, 3586, 3588, 3591, 3596, 3599, - 3602, 3606, 3610, 3615, 3619, 3626, 3634, 3644, 3652, 3660, - 3666, 3668, 3670, 3672, 3678, 3685, 3692, 3697, 3702, 3707, - 3712, 3719, 3725, 3731, 3737, 3742, 3749, 3754, 3756, 3764, - 3774, 3780, 3781, 3787, 3792, 3793, 3795, 3796, 3799, 3800, - 3802, 3806, 3810, 3813, 3816, 3817, 3824, 3826, 3827, 3831, - 3832, 3836, 3840, 3844, 3845, 3847, 3852, 3855, 3858, 3861, - 3864, 3867, 3871, 3874, 3877, 3881, 3882, 3887, 3891, 3893, - 3899, 3903, 3905, 3909, 3911, 3914, 3918, 3920, 3924, 3926, - 3929, 3931, 3932, 3934, 3936, 3938, 3940, 3942, 3944, 3946, - 3948, 3950, 3952, 3954, 3956, 3958, 3960, 3962, 3964, 3966, - 3968, 3970, 3972, 3977, 3979, 3984, 3986, 3991, 3993, 3996, - 3998, 4001, 4003, 4006, 4008, 4012, 4014, 4018, 4020, 4023, - 4025, 4029, 4031, 4034, 4036, 4037, 4039, 4043, 4045, 4049, - 4053, 4055, 4059, 4063, 4064, 4066, 4068, 4070, 4072, 4074, - 4076, 4078, 4080, 4082, 4084, 4086, 4088, 4090, 4092, 4094, - 4099, 4103, 4106, 4110, 4111, 4115, 4119, 4122, 4125, 4127, - 4128, 4131, 4134, 4138, 4141, 4143, 4145, 4149, 4151, 4153, - 4159, 4161, 4164, 4169, 4172, 4173, 4175, 4176, 4178, 4182, - 4184, 4186, 4189, 4193, 4199, 4207, 4215, 4217, 4218, 4219, - 4222, 4223, 4226, 4230, 4234, 4238, 4244, 4252, 4260, 4261, - 4264, 4266, 4267, 4269, 4270, 4272, 4276, 4278, 4281, 4285, - 4288, 4290, 4295, 4298, 4300, 4301, 4305, 4307, 4311, 4313, - 4316, 4321, 4324, 4325, 4327, 4331, 4333, 4337, 4339, 4342, - 4344, 4348, 4350, 4352, 4355, 4357, 4359, 4362, 4364, 4366, - 4369, 4377, 4380, 4386, 4390, 4394, 4396, 4398, 4400, 4402, - 4404, 4406, 4408, 4410, 4412, 4414, 4416, 4418, 4420, 4422, - 4425, 4428, 4432, 4436, 4437, 4439, 4441, 4443, 4449, 4453, - 4454, 4456, 4458, 4460, 4462, 4464, 4466, 4471, 4479, 4486, - 4489, 4490, 4492, 4494, 4496, 4498, 4512, 4529, 4531, 4534, - 4535, 4537, 4538, 4540, 4541, 4544, 4545, 4547, 4548, 4555, - 4564, 4571, 4580, 4587, 4596, 4600, 4603, 4605, 4606, 4613, - 4620, 4622, 4624, 4626, 4628, 4630, 4632, 4635, 4637, 4639, - 4641, 4643, 4645, 4650, 4657, 4661, 4664, 4669, 4673, 4679, - 4681, 4682, 4684, 4686, 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, 4765, 4767, 4769, 4771, 4773, 4775, 4777, 4780, - 4782, 4784, 4787, 4791, 4795, 4799, 4803, 4805, 4809, 4813, - 4816, 4820, 4824, 4826, 4828, 4830, 4834, 4840, 4842, 4844, - 4846, 4848, 4852, 4855, 4860, 4867, 4874, 4875, 4877, 4879, - 4881, 4882, 4885, 4888, 4893, 4900, 4906, 4911, 4918, 4920, - 4922, 4924, 4926, 4928, 4930, 4931, 4933, 4937, 4939, 4940, - 4948, 4952, 4954, 4957, 4961, 4964, 4965, 4968, 4969, 4972, - 4977, 4983, 4992, 4995, 4999, 5005, 5007, 5008, 5011, 5012, - 5015, 5019, 5023, 5027, 5031, 5033, 5035, 5037, 5040, 5044, - 5047, 5050, 5053, 5056, 5060, 5065, 5069, 5071, 5073, 5075, - 5077, 5079, 5081, 5082, 5084, 5088, 5090, 5094, 5097, 5107, - 5120, 5132, 5145, 5160, 5164, 5169, 5174, 5175, 5183, 5194, - 5204, 5207, 5211, 5212, 5217, 5219, 5221, 5223, 5225, 5227, - 5229, 5231, 5233, 5235, 5237, 5239, 5241, 5243, 5245, 5247, - 5249, 5251, 5253, 5255, 5257, 5259, 5261, 5263, 5265, 5267, - 5269, 5271, 5273, 5275, 5277, 5279, 5281, 5283, 5285, 5287, - 5289, 5291, 5293, 5295, 5297, 5299, 5301, 5303, 5305, 5307, - 5309, 5311, 5313, 5315, 5317, 5319, 5321, 5323, 5325, 5327, - 5329, 5331, 5333, 5335, 5337, 5339, 5341, 5343, 5345, 5347, - 5349, 5351, 5353, 5355, 5357, 5359, 5361, 5363, 5365, 5367, - 5369, 5371, 5373, 5375, 5377, 5379, 5381, 5383, 5385, 5387, - 5389, 5391, 5393, 5395, 5397, 5399, 5401, 5403, 5405, 5407, - 5409, 5411, 5413, 5415, 5417, 5419, 5421, 5423, 5425, 5427, - 5429, 5431, 5433, 5435, 5437, 5439, 5441, 5443, 5445, 5447, - 5449, 5451, 5453, 5455, 5457, 5459, 5461, 5463, 5465, 5467, - 5469, 5471, 5473, 5475, 5477, 5479, 5481, 5483, 5485, 5487, - 5489, 5491, 5493, 5495, 5497, 5499, 5501, 5503, 5505, 5507, - 5509, 5511, 5513, 5515, 5517, 5519, 5521, 5523, 5525, 5527, - 5529, 5531, 5533, 5535, 5537, 5539, 5541, 5543, 5545, 5547, - 5549, 5551, 5553, 5555, 5557, 5559, 5561, 5563, 5565, 5567, - 5569, 5571, 5573, 5575, 5577, 5579, 5581, 5583, 5585, 5587, - 5589, 5591, 5593, 5595, 5597, 5599, 5601, 5603, 5605, 5607, - 5609, 5611, 5613, 5615, 5617, 5619, 5621, 5623, 5625, 5627, - 5629, 5631, 5633, 5635, 5637, 5639, 5641, 5643, 5645, 5647, - 5649, 5651, 5653, 5655, 5657, 5659, 5661, 5663, 5665, 5667, - 5669, 5671, 5673, 5675, 5677, 5679, 5681, 5683, 5685, 5687, - 5689, 5691, 5693, 5695, 5697, 5699, 5701, 5703, 5705, 5707, - 5709, 5711, 5713, 5715, 5717, 5719, 5721, 5723, 5725, 5727, - 5729, 5731, 5733, 5735, 5737, 5739, 5741, 5743, 5745, 5747, - 5749, 5751, 5753, 5755, 5757, 5759, 5761, 5763, 5765, 5767, - 5769, 5771, 5773, 5775, 5777, 5779, 5781, 5783, 5785, 5787, - 5789, 5791, 5793, 5795, 5797, 5799, 5801, 5803, 5805, 5807, - 5809, 5811, 5813, 5815, 5817, 5819, 5821, 5823, 5825, 5827, - 5829, 5831, 5833, 5835, 5837, 5839, 5841, 5843, 5845, 5847, - 5849, 5851, 5853, 5855, 5857, 5859, 5861, 5863, 5865, 5867, - 5869, 5871, 5873, 5875, 5877, 5879, 5881, 5883, 5885, 5887, - 5889, 5891, 5893, 5895, 5897, 5899, 5901, 5903, 5905, 5907, - 5909, 5911, 5913, 5915, 5917, 5919, 5921, 5923, 5925, 5927, - 5929, 5931, 5933, 5935, 5937, 5939, 5941, 5943, 5945, 5947, - 5949, 5951, 5953, 5955, 5957, 5959, 5961, 5963, 5965, 5967, - 5969, 5971, 5973, 5975, 5977, 5979, 5981, 5983, 5985, 5987, - 5989, 5991, 5993, 5995, 5997, 5999, 6001, 6003, 6005, 6007, - 6009, 6011, 6013, 6015, 6017, 6019, 6021, 6023, 6025, 6027, - 6029, 6031, 6033, 6035, 6037, 6039, 6041, 6043, 6045, 6047, - 6049, 6051, 6053, 6055, 6057, 6059, 6061, 6063, 6065, 6067, - 6069, 6071, 6073, 6075, 6077, 6079, 6081, 6083, 6085, 6087, - 6089, 6091, 6093, 6095, 6097, 6099, 6101, 6103, 6105, 6107, - 6109, 6111, 6113, 6115, 6117, 6119, 6121, 6123, 6125, 6127, - 6129, 6131, 6133, 6135, 6137, 6139, 6141, 6143, 6145, 6147, - 6149, 6151, 6153, 6155, 6157, 6159, 6161, 6163, 6165, 6167, - 6169, 6171, 6173, 6175, 6177, 6179, 6181, 6183, 6185, 6187, - 6189, 6191, 6193, 6195, 6197, 6199, 6201, 6203, 6205, 6207, - 6209, 6211, 6213, 6215, 6217, 6219, 6221, 6223, 6225, 6227, - 6229, 6231, 6233, 6235, 6237, 6239, 6241, 6243, 6245, 6247, - 6249, 6251, 6253, 6255, 6257, 6259, 6261, 6263, 6265, 6267, - 6269, 6271, 6273, 6275, 6277, 6279, 6281, 6283, 6285, 6287, - 6289, 6291, 6293, 6295, 6297, 6299, 6301, 6303, 6305, 6307, - 6309, 6311, 6313, 6315, 6317, 6319, 6321, 6323, 6325, 6327, - 6329, 6331, 6333, 6335, 6337, 6339, 6341, 6343, 6345, 6347, - 6349, 6351, 6353, 6355, 6357, 6359, 6361, 6363, 6365, 6367, - 6369, 6371, 6373, 6375, 6377, 6379, 6381, 6383, 6385, 6387, - 6389, 6391, 6393, 6395, 6397, 6399, 6401, 6403, 6405, 6407, - 6409, 6411, 6413, 6415, 6417, 6419, 6421, 6423, 6425, 6427, - 6429, 6431, 6433, 6435, 6437, 6439, 6441, 6443, 6445, 6447, - 6449, 6451, 6453, 6455, 6457, 6459, 6461 + 2527, 2528, 2534, 2538, 2540, 2542, 2546, 2552, 2556, 2558, + 2561, 2563, 2567, 2573, 2575, 2578, 2582, 2587, 2593, 2598, + 2604, 2609, 2616, 2622, 2627, 2633, 2639, 2645, 2648, 2653, + 2655, 2657, 2658, 2660, 2665, 2671, 2676, 2677, 2680, 2683, + 2686, 2688, 2690, 2692, 2694, 2695, 2700, 2703, 2705, 2708, + 2711, 2716, 2719, 2726, 2729, 2731, 2735, 2740, 2741, 2744, + 2745, 2748, 2749, 2751, 2755, 2759, 2762, 2763, 2766, 2771, + 2773, 2775, 2777, 2778, 2781, 2785, 2791, 2798, 2801, 2805, + 2807, 2813, 2819, 2825, 2829, 2833, 2837, 2842, 2843, 2845, + 2847, 2849, 2851, 2853, 2856, 2861, 2863, 2865, 2867, 2869, + 2872, 2876, 2877, 2879, 2881, 2883, 2885, 2887, 2890, 2893, + 2896, 2899, 2902, 2904, 2908, 2909, 2911, 2913, 2915, 2917, + 2923, 2926, 2928, 2930, 2932, 2934, 2939, 2941, 2944, 2947, + 2949, 2953, 2957, 2960, 2962, 2963, 2969, 2972, 2978, 2981, + 2983, 2987, 2991, 2992, 2994, 2996, 2998, 3000, 3002, 3004, + 3006, 3008, 3010, 3012, 3014, 3016, 3018, 3020, 3022, 3024, + 3026, 3028, 3030, 3032, 3034, 3036, 3038, 3040, 3042, 3044, + 3046, 3048, 3050, 3052, 3054, 3056, 3058, 3060, 3062, 3064, + 3066, 3068, 3070, 3074, 3078, 3082, 3086, 3090, 3094, 3098, + 3099, 3101, 3105, 3109, 3115, 3118, 3121, 3125, 3129, 3133, + 3137, 3141, 3145, 3149, 3153, 3157, 3161, 3165, 3169, 3173, + 3177, 3181, 3184, 3187, 3191, 3195, 3198, 3201, 3205, 3209, + 3215, 3220, 3227, 3231, 3237, 3242, 3249, 3254, 3261, 3267, + 3275, 3279, 3282, 3287, 3291, 3294, 3298, 3302, 3306, 3310, + 3315, 3319, 3324, 3328, 3333, 3339, 3346, 3353, 3361, 3368, + 3376, 3383, 3391, 3395, 3400, 3405, 3412, 3414, 3420, 3425, + 3429, 3435, 3437, 3441, 3444, 3447, 3451, 3455, 3459, 3463, + 3467, 3471, 3475, 3479, 3483, 3487, 3491, 3495, 3499, 3503, + 3507, 3510, 3513, 3519, 3526, 3533, 3541, 3543, 3546, 3548, + 3550, 3552, 3555, 3558, 3563, 3567, 3569, 3571, 3573, 3575, + 3577, 3579, 3581, 3583, 3585, 3587, 3590, 3595, 3598, 3601, + 3605, 3609, 3614, 3618, 3625, 3633, 3643, 3651, 3659, 3665, + 3667, 3669, 3671, 3677, 3684, 3691, 3696, 3701, 3706, 3711, + 3718, 3724, 3730, 3736, 3741, 3748, 3753, 3755, 3763, 3773, + 3779, 3780, 3786, 3791, 3792, 3794, 3795, 3798, 3799, 3801, + 3805, 3809, 3812, 3815, 3816, 3823, 3825, 3826, 3830, 3831, + 3835, 3839, 3843, 3844, 3846, 3851, 3854, 3857, 3860, 3863, + 3866, 3870, 3873, 3876, 3880, 3881, 3886, 3890, 3892, 3898, + 3902, 3904, 3908, 3910, 3913, 3917, 3919, 3923, 3925, 3928, + 3930, 3931, 3933, 3935, 3937, 3939, 3941, 3943, 3945, 3947, + 3949, 3951, 3953, 3955, 3957, 3959, 3961, 3963, 3965, 3967, + 3969, 3971, 3976, 3978, 3983, 3985, 3990, 3992, 3995, 3997, + 4000, 4002, 4005, 4007, 4011, 4013, 4017, 4019, 4022, 4024, + 4028, 4030, 4033, 4035, 4036, 4038, 4042, 4044, 4048, 4052, + 4054, 4058, 4062, 4063, 4065, 4067, 4069, 4071, 4073, 4075, + 4077, 4079, 4081, 4083, 4085, 4087, 4089, 4091, 4093, 4098, + 4102, 4105, 4109, 4110, 4114, 4118, 4121, 4124, 4126, 4127, + 4130, 4133, 4137, 4140, 4142, 4144, 4148, 4150, 4152, 4158, + 4160, 4163, 4168, 4171, 4172, 4174, 4175, 4177, 4181, 4183, + 4185, 4188, 4192, 4198, 4206, 4214, 4216, 4217, 4218, 4221, + 4222, 4225, 4229, 4233, 4237, 4243, 4251, 4259, 4260, 4263, + 4265, 4266, 4268, 4269, 4271, 4275, 4277, 4280, 4284, 4287, + 4289, 4294, 4297, 4299, 4300, 4304, 4306, 4310, 4312, 4315, + 4320, 4323, 4324, 4326, 4330, 4332, 4336, 4338, 4341, 4343, + 4347, 4349, 4351, 4354, 4356, 4358, 4361, 4363, 4365, 4368, + 4376, 4379, 4385, 4389, 4393, 4395, 4397, 4399, 4401, 4403, + 4405, 4407, 4409, 4411, 4413, 4415, 4417, 4419, 4421, 4424, + 4427, 4431, 4435, 4436, 4438, 4440, 4442, 4448, 4452, 4453, + 4455, 4457, 4459, 4461, 4463, 4465, 4470, 4478, 4485, 4488, + 4489, 4491, 4493, 4495, 4497, 4511, 4528, 4530, 4533, 4534, + 4536, 4537, 4539, 4540, 4543, 4544, 4546, 4547, 4554, 4563, + 4570, 4579, 4586, 4595, 4599, 4602, 4604, 4605, 4612, 4619, + 4621, 4623, 4625, 4627, 4629, 4631, 4634, 4636, 4638, 4640, + 4642, 4644, 4649, 4656, 4660, 4663, 4668, 4672, 4678, 4680, + 4681, 4683, 4685, 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, 4764, 4766, 4768, 4770, 4772, 4774, 4776, 4779, 4781, + 4783, 4786, 4790, 4794, 4798, 4802, 4804, 4808, 4812, 4815, + 4819, 4823, 4825, 4827, 4829, 4833, 4839, 4841, 4843, 4845, + 4847, 4851, 4854, 4859, 4866, 4873, 4874, 4876, 4878, 4880, + 4881, 4884, 4887, 4892, 4899, 4905, 4910, 4917, 4919, 4921, + 4923, 4925, 4927, 4929, 4930, 4932, 4936, 4938, 4939, 4947, + 4951, 4953, 4956, 4960, 4963, 4964, 4967, 4968, 4971, 4976, + 4982, 4991, 4994, 4998, 5004, 5006, 5007, 5010, 5011, 5014, + 5018, 5022, 5026, 5030, 5032, 5034, 5036, 5039, 5043, 5046, + 5049, 5052, 5055, 5059, 5064, 5068, 5070, 5072, 5074, 5076, + 5078, 5080, 5081, 5083, 5087, 5089, 5093, 5096, 5106, 5119, + 5131, 5144, 5159, 5163, 5168, 5173, 5174, 5182, 5193, 5203, + 5206, 5210, 5211, 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, 5342, 5344, 5346, 5348, + 5350, 5352, 5354, 5356, 5358, 5360, 5362, 5364, 5366, 5368, + 5370, 5372, 5374, 5376, 5378, 5380, 5382, 5384, 5386, 5388, + 5390, 5392, 5394, 5396, 5398, 5400, 5402, 5404, 5406, 5408, + 5410, 5412, 5414, 5416, 5418, 5420, 5422, 5424, 5426, 5428, + 5430, 5432, 5434, 5436, 5438, 5440, 5442, 5444, 5446, 5448, + 5450, 5452, 5454, 5456, 5458, 5460, 5462, 5464, 5466, 5468, + 5470, 5472, 5474, 5476, 5478, 5480, 5482, 5484, 5486, 5488, + 5490, 5492, 5494, 5496, 5498, 5500, 5502, 5504, 5506, 5508, + 5510, 5512, 5514, 5516, 5518, 5520, 5522, 5524, 5526, 5528, + 5530, 5532, 5534, 5536, 5538, 5540, 5542, 5544, 5546, 5548, + 5550, 5552, 5554, 5556, 5558, 5560, 5562, 5564, 5566, 5568, + 5570, 5572, 5574, 5576, 5578, 5580, 5582, 5584, 5586, 5588, + 5590, 5592, 5594, 5596, 5598, 5600, 5602, 5604, 5606, 5608, + 5610, 5612, 5614, 5616, 5618, 5620, 5622, 5624, 5626, 5628, + 5630, 5632, 5634, 5636, 5638, 5640, 5642, 5644, 5646, 5648, + 5650, 5652, 5654, 5656, 5658, 5660, 5662, 5664, 5666, 5668, + 5670, 5672, 5674, 5676, 5678, 5680, 5682, 5684, 5686, 5688, + 5690, 5692, 5694, 5696, 5698, 5700, 5702, 5704, 5706, 5708, + 5710, 5712, 5714, 5716, 5718, 5720, 5722, 5724, 5726, 5728, + 5730, 5732, 5734, 5736, 5738, 5740, 5742, 5744, 5746, 5748, + 5750, 5752, 5754, 5756, 5758, 5760, 5762, 5764, 5766, 5768, + 5770, 5772, 5774, 5776, 5778, 5780, 5782, 5784, 5786, 5788, + 5790, 5792, 5794, 5796, 5798, 5800, 5802, 5804, 5806, 5808, + 5810, 5812, 5814, 5816, 5818, 5820, 5822, 5824, 5826, 5828, + 5830, 5832, 5834, 5836, 5838, 5840, 5842, 5844, 5846, 5848, + 5850, 5852, 5854, 5856, 5858, 5860, 5862, 5864, 5866, 5868, + 5870, 5872, 5874, 5876, 5878, 5880, 5882, 5884, 5886, 5888, + 5890, 5892, 5894, 5896, 5898, 5900, 5902, 5904, 5906, 5908, + 5910, 5912, 5914, 5916, 5918, 5920, 5922, 5924, 5926, 5928, + 5930, 5932, 5934, 5936, 5938, 5940, 5942, 5944, 5946, 5948, + 5950, 5952, 5954, 5956, 5958, 5960, 5962, 5964, 5966, 5968, + 5970, 5972, 5974, 5976, 5978, 5980, 5982, 5984, 5986, 5988, + 5990, 5992, 5994, 5996, 5998, 6000, 6002, 6004, 6006, 6008, + 6010, 6012, 6014, 6016, 6018, 6020, 6022, 6024, 6026, 6028, + 6030, 6032, 6034, 6036, 6038, 6040, 6042, 6044, 6046, 6048, + 6050, 6052, 6054, 6056, 6058, 6060, 6062, 6064, 6066, 6068, + 6070, 6072, 6074, 6076, 6078, 6080, 6082, 6084, 6086, 6088, + 6090, 6092, 6094, 6096, 6098, 6100, 6102, 6104, 6106, 6108, + 6110, 6112, 6114, 6116, 6118, 6120, 6122, 6124, 6126, 6128, + 6130, 6132, 6134, 6136, 6138, 6140, 6142, 6144, 6146, 6148, + 6150, 6152, 6154, 6156, 6158, 6160, 6162, 6164, 6166, 6168, + 6170, 6172, 6174, 6176, 6178, 6180, 6182, 6184, 6186, 6188, + 6190, 6192, 6194, 6196, 6198, 6200, 6202, 6204, 6206, 6208, + 6210, 6212, 6214, 6216, 6218, 6220, 6222, 6224, 6226, 6228, + 6230, 6232, 6234, 6236, 6238, 6240, 6242, 6244, 6246, 6248, + 6250, 6252, 6254, 6256, 6258, 6260, 6262, 6264, 6266, 6268, + 6270, 6272, 6274, 6276, 6278, 6280, 6282, 6284, 6286, 6288, + 6290, 6292, 6294, 6296, 6298, 6300, 6302, 6304, 6306, 6308, + 6310, 6312, 6314, 6316, 6318, 6320, 6322, 6324, 6326, 6328, + 6330, 6332, 6334, 6336, 6338, 6340, 6342, 6344, 6346, 6348, + 6350, 6352, 6354, 6356, 6358, 6360, 6362, 6364, 6366, 6368, + 6370, 6372, 6374, 6376, 6378, 6380, 6382, 6384, 6386, 6388, + 6390, 6392, 6394, 6396, 6398, 6400, 6402, 6404, 6406, 6408, + 6410, 6412, 6414, 6416, 6418, 6420, 6422, 6424, 6426, 6428, + 6430, 6432, 6434, 6436, 6438, 6440, 6442, 6444, 6446, 6448, + 6450, 6452, 6454, 6456, 6458, 6460 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ @@ -2205,400 +2205,400 @@ static const yytype_int16 yyrhs[] = 167, 762, 757, 519, 768, -1, 756, 452, 758, 518, 763, 167, 765, 519, 768, -1, 181, 59, 911, -1, -1, 200, 282, -1, 148, 282, -1, -1, 823, 199, - 518, 901, 519, -1, 823, 199, 547, -1, -1, 825, - -1, 827, -1, 518, 868, 519, -1, 760, 199, 518, - 901, 519, -1, 760, 199, 547, -1, 761, -1, 762, - 761, -1, 547, -1, 518, 911, 519, -1, 763, 199, - 518, 901, 519, -1, 764, -1, 765, 764, -1, 518, - 766, 519, -1, 756, 101, 225, 756, -1, 756, 770, - 225, 756, 772, -1, 756, 225, 756, 772, -1, 756, - 269, 770, 225, 756, -1, 756, 269, 225, 756, -1, - 756, 42, 770, 225, 756, 772, -1, 756, 42, 225, - 756, 772, -1, 756, 322, 225, 756, -1, 756, 37, - 225, 756, 772, -1, 756, 383, 225, 756, 772, -1, - 40, 547, 518, 911, 519, -1, 40, 547, -1, 546, - 518, 911, 519, -1, 546, -1, 767, -1, -1, 767, - -1, 40, 518, 780, 519, -1, 40, 547, 518, 780, - 519, -1, 546, 518, 780, 519, -1, -1, 173, 771, - -1, 235, 771, -1, 364, 771, -1, 383, -1, 37, - -1, 209, -1, 300, -1, -1, 457, 518, 911, 519, - -1, 290, 822, -1, 545, -1, 545, 511, -1, 291, - 545, -1, 291, 518, 545, 519, -1, 833, 778, -1, - 369, 172, 518, 776, 519, 778, -1, 833, 777, -1, - 775, -1, 776, 522, 775, -1, 40, 518, 780, 519, - -1, -1, 504, 297, -1, -1, 477, 822, -1, -1, - 781, -1, 780, 522, 781, -1, 547, 786, 782, -1, - 80, 920, -1, -1, 546, 786, -1, 783, 522, 546, - 786, -1, 368, -1, 412, -1, 786, -1, -1, 789, - 788, -1, 390, 789, 788, -1, 789, 39, 516, 916, - 517, -1, 390, 789, 39, 516, 916, 517, -1, 789, - 39, -1, 390, 789, 39, -1, 787, -1, 784, 518, - 783, 519, 788, -1, 247, 518, 874, 519, 788, -1, - 447, 518, 783, 519, 788, -1, 3, 520, 3, -1, - 787, 520, 3, -1, 788, 516, 517, -1, 788, 516, - 916, 517, -1, -1, 791, -1, 793, -1, 795, -1, - 799, -1, 805, -1, 806, 821, -1, 806, 518, 916, - 519, -1, 793, -1, 796, -1, 800, -1, 805, -1, - 919, 792, -1, 518, 871, 519, -1, -1, 216, -1, - 217, -1, 397, -1, 54, -1, 342, -1, 165, 794, - -1, 136, 325, -1, 115, 792, -1, 112, 792, -1, - 283, 792, -1, 57, -1, 518, 916, 519, -1, -1, - 797, -1, 798, -1, 797, -1, 798, -1, 56, 804, - 518, 870, 519, -1, 56, 804, -1, 801, -1, 802, - -1, 801, -1, 802, -1, 803, 518, 916, 519, -1, - 803, -1, 72, 804, -1, 71, 804, -1, 464, -1, - 268, 72, 804, -1, 268, 71, 804, -1, 270, 804, - -1, 467, -1, -1, 430, 518, 916, 519, 807, -1, - 430, 807, -1, 429, 518, 916, 519, 807, -1, 429, - 807, -1, 219, -1, 504, 429, 501, -1, 482, 429, - 501, -1, -1, 498, -1, 499, -1, 263, -1, 264, - -1, 109, -1, 110, -1, 189, -1, 190, -1, 259, - -1, 260, -1, 378, -1, 379, -1, 257, -1, 258, - -1, 253, -1, 254, -1, 474, -1, 475, -1, 337, - -1, 338, -1, 113, -1, 114, -1, 69, -1, 68, - -1, 256, -1, 255, -1, 808, -1, 809, -1, 810, + 518, 901, 519, -1, 823, 199, 547, -1, 825, -1, + 827, -1, 518, 868, 519, -1, 760, 199, 518, 901, + 519, -1, 760, 199, 547, -1, 761, -1, 762, 761, + -1, 547, -1, 518, 911, 519, -1, 763, 199, 518, + 901, 519, -1, 764, -1, 765, 764, -1, 518, 766, + 519, -1, 756, 101, 225, 756, -1, 756, 770, 225, + 756, 772, -1, 756, 225, 756, 772, -1, 756, 269, + 770, 225, 756, -1, 756, 269, 225, 756, -1, 756, + 42, 770, 225, 756, 772, -1, 756, 42, 225, 756, + 772, -1, 756, 322, 225, 756, -1, 756, 37, 225, + 756, 772, -1, 756, 383, 225, 756, 772, -1, 40, + 547, 518, 911, 519, -1, 40, 547, -1, 546, 518, + 911, 519, -1, 546, -1, 767, -1, -1, 767, -1, + 40, 518, 780, 519, -1, 40, 547, 518, 780, 519, + -1, 546, 518, 780, 519, -1, -1, 173, 771, -1, + 235, 771, -1, 364, 771, -1, 383, -1, 37, -1, + 209, -1, 300, -1, -1, 457, 518, 911, 519, -1, + 290, 822, -1, 545, -1, 545, 511, -1, 291, 545, + -1, 291, 518, 545, 519, -1, 833, 778, -1, 369, + 172, 518, 776, 519, 778, -1, 833, 777, -1, 775, + -1, 776, 522, 775, -1, 40, 518, 780, 519, -1, + -1, 504, 297, -1, -1, 477, 822, -1, -1, 781, + -1, 780, 522, 781, -1, 547, 786, 782, -1, 80, + 920, -1, -1, 546, 786, -1, 783, 522, 546, 786, + -1, 368, -1, 412, -1, 786, -1, -1, 789, 788, + -1, 390, 789, 788, -1, 789, 39, 516, 916, 517, + -1, 390, 789, 39, 516, 916, 517, -1, 789, 39, + -1, 390, 789, 39, -1, 787, -1, 784, 518, 783, + 519, 788, -1, 247, 518, 874, 519, 788, -1, 447, + 518, 783, 519, 788, -1, 3, 520, 3, -1, 787, + 520, 3, -1, 788, 516, 517, -1, 788, 516, 916, + 517, -1, -1, 791, -1, 793, -1, 795, -1, 799, + -1, 805, -1, 806, 821, -1, 806, 518, 916, 519, + -1, 793, -1, 796, -1, 800, -1, 805, -1, 919, + 792, -1, 518, 871, 519, -1, -1, 216, -1, 217, + -1, 397, -1, 54, -1, 342, -1, 165, 794, -1, + 136, 325, -1, 115, 792, -1, 112, 792, -1, 283, + 792, -1, 57, -1, 518, 916, 519, -1, -1, 797, + -1, 798, -1, 797, -1, 798, -1, 56, 804, 518, + 870, 519, -1, 56, 804, -1, 801, -1, 802, -1, + 801, -1, 802, -1, 803, 518, 916, 519, -1, 803, + -1, 72, 804, -1, 71, 804, -1, 464, -1, 268, + 72, 804, -1, 268, 71, 804, -1, 270, 804, -1, + 467, -1, -1, 430, 518, 916, 519, 807, -1, 430, + 807, -1, 429, 518, 916, 519, 807, -1, 429, 807, + -1, 219, -1, 504, 429, 501, -1, 482, 429, 501, + -1, -1, 498, -1, 499, -1, 263, -1, 264, -1, + 109, -1, 110, -1, 189, -1, 190, -1, 259, -1, + 260, -1, 378, -1, 379, -1, 257, -1, 258, -1, + 253, -1, 254, -1, 474, -1, 475, -1, 337, -1, + 338, -1, 113, -1, 114, -1, 69, -1, 68, -1, + 256, -1, 255, -1, 808, -1, 809, -1, 810, -1, + 811, -1, 812, -1, 813, -1, 814, -1, 815, -1, + 816, -1, 817, -1, 818, -1, 819, -1, 820, -1, + 808, 431, 809, -1, 810, 431, 811, -1, 810, 431, + 812, -1, 810, 431, 813, -1, 811, 431, 812, -1, + 811, 431, 813, -1, 812, 431, 813, -1, -1, 824, + -1, 822, 11, 786, -1, 822, 80, 920, -1, 822, + 46, 429, 501, 822, -1, 509, 822, -1, 510, 822, + -1, 822, 509, 822, -1, 822, 510, 822, -1, 822, + 511, 822, -1, 822, 512, 822, -1, 822, 15, 822, + -1, 822, 513, 822, -1, 822, 514, 822, -1, 822, + 16, 822, -1, 822, 505, 822, -1, 822, 506, 822, + -1, 822, 507, 822, -1, 822, 19, 822, -1, 822, + 20, 822, -1, 822, 21, 822, -1, 822, 863, 822, + -1, 863, 822, -1, 822, 863, -1, 822, 36, 822, + -1, 822, 295, 822, -1, 275, 822, -1, 502, 822, + -1, 822, 177, 822, -1, 822, 237, 822, -1, 822, + 237, 822, 145, 822, -1, 822, 502, 237, 822, -1, + 822, 502, 237, 822, 145, 822, -1, 822, 194, 822, + -1, 822, 194, 822, 145, 822, -1, 822, 502, 194, + 822, -1, 822, 502, 194, 822, 145, 822, -1, 822, + 394, 431, 822, -1, 822, 394, 431, 822, 145, 822, + -1, 822, 502, 394, 431, 822, -1, 822, 502, 394, + 431, 822, 145, 822, -1, 822, 222, 280, -1, 822, + 223, -1, 822, 222, 275, 280, -1, 822, 275, 280, + -1, 822, 278, -1, 822, 17, 822, -1, 822, 18, + 822, -1, 852, 302, 852, -1, 822, 222, 438, -1, + 822, 222, 275, 438, -1, 822, 222, 160, -1, 822, + 222, 275, 160, -1, 822, 222, 449, -1, 822, 222, + 275, 449, -1, 822, 222, 132, 172, 822, -1, 822, + 222, 275, 132, 172, 822, -1, 822, 222, 285, 518, + 874, 519, -1, 822, 222, 275, 285, 518, 874, 519, + -1, 822, 53, 898, 823, 36, 822, -1, 822, 502, + 53, 898, 823, 36, 822, -1, 822, 53, 416, 823, + 36, 822, -1, 822, 502, 53, 416, 823, 36, 822, + -1, 822, 199, 884, -1, 822, 502, 199, 884, -1, + 822, 865, 860, 687, -1, 822, 865, 860, 518, 822, + 519, -1, 117, -1, 511, 83, 518, 822, 519, -1, + 83, 518, 822, 519, -1, 511, 904, 908, -1, 546, + 520, 511, 904, 908, -1, 824, -1, 823, 11, 786, + -1, 509, 823, -1, 510, 823, -1, 823, 509, 823, + -1, 823, 510, 823, -1, 823, 511, 823, -1, 823, + 512, 823, -1, 823, 15, 823, -1, 823, 513, 823, + -1, 823, 514, 823, -1, 823, 16, 823, -1, 823, + 505, 823, -1, 823, 506, 823, -1, 823, 507, 823, + -1, 823, 19, 823, -1, 823, 20, 823, -1, 823, + 21, 823, -1, 823, 863, 823, -1, 863, 823, -1, + 823, 863, -1, 823, 222, 132, 172, 823, -1, 823, + 222, 275, 132, 172, 823, -1, 823, 222, 285, 518, + 874, 519, -1, 823, 222, 275, 285, 518, 874, 519, + -1, 825, -1, 826, 897, -1, 892, -1, 915, -1, + 687, -1, 687, 549, -1, 152, 687, -1, 741, 518, + 870, 519, -1, 518, 822, 519, -1, 827, -1, 852, + -1, 523, -1, 10, -1, 829, -1, 830, -1, 832, + -1, 885, -1, 828, -1, 836, -1, 39, 687, -1, + 39, 516, 871, 517, -1, 524, 9, -1, 525, 552, + -1, 516, 871, 517, -1, 526, 855, 527, -1, 247, + 526, 859, 527, -1, 914, 518, 519, -1, 914, 518, + 872, 710, 709, 519, -1, 914, 518, 466, 873, 710, + 709, 519, -1, 914, 518, 872, 522, 466, 873, 710, + 709, 519, -1, 914, 518, 30, 872, 710, 709, 519, + -1, 914, 518, 132, 872, 710, 709, 519, -1, 831, + 837, 838, 839, 843, -1, 834, -1, 831, -1, 834, + -1, 81, 167, 518, 822, 519, -1, 66, 518, 822, + 40, 786, 519, -1, 441, 518, 822, 40, 786, 519, + -1, 159, 518, 875, 519, -1, 303, 518, 877, 519, + -1, 321, 518, 879, 519, -1, 414, 518, 880, 519, + -1, 435, 518, 822, 40, 786, 519, -1, 437, 518, + 58, 883, 519, -1, 437, 518, 233, 883, 519, -1, + 437, 518, 432, 883, 519, -1, 437, 518, 883, 519, + -1, 281, 518, 822, 522, 822, 519, -1, 79, 518, + 870, 519, -1, 890, -1, 516, 822, 167, 835, 199, + 822, 517, -1, 516, 822, 167, 835, 199, 824, 192, + 822, 517, -1, 481, 181, 518, 711, 519, -1, -1, + 163, 518, 477, 822, 519, -1, 163, 518, 822, 519, + -1, -1, 155, -1, -1, 479, 841, -1, -1, 842, + -1, 841, 522, 842, -1, 546, 40, 844, -1, 301, + 844, -1, 301, 546, -1, -1, 518, 845, 846, 710, + 847, 519, -1, 546, -1, -1, 310, 59, 869, -1, + -1, 340, 848, 850, -1, 369, 848, 850, -1, 184, + 848, 850, -1, -1, 849, -1, 53, 849, 36, 849, + -1, 444, 324, -1, 444, 166, -1, 104, 368, -1, + 822, 324, -1, 822, 166, -1, 148, 104, 368, -1, + 148, 181, -1, 148, 428, -1, 148, 273, 298, -1, + -1, 368, 518, 870, 519, -1, 368, 518, 519, -1, + 851, -1, 518, 869, 522, 822, 519, -1, 547, 528, + 822, -1, 853, -1, 854, 522, 853, -1, 854, -1, + 854, 522, -1, 822, 528, 822, -1, 856, -1, 857, + 522, 856, -1, 857, -1, 857, 522, -1, 858, -1, + -1, 38, -1, 399, -1, 30, -1, 8, -1, 862, + -1, 509, -1, 510, -1, 511, -1, 512, -1, 15, + -1, 513, -1, 514, -1, 16, -1, 505, -1, 506, + -1, 507, -1, 19, -1, 20, -1, 21, -1, 8, + -1, 292, 518, 866, 519, -1, 861, -1, 292, 518, + 866, 519, -1, 861, -1, 292, 518, 866, 519, -1, + 237, -1, 502, 237, -1, 177, -1, 502, 177, -1, + 194, -1, 502, 194, -1, 861, -1, 546, 520, 866, + -1, 824, -1, 867, 522, 824, -1, 867, -1, 867, + 522, -1, 822, -1, 869, 522, 822, -1, 869, -1, + 869, 522, -1, 870, -1, -1, 873, -1, 872, 522, + 873, -1, 822, -1, 923, 13, 822, -1, 923, 14, + 822, -1, 786, -1, 874, 522, 786, -1, 876, 172, + 822, -1, -1, 3, -1, 808, -1, 809, -1, 810, -1, 811, -1, 812, -1, 813, -1, 814, -1, 815, -1, 816, -1, 817, -1, 818, -1, 819, -1, 820, - -1, 808, 431, 809, -1, 810, 431, 811, -1, 810, - 431, 812, -1, 810, 431, 813, -1, 811, 431, 812, - -1, 811, 431, 813, -1, 812, 431, 813, -1, -1, - 824, -1, 822, 11, 786, -1, 822, 80, 920, -1, - 822, 46, 429, 501, 822, -1, 509, 822, -1, 510, - 822, -1, 822, 509, 822, -1, 822, 510, 822, -1, - 822, 511, 822, -1, 822, 512, 822, -1, 822, 15, - 822, -1, 822, 513, 822, -1, 822, 514, 822, -1, - 822, 16, 822, -1, 822, 505, 822, -1, 822, 506, - 822, -1, 822, 507, 822, -1, 822, 19, 822, -1, - 822, 20, 822, -1, 822, 21, 822, -1, 822, 863, - 822, -1, 863, 822, -1, 822, 863, -1, 822, 36, - 822, -1, 822, 295, 822, -1, 275, 822, -1, 502, - 822, -1, 822, 177, 822, -1, 822, 237, 822, -1, - 822, 237, 822, 145, 822, -1, 822, 502, 237, 822, - -1, 822, 502, 237, 822, 145, 822, -1, 822, 194, - 822, -1, 822, 194, 822, 145, 822, -1, 822, 502, - 194, 822, -1, 822, 502, 194, 822, 145, 822, -1, - 822, 394, 431, 822, -1, 822, 394, 431, 822, 145, - 822, -1, 822, 502, 394, 431, 822, -1, 822, 502, - 394, 431, 822, 145, 822, -1, 822, 222, 280, -1, - 822, 223, -1, 822, 222, 275, 280, -1, 822, 275, - 280, -1, 822, 278, -1, 822, 17, 822, -1, 822, - 18, 822, -1, 852, 302, 852, -1, 822, 222, 438, - -1, 822, 222, 275, 438, -1, 822, 222, 160, -1, - 822, 222, 275, 160, -1, 822, 222, 449, -1, 822, - 222, 275, 449, -1, 822, 222, 132, 172, 822, -1, - 822, 222, 275, 132, 172, 822, -1, 822, 222, 285, - 518, 874, 519, -1, 822, 222, 275, 285, 518, 874, - 519, -1, 822, 53, 898, 823, 36, 822, -1, 822, - 502, 53, 898, 823, 36, 822, -1, 822, 53, 416, - 823, 36, 822, -1, 822, 502, 53, 416, 823, 36, - 822, -1, 822, 199, 884, -1, 822, 502, 199, 884, - -1, 822, 865, 860, 687, -1, 822, 865, 860, 518, - 822, 519, -1, 117, -1, 511, 83, 518, 822, 519, - -1, 83, 518, 822, 519, -1, 511, 904, 908, -1, - 546, 520, 511, 904, 908, -1, 824, -1, 823, 11, - 786, -1, 509, 823, -1, 510, 823, -1, 823, 509, - 823, -1, 823, 510, 823, -1, 823, 511, 823, -1, - 823, 512, 823, -1, 823, 15, 823, -1, 823, 513, - 823, -1, 823, 514, 823, -1, 823, 16, 823, -1, - 823, 505, 823, -1, 823, 506, 823, -1, 823, 507, - 823, -1, 823, 19, 823, -1, 823, 20, 823, -1, - 823, 21, 823, -1, 823, 863, 823, -1, 863, 823, - -1, 823, 863, -1, 823, 222, 132, 172, 823, -1, - 823, 222, 275, 132, 172, 823, -1, 823, 222, 285, - 518, 874, 519, -1, 823, 222, 275, 285, 518, 874, - 519, -1, 825, -1, 826, 897, -1, 892, -1, 915, - -1, 687, -1, 687, 549, -1, 152, 687, -1, 741, - 518, 870, 519, -1, 518, 822, 519, -1, 827, -1, - 852, -1, 523, -1, 10, -1, 829, -1, 830, -1, - 832, -1, 885, -1, 828, -1, 836, -1, 39, 687, - -1, 39, 516, 871, 517, -1, 524, 9, -1, 525, - 552, -1, 516, 871, 517, -1, 526, 855, 527, -1, - 247, 526, 859, 527, -1, 914, 518, 519, -1, 914, - 518, 872, 710, 709, 519, -1, 914, 518, 466, 873, - 710, 709, 519, -1, 914, 518, 872, 522, 466, 873, - 710, 709, 519, -1, 914, 518, 30, 872, 710, 709, - 519, -1, 914, 518, 132, 872, 710, 709, 519, -1, - 831, 837, 838, 839, 843, -1, 834, -1, 831, -1, - 834, -1, 81, 167, 518, 822, 519, -1, 66, 518, - 822, 40, 786, 519, -1, 441, 518, 822, 40, 786, - 519, -1, 159, 518, 875, 519, -1, 303, 518, 877, - 519, -1, 321, 518, 879, 519, -1, 414, 518, 880, - 519, -1, 435, 518, 822, 40, 786, 519, -1, 437, - 518, 58, 883, 519, -1, 437, 518, 233, 883, 519, - -1, 437, 518, 432, 883, 519, -1, 437, 518, 883, - 519, -1, 281, 518, 822, 522, 822, 519, -1, 79, - 518, 870, 519, -1, 890, -1, 516, 822, 167, 835, - 199, 822, 517, -1, 516, 822, 167, 835, 199, 824, - 192, 822, 517, -1, 481, 181, 518, 711, 519, -1, - -1, 163, 518, 477, 822, 519, -1, 163, 518, 822, - 519, -1, -1, 155, -1, -1, 479, 841, -1, -1, - 842, -1, 841, 522, 842, -1, 546, 40, 844, -1, - 301, 844, -1, 301, 546, -1, -1, 518, 845, 846, - 710, 847, 519, -1, 546, -1, -1, 310, 59, 869, - -1, -1, 340, 848, 850, -1, 369, 848, 850, -1, - 184, 848, 850, -1, -1, 849, -1, 53, 849, 36, - 849, -1, 444, 324, -1, 444, 166, -1, 104, 368, - -1, 822, 324, -1, 822, 166, -1, 148, 104, 368, - -1, 148, 181, -1, 148, 428, -1, 148, 273, 298, - -1, -1, 368, 518, 870, 519, -1, 368, 518, 519, - -1, 851, -1, 518, 869, 522, 822, 519, -1, 547, - 528, 822, -1, 853, -1, 854, 522, 853, -1, 854, - -1, 854, 522, -1, 822, 528, 822, -1, 856, -1, - 857, 522, 856, -1, 857, -1, 857, 522, -1, 858, - -1, -1, 38, -1, 399, -1, 30, -1, 8, -1, - 862, -1, 509, -1, 510, -1, 511, -1, 512, -1, - 15, -1, 513, -1, 514, -1, 16, -1, 505, -1, - 506, -1, 507, -1, 19, -1, 20, -1, 21, -1, - 8, -1, 292, 518, 866, 519, -1, 861, -1, 292, - 518, 866, 519, -1, 861, -1, 292, 518, 866, 519, - -1, 237, -1, 502, 237, -1, 177, -1, 502, 177, - -1, 194, -1, 502, 194, -1, 861, -1, 546, 520, - 866, -1, 824, -1, 867, 522, 824, -1, 867, -1, - 867, 522, -1, 822, -1, 869, 522, 822, -1, 869, - -1, 869, 522, -1, 870, -1, -1, 873, -1, 872, - 522, 873, -1, 822, -1, 923, 13, 822, -1, 923, - 14, 822, -1, 786, -1, 874, 522, 786, -1, 876, - 172, 822, -1, -1, 3, -1, 808, -1, 809, -1, - 810, -1, 811, -1, 812, -1, 813, -1, 814, -1, - 815, -1, 816, -1, 817, -1, 818, -1, 819, -1, - 820, -1, 548, -1, 822, 878, 881, 882, -1, 822, - 878, 881, -1, 318, 822, -1, 823, 199, 823, -1, - -1, 822, 881, 882, -1, 822, 882, 881, -1, 822, - 881, -1, 822, 882, -1, 869, -1, -1, 172, 822, - -1, 167, 822, -1, 822, 172, 870, -1, 172, 870, - -1, 870, -1, 687, -1, 518, 870, 519, -1, 892, - -1, 827, -1, 65, 889, 886, 888, 143, -1, 887, - -1, 886, 887, -1, 476, 822, 427, 822, -1, 139, - 822, -1, -1, 822, -1, -1, 891, -1, 890, 522, - 891, -1, 546, -1, 546, -1, 546, 549, -1, 516, - 822, 517, -1, 516, 893, 528, 893, 517, -1, 516, - 893, 528, 893, 528, 893, 517, -1, 516, 893, 528, - 510, 528, 893, 517, -1, 822, -1, -1, -1, 894, - 550, -1, -1, 518, 519, -1, 518, 872, 519, -1, - 520, 551, 895, -1, 516, 822, 517, -1, 516, 893, - 528, 893, 517, -1, 516, 893, 528, 893, 528, 893, - 517, -1, 516, 893, 528, 510, 528, 893, 517, -1, - -1, 897, 896, -1, 45, -1, -1, 901, -1, -1, - 902, -1, 900, 522, 902, -1, 900, -1, 900, 522, - -1, 822, 40, 924, -1, 822, 3, -1, 822, -1, - 148, 518, 911, 519, -1, 148, 546, -1, 903, -1, - -1, 822, 40, 546, -1, 905, -1, 906, 522, 905, - -1, 906, -1, 906, 522, -1, 355, 518, 907, 519, - -1, 355, 905, -1, -1, 545, -1, 909, 522, 545, - -1, 913, -1, 910, 522, 913, -1, 910, -1, 910, - 522, -1, 911, -1, 518, 911, 519, -1, 547, -1, - 918, -1, 546, 549, -1, 916, -1, 4, -1, 548, - 894, -1, 6, -1, 7, -1, 914, 548, -1, 914, - 518, 872, 710, 709, 519, 548, -1, 790, 548, -1, - 806, 518, 822, 519, 821, -1, 806, 916, 821, -1, - 806, 548, 821, -1, 438, -1, 160, -1, 280, -1, - 9, -1, 3, -1, 996, -1, 1001, -1, 3, -1, - 996, -1, 998, -1, 3, -1, 996, -1, 999, -1, - 546, -1, 546, 921, -1, 520, 551, -1, 921, 520, - 551, -1, 518, 911, 519, -1, -1, 917, -1, 552, - -1, 5, -1, 326, 913, 926, 40, 927, -1, 518, - 874, 519, -1, -1, 686, -1, 555, -1, 667, -1, - 668, -1, 972, -1, 984, -1, 100, 373, 545, 929, - -1, 100, 373, 192, 275, 152, 545, 929, -1, 100, - 295, 355, 373, 545, 929, -1, 929, 930, -1, -1, - 604, -1, 931, -1, 580, -1, 991, -1, 100, 937, - 203, 934, 935, 290, 545, 933, 518, 574, 519, 936, - 779, -1, 100, 937, 203, 934, 192, 275, 152, 633, - 290, 545, 933, 518, 574, 519, 936, 779, -1, 546, - -1, 457, 932, -1, -1, 89, -1, -1, 633, -1, - -1, 480, 619, -1, -1, 448, -1, -1, 32, 419, - 773, 389, 373, 913, -1, 32, 419, 192, 152, 773, - 389, 373, 913, -1, 32, 384, 545, 389, 373, 913, - -1, 32, 384, 192, 152, 545, 389, 373, 913, -1, - 32, 470, 545, 389, 373, 913, -1, 32, 470, 192, - 152, 545, 389, 373, 913, -1, 168, 75, 940, -1, - 75, 940, -1, 546, -1, -1, 84, 290, 943, 545, - 222, 942, -1, 84, 290, 82, 822, 222, 942, -1, - 548, -1, 280, -1, 419, -1, 384, -1, 174, -1, - 246, -1, 246, 419, -1, 470, -1, 108, -1, 203, - -1, 373, -1, 442, -1, 154, 108, 548, 676, -1, - 154, 108, 546, 431, 548, 676, -1, 198, 108, 548, - -1, 153, 949, -1, 153, 953, 947, 949, -1, 153, - 468, 949, -1, 153, 518, 952, 519, 949, -1, 468, - -1, -1, 954, -1, 594, -1, -1, 938, -1, 591, - -1, 533, -1, 990, -1, 939, -1, 668, -1, 993, - -1, 658, -1, 928, -1, 580, -1, 604, -1, 576, - -1, 544, -1, 972, -1, 652, -1, 587, -1, 931, - -1, 555, -1, 963, -1, 579, -1, 925, -1, 553, - -1, 686, -1, 600, -1, 667, -1, 586, -1, 967, - -1, 981, -1, 957, -1, 984, -1, 991, -1, 3, - -1, 996, -1, 1000, -1, 950, -1, 548, -1, 955, - -1, 952, 522, 955, -1, 35, -1, 34, -1, 438, - -1, 160, -1, 290, -1, 951, -1, 956, 948, -1, - 950, -1, 953, -1, 389, 958, -1, 389, 241, 958, - -1, 389, 388, 958, -1, 389, 178, 958, -1, 389, - 465, 958, -1, 959, -1, 988, 172, 104, -1, 429, - 501, 961, -1, 373, 548, -1, 988, 431, 962, -1, - 988, 507, 962, -1, 822, -1, 548, -1, 3, -1, - 806, 548, 821, -1, 806, 518, 916, 519, 548, -1, - 594, -1, 117, -1, 241, -1, 960, -1, 962, 522, - 960, -1, 240, 965, -1, 964, 214, 965, 966, -1, - 964, 214, 965, 172, 546, 966, -1, 964, 214, 965, - 172, 548, 966, -1, -1, 168, -1, 548, -1, 546, - -1, -1, 469, 548, -1, 469, 546, -1, 458, 969, - 971, 947, -1, 458, 969, 971, 947, 545, 922, -1, - 458, 969, 971, 947, 976, -1, 458, 518, 970, 519, - -1, 458, 518, 970, 519, 545, 922, -1, 953, -1, - 468, -1, 171, -1, 173, -1, 3, -1, 173, -1, - -1, 968, -1, 970, 522, 968, -1, 171, -1, -1, - 560, 122, 172, 973, 975, 974, 566, -1, 439, 704, - 973, -1, 773, -1, 773, 546, -1, 773, 40, 546, - -1, 477, 822, -1, -1, 457, 755, -1, -1, 953, - 947, -1, 953, 947, 545, 922, -1, 47, 979, 548, - 980, 676, -1, 47, 192, 275, 152, 979, 548, 980, - 676, -1, 128, 552, -1, 128, 108, 552, -1, 128, - 108, 192, 152, 552, -1, 108, -1, -1, 40, 546, - -1, -1, 357, 983, -1, 357, 241, 983, -1, 357, - 388, 983, -1, 357, 178, 983, -1, 357, 465, 983, - -1, 988, -1, 30, -1, 982, -1, 429, 501, -1, - 433, 224, 236, -1, 986, 686, -1, 415, 686, -1, - 415, 989, -1, 986, 989, -1, 986, 429, 501, -1, - 986, 433, 224, 236, -1, 986, 30, 987, -1, 986, - -1, 127, -1, 126, -1, 393, -1, 985, -1, 420, - -1, -1, 546, -1, 988, 520, 546, -1, 546, -1, - 989, 520, 546, -1, 61, 831, -1, 100, 650, 470, - 545, 639, 936, 40, 686, 992, -1, 100, 650, 470, - 192, 275, 152, 545, 639, 936, 40, 686, 992, -1, - 100, 295, 355, 650, 470, 545, 639, 936, 40, 686, - 992, -1, 100, 650, 345, 470, 545, 518, 643, 519, - 936, 40, 686, 992, -1, 100, 295, 355, 650, 345, - 470, 545, 518, 643, 519, 936, 40, 686, 992, -1, - 480, 74, 293, -1, 480, 64, 74, 293, -1, 480, - 241, 74, 293, -1, -1, 100, 650, 419, 995, 40, - 686, 994, -1, 100, 650, 419, 192, 275, 152, 995, - 40, 686, 994, -1, 100, 295, 355, 650, 419, 995, - 40, 686, 994, -1, 480, 107, -1, 480, 273, 107, - -1, -1, 545, 639, 626, 618, -1, 22, -1, 23, - -1, 24, -1, 25, -1, 26, -1, 27, -1, 28, - -1, 29, -1, 31, -1, 32, -1, 33, -1, 43, - -1, 44, -1, 46, -1, 47, -1, 48, -1, 50, - -1, 51, -1, 52, -1, 59, -1, 60, -1, 61, - -1, 62, -1, 63, -1, 64, -1, 67, -1, 68, - -1, 69, -1, 70, -1, 73, -1, 75, -1, 76, - -1, 77, -1, 78, -1, 84, -1, 85, -1, 86, - -1, 87, -1, 88, -1, 90, -1, 91, -1, 92, - -1, 94, -1, 95, -1, 96, -1, 97, -1, 98, - -1, 99, -1, 102, -1, 103, -1, 104, -1, 105, - -1, 106, -1, 107, -1, 108, -1, 109, -1, 110, - -1, 111, -1, 113, -1, 114, -1, 116, -1, 118, - -1, 120, -1, 121, -1, 122, -1, 123, -1, 124, - -1, 125, -1, 128, -1, 129, -1, 130, -1, 131, - -1, 134, -1, 135, -1, 136, -1, 137, -1, 138, - -1, 140, -1, 141, -1, 142, -1, 144, -1, 145, - -1, 146, -1, 148, -1, 149, -1, 150, -1, 151, - -1, 153, -1, 154, -1, 155, -1, 156, -1, 157, - -1, 158, -1, 161, -1, 163, -1, 164, -1, 166, - -1, 168, -1, 170, -1, 174, -1, 175, -1, 178, - -1, 180, -1, 184, -1, 185, -1, 187, -1, 188, - -1, 189, -1, 190, -1, 191, -1, 192, -1, 193, - -1, 195, -1, 196, -1, 197, -1, 198, -1, 200, - -1, 201, -1, 202, -1, 203, -1, 204, -1, 205, - -1, 206, -1, 208, -1, 211, -1, 212, -1, 213, - -1, 214, -1, 215, -1, 221, -1, 224, -1, 226, - -1, 227, -1, 228, -1, 229, -1, 230, -1, 231, - -1, 234, -1, 236, -1, 239, -1, 240, -1, 241, - -1, 242, -1, 243, -1, 244, -1, 245, -1, 246, - -1, 248, -1, 249, -1, 250, -1, 251, -1, 252, - -1, 253, -1, 254, -1, 255, -1, 256, -1, 257, - -1, 258, -1, 259, -1, 260, -1, 261, -1, 262, - -1, 263, -1, 264, -1, 265, -1, 266, -1, 267, - -1, 271, -1, 272, -1, 273, -1, 276, -1, 277, - -1, 279, -1, 282, -1, 284, -1, 285, -1, 286, - -1, 288, -1, 289, -1, 292, -1, 293, -1, 294, - -1, 297, -1, 298, -1, 301, -1, 304, -1, 305, - -1, 306, -1, 307, -1, 308, -1, 309, -1, 310, - -1, 311, -1, 312, -1, 313, -1, 314, -1, 319, - -1, 320, -1, 323, -1, 324, -1, 326, -1, 327, - -1, 328, -1, 330, -1, 331, -1, 332, -1, 333, - -1, 334, -1, 335, -1, 337, -1, 338, -1, 339, - -1, 340, -1, 341, -1, 343, -1, 344, -1, 345, - -1, 346, -1, 348, -1, 349, -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, 365, -1, 366, -1, 367, -1, 369, - -1, 370, -1, 371, -1, 372, -1, 373, -1, 374, - -1, 375, -1, 376, -1, 377, -1, 378, -1, 379, - -1, 380, -1, 381, -1, 384, -1, 385, -1, 386, - -1, 387, -1, 388, -1, 389, -1, 391, -1, 392, - -1, 395, -1, 396, -1, 398, -1, 400, -1, 401, - -1, 402, -1, 403, -1, 404, -1, 405, -1, 406, - -1, 407, -1, 408, -1, 409, -1, 410, -1, 411, - -1, 413, -1, 417, -1, 418, -1, 420, -1, 422, - -1, 423, -1, 424, -1, 425, -1, 426, -1, 428, - -1, 433, -1, 434, -1, 436, -1, 439, -1, 440, - -1, 442, -1, 443, -1, 444, -1, 445, -1, 446, - -1, 449, -1, 450, -1, 451, -1, 453, -1, 454, - -1, 455, -1, 456, -1, 458, -1, 459, -1, 460, - -1, 461, -1, 462, -1, 465, -1, 467, -1, 469, - -1, 470, -1, 471, -1, 472, -1, 473, -1, 474, - -1, 475, -1, 478, -1, 481, -1, 482, -1, 483, - -1, 484, -1, 485, -1, 486, -1, 498, -1, 499, - -1, 500, -1, 501, -1, 53, -1, 54, -1, 56, - -1, 57, -1, 71, -1, 72, -1, 79, -1, 83, - -1, 112, -1, 115, -1, 152, -1, 159, -1, 165, - -1, 176, -1, 182, -1, 183, -1, 210, -1, 216, - -1, 217, -1, 219, -1, 247, -1, 268, -1, 270, - -1, 274, -1, 281, -1, 283, -1, 299, -1, 303, - -1, 321, -1, 325, -1, 342, -1, 368, -1, 390, - -1, 397, -1, 412, -1, 414, -1, 429, -1, 430, - -1, 435, -1, 437, -1, 441, -1, 463, -1, 464, - -1, 487, -1, 488, -1, 489, -1, 490, -1, 491, - -1, 492, -1, 493, -1, 494, -1, 495, -1, 496, - -1, 497, -1, 42, -1, 49, -1, 55, -1, 81, - -1, 89, -1, 101, -1, 171, -1, 173, -1, 176, - -1, 177, -1, 194, -1, 209, -1, 222, -1, 223, - -1, 225, -1, 235, -1, 237, -1, 247, -1, 269, - -1, 278, -1, 300, -1, 302, -1, 322, -1, 364, - -1, 394, -1, 412, -1, 421, -1, 468, -1, 37, - -1, 42, -1, 49, -1, 55, -1, 81, -1, 83, - -1, 89, -1, 101, -1, 171, -1, 173, -1, 177, - -1, 194, -1, 209, -1, 222, -1, 223, -1, 225, - -1, 235, -1, 237, -1, 269, -1, 278, -1, 300, - -1, 302, -1, 322, -1, 364, -1, 383, -1, 394, - -1, 421, -1, 441, -1, 468, -1, 37, -1, 42, - -1, 49, -1, 53, -1, 54, -1, 55, -1, 56, - -1, 57, -1, 72, -1, 71, -1, 79, -1, 81, - -1, 83, -1, 89, -1, 101, -1, 112, -1, 115, - -1, 152, -1, 159, -1, 165, -1, 171, -1, 173, - -1, 176, -1, 177, -1, 182, -1, 183, -1, 194, - -1, 209, -1, 210, -1, 217, -1, 219, -1, 216, - -1, 222, -1, 223, -1, 225, -1, 235, -1, 237, - -1, 247, -1, 268, -1, 269, -1, 270, -1, 274, - -1, 278, -1, 281, -1, 283, -1, 300, -1, 299, - -1, 302, -1, 303, -1, 321, -1, 322, -1, 325, - -1, 342, -1, 364, -1, 368, -1, 383, -1, 390, - -1, 394, -1, 397, -1, 412, -1, 414, -1, 421, - -1, 429, -1, 430, -1, 435, -1, 437, -1, 441, - -1, 463, -1, 464, -1, 468, -1, 487, -1, 488, - -1, 489, -1, 490, -1, 491, -1, 492, -1, 493, - -1, 494, -1, 495, -1, 496, -1, 497, -1, 37, - -1, 42, -1, 49, -1, 55, -1, 81, -1, 83, - -1, 89, -1, 101, -1, 171, -1, 173, -1, 176, - -1, 177, -1, 194, -1, 209, -1, 222, -1, 223, - -1, 225, -1, 235, -1, 237, -1, 247, -1, 269, - -1, 278, -1, 300, -1, 302, -1, 322, -1, 364, - -1, 383, -1, 394, -1, 412, -1, 421, -1, 441, - -1, 468, -1, 30, -1, 34, -1, 35, -1, 36, - -1, 38, -1, 39, -1, 40, -1, 41, -1, 45, - -1, 58, -1, 65, -1, 66, -1, 74, -1, 80, - -1, 82, -1, 93, -1, 100, -1, 117, -1, 119, - -1, 126, -1, 127, -1, 132, -1, 133, -1, 139, - -1, 143, -1, 147, -1, 160, -1, 162, -1, 167, - -1, 169, -1, 172, -1, 179, -1, 181, -1, 186, - -1, 199, -1, 207, -1, 218, -1, 220, -1, 232, - -1, 233, -1, 238, -1, 275, -1, 280, -1, 287, - -1, 290, -1, 291, -1, 295, -1, 296, -1, 315, - -1, 316, -1, 317, -1, 318, -1, 329, -1, 336, - -1, 347, -1, 361, -1, 382, -1, 393, -1, 399, - -1, 415, -1, 416, -1, 419, -1, 427, -1, 431, - -1, 432, -1, 438, -1, 447, -1, 448, -1, 452, - -1, 457, -1, 466, -1, 476, -1, 477, -1, 479, - -1, 480, -1 + -1, 548, -1, 822, 878, 881, 882, -1, 822, 878, + 881, -1, 318, 822, -1, 823, 199, 823, -1, -1, + 822, 881, 882, -1, 822, 882, 881, -1, 822, 881, + -1, 822, 882, -1, 869, -1, -1, 172, 822, -1, + 167, 822, -1, 822, 172, 870, -1, 172, 870, -1, + 870, -1, 687, -1, 518, 870, 519, -1, 892, -1, + 827, -1, 65, 889, 886, 888, 143, -1, 887, -1, + 886, 887, -1, 476, 822, 427, 822, -1, 139, 822, + -1, -1, 822, -1, -1, 891, -1, 890, 522, 891, + -1, 546, -1, 546, -1, 546, 549, -1, 516, 822, + 517, -1, 516, 893, 528, 893, 517, -1, 516, 893, + 528, 893, 528, 893, 517, -1, 516, 893, 528, 510, + 528, 893, 517, -1, 822, -1, -1, -1, 894, 550, + -1, -1, 518, 519, -1, 518, 872, 519, -1, 520, + 551, 895, -1, 516, 822, 517, -1, 516, 893, 528, + 893, 517, -1, 516, 893, 528, 893, 528, 893, 517, + -1, 516, 893, 528, 510, 528, 893, 517, -1, -1, + 897, 896, -1, 45, -1, -1, 901, -1, -1, 902, + -1, 900, 522, 902, -1, 900, -1, 900, 522, -1, + 822, 40, 924, -1, 822, 3, -1, 822, -1, 148, + 518, 911, 519, -1, 148, 546, -1, 903, -1, -1, + 822, 40, 546, -1, 905, -1, 906, 522, 905, -1, + 906, -1, 906, 522, -1, 355, 518, 907, 519, -1, + 355, 905, -1, -1, 545, -1, 909, 522, 545, -1, + 913, -1, 910, 522, 913, -1, 910, -1, 910, 522, + -1, 911, -1, 518, 911, 519, -1, 547, -1, 918, + -1, 546, 549, -1, 916, -1, 4, -1, 548, 894, + -1, 6, -1, 7, -1, 914, 548, -1, 914, 518, + 872, 710, 709, 519, 548, -1, 790, 548, -1, 806, + 518, 822, 519, 821, -1, 806, 916, 821, -1, 806, + 548, 821, -1, 438, -1, 160, -1, 280, -1, 9, + -1, 3, -1, 996, -1, 1001, -1, 3, -1, 996, + -1, 998, -1, 3, -1, 996, -1, 999, -1, 546, + -1, 546, 921, -1, 520, 551, -1, 921, 520, 551, + -1, 518, 911, 519, -1, -1, 917, -1, 552, -1, + 5, -1, 326, 913, 926, 40, 927, -1, 518, 874, + 519, -1, -1, 686, -1, 555, -1, 667, -1, 668, + -1, 972, -1, 984, -1, 100, 373, 545, 929, -1, + 100, 373, 192, 275, 152, 545, 929, -1, 100, 295, + 355, 373, 545, 929, -1, 929, 930, -1, -1, 604, + -1, 931, -1, 580, -1, 991, -1, 100, 937, 203, + 934, 935, 290, 545, 933, 518, 574, 519, 936, 779, + -1, 100, 937, 203, 934, 192, 275, 152, 633, 290, + 545, 933, 518, 574, 519, 936, 779, -1, 546, -1, + 457, 932, -1, -1, 89, -1, -1, 633, -1, -1, + 480, 619, -1, -1, 448, -1, -1, 32, 419, 773, + 389, 373, 913, -1, 32, 419, 192, 152, 773, 389, + 373, 913, -1, 32, 384, 545, 389, 373, 913, -1, + 32, 384, 192, 152, 545, 389, 373, 913, -1, 32, + 470, 545, 389, 373, 913, -1, 32, 470, 192, 152, + 545, 389, 373, 913, -1, 168, 75, 940, -1, 75, + 940, -1, 546, -1, -1, 84, 290, 943, 545, 222, + 942, -1, 84, 290, 82, 822, 222, 942, -1, 548, + -1, 280, -1, 419, -1, 384, -1, 174, -1, 246, + -1, 246, 419, -1, 470, -1, 108, -1, 203, -1, + 373, -1, 442, -1, 154, 108, 548, 676, -1, 154, + 108, 546, 431, 548, 676, -1, 198, 108, 548, -1, + 153, 949, -1, 153, 953, 947, 949, -1, 153, 468, + 949, -1, 153, 518, 952, 519, 949, -1, 468, -1, + -1, 954, -1, 594, -1, -1, 938, -1, 591, -1, + 533, -1, 990, -1, 939, -1, 668, -1, 993, -1, + 658, -1, 928, -1, 580, -1, 604, -1, 576, -1, + 544, -1, 972, -1, 652, -1, 587, -1, 931, -1, + 555, -1, 963, -1, 579, -1, 925, -1, 553, -1, + 686, -1, 600, -1, 667, -1, 586, -1, 967, -1, + 981, -1, 957, -1, 984, -1, 991, -1, 3, -1, + 996, -1, 1000, -1, 950, -1, 548, -1, 955, -1, + 952, 522, 955, -1, 35, -1, 34, -1, 438, -1, + 160, -1, 290, -1, 951, -1, 956, 948, -1, 950, + -1, 953, -1, 389, 958, -1, 389, 241, 958, -1, + 389, 388, 958, -1, 389, 178, 958, -1, 389, 465, + 958, -1, 959, -1, 988, 172, 104, -1, 429, 501, + 961, -1, 373, 548, -1, 988, 431, 962, -1, 988, + 507, 962, -1, 822, -1, 548, -1, 3, -1, 806, + 548, 821, -1, 806, 518, 916, 519, 548, -1, 594, + -1, 117, -1, 241, -1, 960, -1, 962, 522, 960, + -1, 240, 965, -1, 964, 214, 965, 966, -1, 964, + 214, 965, 172, 546, 966, -1, 964, 214, 965, 172, + 548, 966, -1, -1, 168, -1, 548, -1, 546, -1, + -1, 469, 548, -1, 469, 546, -1, 458, 969, 971, + 947, -1, 458, 969, 971, 947, 545, 922, -1, 458, + 969, 971, 947, 976, -1, 458, 518, 970, 519, -1, + 458, 518, 970, 519, 545, 922, -1, 953, -1, 468, + -1, 171, -1, 173, -1, 3, -1, 173, -1, -1, + 968, -1, 970, 522, 968, -1, 171, -1, -1, 560, + 122, 172, 973, 975, 974, 566, -1, 439, 704, 973, + -1, 773, -1, 773, 546, -1, 773, 40, 546, -1, + 477, 822, -1, -1, 457, 755, -1, -1, 953, 947, + -1, 953, 947, 545, 922, -1, 47, 979, 548, 980, + 676, -1, 47, 192, 275, 152, 979, 548, 980, 676, + -1, 128, 552, -1, 128, 108, 552, -1, 128, 108, + 192, 152, 552, -1, 108, -1, -1, 40, 546, -1, + -1, 357, 983, -1, 357, 241, 983, -1, 357, 388, + 983, -1, 357, 178, 983, -1, 357, 465, 983, -1, + 988, -1, 30, -1, 982, -1, 429, 501, -1, 433, + 224, 236, -1, 986, 686, -1, 415, 686, -1, 415, + 989, -1, 986, 989, -1, 986, 429, 501, -1, 986, + 433, 224, 236, -1, 986, 30, 987, -1, 986, -1, + 127, -1, 126, -1, 393, -1, 985, -1, 420, -1, + -1, 546, -1, 988, 520, 546, -1, 546, -1, 989, + 520, 546, -1, 61, 831, -1, 100, 650, 470, 545, + 639, 936, 40, 686, 992, -1, 100, 650, 470, 192, + 275, 152, 545, 639, 936, 40, 686, 992, -1, 100, + 295, 355, 650, 470, 545, 639, 936, 40, 686, 992, + -1, 100, 650, 345, 470, 545, 518, 643, 519, 936, + 40, 686, 992, -1, 100, 295, 355, 650, 345, 470, + 545, 518, 643, 519, 936, 40, 686, 992, -1, 480, + 74, 293, -1, 480, 64, 74, 293, -1, 480, 241, + 74, 293, -1, -1, 100, 650, 419, 995, 40, 686, + 994, -1, 100, 650, 419, 192, 275, 152, 995, 40, + 686, 994, -1, 100, 295, 355, 650, 419, 995, 40, + 686, 994, -1, 480, 107, -1, 480, 273, 107, -1, + -1, 545, 639, 626, 618, -1, 22, -1, 23, -1, + 24, -1, 25, -1, 26, -1, 27, -1, 28, -1, + 29, -1, 31, -1, 32, -1, 33, -1, 43, -1, + 44, -1, 46, -1, 47, -1, 48, -1, 50, -1, + 51, -1, 52, -1, 59, -1, 60, -1, 61, -1, + 62, -1, 63, -1, 64, -1, 67, -1, 68, -1, + 69, -1, 70, -1, 73, -1, 75, -1, 76, -1, + 77, -1, 78, -1, 84, -1, 85, -1, 86, -1, + 87, -1, 88, -1, 90, -1, 91, -1, 92, -1, + 94, -1, 95, -1, 96, -1, 97, -1, 98, -1, + 99, -1, 102, -1, 103, -1, 104, -1, 105, -1, + 106, -1, 107, -1, 108, -1, 109, -1, 110, -1, + 111, -1, 113, -1, 114, -1, 116, -1, 118, -1, + 120, -1, 121, -1, 122, -1, 123, -1, 124, -1, + 125, -1, 128, -1, 129, -1, 130, -1, 131, -1, + 134, -1, 135, -1, 136, -1, 137, -1, 138, -1, + 140, -1, 141, -1, 142, -1, 144, -1, 145, -1, + 146, -1, 148, -1, 149, -1, 150, -1, 151, -1, + 153, -1, 154, -1, 155, -1, 156, -1, 157, -1, + 158, -1, 161, -1, 163, -1, 164, -1, 166, -1, + 168, -1, 170, -1, 174, -1, 175, -1, 178, -1, + 180, -1, 184, -1, 185, -1, 187, -1, 188, -1, + 189, -1, 190, -1, 191, -1, 192, -1, 193, -1, + 195, -1, 196, -1, 197, -1, 198, -1, 200, -1, + 201, -1, 202, -1, 203, -1, 204, -1, 205, -1, + 206, -1, 208, -1, 211, -1, 212, -1, 213, -1, + 214, -1, 215, -1, 221, -1, 224, -1, 226, -1, + 227, -1, 228, -1, 229, -1, 230, -1, 231, -1, + 234, -1, 236, -1, 239, -1, 240, -1, 241, -1, + 242, -1, 243, -1, 244, -1, 245, -1, 246, -1, + 248, -1, 249, -1, 250, -1, 251, -1, 252, -1, + 253, -1, 254, -1, 255, -1, 256, -1, 257, -1, + 258, -1, 259, -1, 260, -1, 261, -1, 262, -1, + 263, -1, 264, -1, 265, -1, 266, -1, 267, -1, + 271, -1, 272, -1, 273, -1, 276, -1, 277, -1, + 279, -1, 282, -1, 284, -1, 285, -1, 286, -1, + 288, -1, 289, -1, 292, -1, 293, -1, 294, -1, + 297, -1, 298, -1, 301, -1, 304, -1, 305, -1, + 306, -1, 307, -1, 308, -1, 309, -1, 310, -1, + 311, -1, 312, -1, 313, -1, 314, -1, 319, -1, + 320, -1, 323, -1, 324, -1, 326, -1, 327, -1, + 328, -1, 330, -1, 331, -1, 332, -1, 333, -1, + 334, -1, 335, -1, 337, -1, 338, -1, 339, -1, + 340, -1, 341, -1, 343, -1, 344, -1, 345, -1, + 346, -1, 348, -1, 349, -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, 365, -1, 366, -1, 367, -1, 369, -1, + 370, -1, 371, -1, 372, -1, 373, -1, 374, -1, + 375, -1, 376, -1, 377, -1, 378, -1, 379, -1, + 380, -1, 381, -1, 384, -1, 385, -1, 386, -1, + 387, -1, 388, -1, 389, -1, 391, -1, 392, -1, + 395, -1, 396, -1, 398, -1, 400, -1, 401, -1, + 402, -1, 403, -1, 404, -1, 405, -1, 406, -1, + 407, -1, 408, -1, 409, -1, 410, -1, 411, -1, + 413, -1, 417, -1, 418, -1, 420, -1, 422, -1, + 423, -1, 424, -1, 425, -1, 426, -1, 428, -1, + 433, -1, 434, -1, 436, -1, 439, -1, 440, -1, + 442, -1, 443, -1, 444, -1, 445, -1, 446, -1, + 449, -1, 450, -1, 451, -1, 453, -1, 454, -1, + 455, -1, 456, -1, 458, -1, 459, -1, 460, -1, + 461, -1, 462, -1, 465, -1, 467, -1, 469, -1, + 470, -1, 471, -1, 472, -1, 473, -1, 474, -1, + 475, -1, 478, -1, 481, -1, 482, -1, 483, -1, + 484, -1, 485, -1, 486, -1, 498, -1, 499, -1, + 500, -1, 501, -1, 53, -1, 54, -1, 56, -1, + 57, -1, 71, -1, 72, -1, 79, -1, 83, -1, + 112, -1, 115, -1, 152, -1, 159, -1, 165, -1, + 176, -1, 182, -1, 183, -1, 210, -1, 216, -1, + 217, -1, 219, -1, 247, -1, 268, -1, 270, -1, + 274, -1, 281, -1, 283, -1, 299, -1, 303, -1, + 321, -1, 325, -1, 342, -1, 368, -1, 390, -1, + 397, -1, 412, -1, 414, -1, 429, -1, 430, -1, + 435, -1, 437, -1, 441, -1, 463, -1, 464, -1, + 487, -1, 488, -1, 489, -1, 490, -1, 491, -1, + 492, -1, 493, -1, 494, -1, 495, -1, 496, -1, + 497, -1, 42, -1, 49, -1, 55, -1, 81, -1, + 89, -1, 101, -1, 171, -1, 173, -1, 176, -1, + 177, -1, 194, -1, 209, -1, 222, -1, 223, -1, + 225, -1, 235, -1, 237, -1, 247, -1, 269, -1, + 278, -1, 300, -1, 302, -1, 322, -1, 364, -1, + 394, -1, 412, -1, 421, -1, 468, -1, 37, -1, + 42, -1, 49, -1, 55, -1, 81, -1, 83, -1, + 89, -1, 101, -1, 171, -1, 173, -1, 177, -1, + 194, -1, 209, -1, 222, -1, 223, -1, 225, -1, + 235, -1, 237, -1, 269, -1, 278, -1, 300, -1, + 302, -1, 322, -1, 364, -1, 383, -1, 394, -1, + 421, -1, 441, -1, 468, -1, 37, -1, 42, -1, + 49, -1, 53, -1, 54, -1, 55, -1, 56, -1, + 57, -1, 72, -1, 71, -1, 79, -1, 81, -1, + 83, -1, 89, -1, 101, -1, 112, -1, 115, -1, + 152, -1, 159, -1, 165, -1, 171, -1, 173, -1, + 176, -1, 177, -1, 182, -1, 183, -1, 194, -1, + 209, -1, 210, -1, 217, -1, 219, -1, 216, -1, + 222, -1, 223, -1, 225, -1, 235, -1, 237, -1, + 247, -1, 268, -1, 269, -1, 270, -1, 274, -1, + 278, -1, 281, -1, 283, -1, 300, -1, 299, -1, + 302, -1, 303, -1, 321, -1, 322, -1, 325, -1, + 342, -1, 364, -1, 368, -1, 383, -1, 390, -1, + 394, -1, 397, -1, 412, -1, 414, -1, 421, -1, + 429, -1, 430, -1, 435, -1, 437, -1, 441, -1, + 463, -1, 464, -1, 468, -1, 487, -1, 488, -1, + 489, -1, 490, -1, 491, -1, 492, -1, 493, -1, + 494, -1, 495, -1, 496, -1, 497, -1, 37, -1, + 42, -1, 49, -1, 55, -1, 81, -1, 83, -1, + 89, -1, 101, -1, 171, -1, 173, -1, 176, -1, + 177, -1, 194, -1, 209, -1, 222, -1, 223, -1, + 225, -1, 235, -1, 237, -1, 247, -1, 269, -1, + 278, -1, 300, -1, 302, -1, 322, -1, 364, -1, + 383, -1, 394, -1, 412, -1, 421, -1, 441, -1, + 468, -1, 30, -1, 34, -1, 35, -1, 36, -1, + 38, -1, 39, -1, 40, -1, 41, -1, 45, -1, + 58, -1, 65, -1, 66, -1, 74, -1, 80, -1, + 82, -1, 93, -1, 100, -1, 117, -1, 119, -1, + 126, -1, 127, -1, 132, -1, 133, -1, 139, -1, + 143, -1, 147, -1, 160, -1, 162, -1, 167, -1, + 169, -1, 172, -1, 179, -1, 181, -1, 186, -1, + 199, -1, 207, -1, 218, -1, 220, -1, 232, -1, + 233, -1, 238, -1, 275, -1, 280, -1, 287, -1, + 290, -1, 291, -1, 295, -1, 296, -1, 315, -1, + 316, -1, 317, -1, 318, -1, 329, -1, 336, -1, + 347, -1, 361, -1, 382, -1, 393, -1, 399, -1, + 415, -1, 416, -1, 419, -1, 427, -1, 431, -1, + 432, -1, 438, -1, 447, -1, 448, -1, 452, -1, + 457, -1, 466, -1, 476, -1, 477, -1, 479, -1, + 480, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ @@ -2677,87 +2677,87 @@ static const yytype_uint16 yyrline[] = 958, 962, 963, 968, 969, 970, 979, 985, 994, 995, 1008, 1009, 1013, 1014, 1018, 1019, 1025, 1031, 1039, 1048, 1056, 1065, 1074, 1078, 1083, 1094, 1108, 1109, 1112, 1113, - 1114, 1117, 1125, 1134, 1135, 1136, 1137, 1140, 1148, 1157, - 1161, 1168, 1169, 1173, 1182, 1186, 1211, 1215, 1228, 1242, - 1257, 1269, 1282, 1296, 1310, 1323, 1338, 1357, 1363, 1368, - 1374, 1381, 1382, 1390, 1394, 1398, 1404, 1411, 1416, 1417, - 1418, 1419, 1420, 1421, 1425, 1426, 1438, 1439, 1444, 1451, - 1458, 1465, 1497, 1508, 1521, 1526, 1527, 1530, 1531, 1534, - 1535, 1540, 1541, 1546, 1550, 1556, 1577, 1585, 1598, 1601, - 1605, 1605, 1608, 1609, 1611, 1616, 1623, 1628, 1634, 1639, - 1645, 1649, 1656, 1663, 1673, 1674, 1678, 1680, 1683, 1687, - 1688, 1689, 1690, 1691, 1692, 1697, 1717, 1718, 1719, 1720, - 1731, 1745, 1746, 1752, 1757, 1762, 1767, 1772, 1777, 1782, - 1787, 1793, 1799, 1805, 1812, 1834, 1843, 1847, 1855, 1859, - 1867, 1879, 1900, 1904, 1910, 1914, 1927, 1935, 1945, 1947, - 1949, 1951, 1953, 1955, 1960, 1961, 1968, 1977, 1985, 1994, - 2005, 2013, 2014, 2015, 2019, 2019, 2022, 2022, 2025, 2025, - 2028, 2028, 2031, 2031, 2034, 2034, 2037, 2037, 2040, 2040, - 2043, 2043, 2046, 2046, 2049, 2049, 2052, 2052, 2055, 2055, - 2058, 2060, 2062, 2064, 2066, 2068, 2070, 2072, 2074, 2076, - 2078, 2080, 2082, 2084, 2089, 2094, 2100, 2107, 2112, 2118, - 2124, 2155, 2157, 2159, 2167, 2182, 2184, 2186, 2188, 2190, - 2192, 2194, 2196, 2198, 2200, 2202, 2204, 2206, 2208, 2210, - 2212, 2215, 2217, 2219, 2222, 2224, 2226, 2228, 2230, 2235, - 2240, 2247, 2252, 2259, 2264, 2271, 2276, 2284, 2292, 2300, - 2308, 2326, 2334, 2342, 2350, 2358, 2366, 2374, 2378, 2394, - 2402, 2410, 2418, 2426, 2434, 2442, 2446, 2450, 2454, 2458, - 2466, 2474, 2482, 2490, 2510, 2532, 2543, 2550, 2564, 2573, - 2581, 2589, 2609, 2611, 2613, 2615, 2617, 2619, 2621, 2623, - 2625, 2627, 2629, 2631, 2633, 2635, 2637, 2639, 2641, 2643, - 2645, 2647, 2649, 2651, 2655, 2659, 2663, 2677, 2678, 2692, - 2693, 2694, 2705, 2729, 2740, 2750, 2754, 2758, 2765, 2769, - 2776, 2780, 2784, 2788, 2790, 2793, 2796, 2807, 2812, 2819, - 2825, 2831, 2838, 2858, 2862, 2869, 2877, 2885, 2896, 2916, - 2952, 2963, 2964, 2971, 2977, 2979, 2981, 2985, 2994, 2999, - 3006, 3021, 3028, 3032, 3036, 3040, 3044, 3054, 3062, 3071, - 3093, 3094, 3098, 3099, 3100, 3104, 3105, 3112, 3113, 3117, - 3118, 3123, 3131, 3133, 3147, 3150, 3177, 3178, 3181, 3182, - 3190, 3198, 3206, 3215, 3225, 3243, 3289, 3298, 3307, 3316, - 3325, 3337, 3338, 3339, 3340, 3341, 3355, 3356, 3359, 3360, - 3364, 3374, 3375, 3379, 3380, 3384, 3391, 3392, 3397, 3398, - 3403, 3404, 3407, 3408, 3409, 3412, 3413, 3416, 3417, 3418, - 3419, 3420, 3421, 3422, 3423, 3424, 3425, 3426, 3427, 3428, - 3429, 3432, 3434, 3439, 3441, 3446, 3448, 3450, 3452, 3454, - 3456, 3458, 3460, 3474, 3476, 3481, 3485, 3492, 3497, 3503, - 3507, 3514, 3519, 3526, 3531, 3539, 3543, 3549, 3553, 3562, - 3573, 3574, 3578, 3582, 3589, 3590, 3591, 3592, 3593, 3594, - 3595, 3596, 3597, 3598, 3599, 3600, 3601, 3602, 3603, 3613, - 3617, 3624, 3631, 3632, 3648, 3652, 3657, 3661, 3676, 3681, - 3685, 3688, 3691, 3692, 3693, 3696, 3703, 3704, 3705, 3715, - 3729, 3730, 3734, 3745, 3746, 3749, 3750, 3754, 3755, 3758, - 3764, 3768, 3775, 3783, 3791, 3799, 3809, 3810, 3815, 3816, - 3820, 3821, 3822, 3826, 3835, 3843, 3851, 3860, 3875, 3876, - 3881, 3882, 3892, 3893, 3897, 3898, 3902, 3903, 3906, 3922, - 3930, 3940, 3941, 3944, 3945, 3948, 3952, 3953, 3957, 3958, - 3961, 3962, 3963, 3973, 3974, 3978, 3980, 3986, 3987, 3991, - 3992, 3995, 4006, 4009, 4020, 4024, 4028, 4040, 4044, 4053, - 4060, 4098, 4102, 4106, 4110, 4114, 4118, 4122, 4128, 4145, - 4146, 4147, 4150, 4151, 4152, 4155, 4156, 4157, 4160, 4161, - 4164, 4166, 4171, 4172, 4175, 4179, 4180, 7, 18, 19, - 23, 24, 25, 26, 27, 28, 7, 26, 50, 73, - 80, 85, 86, 87, 88, 8, 33, 62, 66, 67, - 72, 73, 78, 79, 83, 84, 89, 90, 7, 16, - 25, 34, 43, 52, 5, 12, 22, 23, 7, 15, - 26, 27, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 7, 19, 33, 9, 16, 26, 33, 44, - 45, 50, 51, 52, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, 86, 87, 91, 92, 93, 98, 99, - 104, 108, 116, 117, 122, 123, 124, 130, 135, 143, - 144, 10, 16, 22, 28, 34, 44, 45, 53, 64, - 76, 84, 95, 101, 105, 109, 124, 131, 132, 133, - 137, 138, 7, 17, 26, 35, 46, 47, 49, 50, - 53, 54, 55, 8, 22, 36, 48, 56, 70, 71, - 72, 73, 74, 87, 88, 93, 94, 98, 99, 7, - 18, 31, 35, 42, 53, 54, 60, 61, 9, 19, - 7, 16, 28, 35, 42, 51, 52, 56, 57, 2, - 7, 12, 17, 22, 31, 38, 48, 49, 56, 3, - 10, 17, 24, 31, 38, 45, 52, 61, 61, 63, - 63, 65, 65, 67, 68, 72, 73, 6, 8, 21, - 34, 47, 65, 87, 88, 89, 90, 11, 24, 37, - 54, 55, 56, 61, 74, 74, 74, 74, 74, 74, + 1114, 1117, 1125, 1135, 1136, 1137, 1140, 1148, 1157, 1161, + 1168, 1169, 1173, 1182, 1186, 1211, 1215, 1228, 1242, 1257, + 1269, 1282, 1296, 1310, 1323, 1338, 1357, 1363, 1368, 1374, + 1381, 1382, 1390, 1394, 1398, 1404, 1411, 1416, 1417, 1418, + 1419, 1420, 1421, 1425, 1426, 1438, 1439, 1444, 1451, 1458, + 1465, 1497, 1508, 1521, 1526, 1527, 1530, 1531, 1534, 1535, + 1540, 1541, 1546, 1550, 1556, 1577, 1585, 1598, 1601, 1605, + 1605, 1608, 1609, 1611, 1616, 1623, 1628, 1634, 1639, 1645, + 1649, 1656, 1663, 1673, 1674, 1678, 1680, 1683, 1687, 1688, + 1689, 1690, 1691, 1692, 1697, 1717, 1718, 1719, 1720, 1731, + 1745, 1746, 1752, 1757, 1762, 1767, 1772, 1777, 1782, 1787, + 1793, 1799, 1805, 1812, 1834, 1843, 1847, 1855, 1859, 1867, + 1879, 1900, 1904, 1910, 1914, 1927, 1935, 1945, 1947, 1949, + 1951, 1953, 1955, 1960, 1961, 1968, 1977, 1985, 1994, 2005, + 2013, 2014, 2015, 2019, 2019, 2022, 2022, 2025, 2025, 2028, + 2028, 2031, 2031, 2034, 2034, 2037, 2037, 2040, 2040, 2043, + 2043, 2046, 2046, 2049, 2049, 2052, 2052, 2055, 2055, 2058, + 2060, 2062, 2064, 2066, 2068, 2070, 2072, 2074, 2076, 2078, + 2080, 2082, 2084, 2089, 2094, 2100, 2107, 2112, 2118, 2124, + 2155, 2157, 2159, 2167, 2182, 2184, 2186, 2188, 2190, 2192, + 2194, 2196, 2198, 2200, 2202, 2204, 2206, 2208, 2210, 2212, + 2215, 2217, 2219, 2222, 2224, 2226, 2228, 2230, 2235, 2240, + 2247, 2252, 2259, 2264, 2271, 2276, 2284, 2292, 2300, 2308, + 2326, 2334, 2342, 2350, 2358, 2366, 2374, 2378, 2394, 2402, + 2410, 2418, 2426, 2434, 2442, 2446, 2450, 2454, 2458, 2466, + 2474, 2482, 2490, 2510, 2532, 2543, 2550, 2564, 2573, 2581, + 2589, 2609, 2611, 2613, 2615, 2617, 2619, 2621, 2623, 2625, + 2627, 2629, 2631, 2633, 2635, 2637, 2639, 2641, 2643, 2645, + 2647, 2649, 2651, 2655, 2659, 2663, 2677, 2678, 2692, 2693, + 2694, 2705, 2729, 2740, 2750, 2754, 2758, 2765, 2769, 2776, + 2780, 2784, 2788, 2790, 2793, 2796, 2807, 2812, 2819, 2825, + 2831, 2838, 2858, 2862, 2869, 2877, 2885, 2896, 2916, 2952, + 2963, 2964, 2971, 2977, 2979, 2981, 2985, 2994, 2999, 3006, + 3021, 3028, 3032, 3036, 3040, 3044, 3054, 3062, 3071, 3093, + 3094, 3098, 3099, 3100, 3104, 3105, 3112, 3113, 3117, 3118, + 3123, 3131, 3133, 3147, 3150, 3177, 3178, 3181, 3182, 3190, + 3198, 3206, 3215, 3225, 3243, 3289, 3298, 3307, 3316, 3325, + 3337, 3338, 3339, 3340, 3341, 3355, 3356, 3359, 3360, 3364, + 3374, 3375, 3379, 3380, 3384, 3391, 3392, 3397, 3398, 3403, + 3404, 3407, 3408, 3409, 3412, 3413, 3416, 3417, 3418, 3419, + 3420, 3421, 3422, 3423, 3424, 3425, 3426, 3427, 3428, 3429, + 3432, 3434, 3439, 3441, 3446, 3448, 3450, 3452, 3454, 3456, + 3458, 3460, 3474, 3476, 3481, 3485, 3492, 3497, 3503, 3507, + 3514, 3519, 3526, 3531, 3539, 3543, 3549, 3553, 3562, 3573, + 3574, 3578, 3582, 3589, 3590, 3591, 3592, 3593, 3594, 3595, + 3596, 3597, 3598, 3599, 3600, 3601, 3602, 3603, 3613, 3617, + 3624, 3631, 3632, 3648, 3652, 3657, 3661, 3676, 3681, 3685, + 3688, 3691, 3692, 3693, 3696, 3703, 3704, 3705, 3715, 3729, + 3730, 3734, 3745, 3746, 3749, 3750, 3754, 3755, 3758, 3764, + 3768, 3775, 3783, 3791, 3799, 3809, 3810, 3815, 3816, 3820, + 3821, 3822, 3826, 3835, 3843, 3851, 3860, 3875, 3876, 3881, + 3882, 3892, 3893, 3897, 3898, 3902, 3903, 3906, 3922, 3930, + 3940, 3941, 3944, 3945, 3948, 3952, 3953, 3957, 3958, 3961, + 3962, 3963, 3973, 3974, 3978, 3980, 3986, 3987, 3991, 3992, + 3995, 4006, 4009, 4020, 4024, 4028, 4040, 4044, 4053, 4060, + 4098, 4102, 4106, 4110, 4114, 4118, 4122, 4128, 4145, 4146, + 4147, 4150, 4151, 4152, 4155, 4156, 4157, 4160, 4161, 4164, + 4166, 4171, 4172, 4175, 4179, 4180, 7, 18, 19, 23, + 24, 25, 26, 27, 28, 7, 26, 50, 73, 80, + 85, 86, 87, 88, 8, 33, 62, 66, 67, 72, + 73, 78, 79, 83, 84, 89, 90, 7, 16, 25, + 34, 43, 52, 5, 12, 22, 23, 7, 15, 26, + 27, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 7, 19, 33, 9, 16, 26, 33, 44, 45, + 50, 51, 52, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 91, 92, 93, 98, 99, 104, + 108, 116, 117, 122, 123, 124, 130, 135, 143, 144, + 10, 16, 22, 28, 34, 44, 45, 53, 64, 76, + 84, 95, 101, 105, 109, 124, 131, 132, 133, 137, + 138, 7, 17, 26, 35, 46, 47, 49, 50, 53, + 54, 55, 8, 22, 36, 48, 56, 70, 71, 72, + 73, 74, 87, 88, 93, 94, 98, 99, 7, 18, + 31, 35, 42, 53, 54, 60, 61, 9, 19, 7, + 16, 28, 35, 42, 51, 52, 56, 57, 2, 7, + 12, 17, 22, 31, 38, 48, 49, 56, 3, 10, + 17, 24, 31, 38, 45, 52, 61, 61, 63, 63, + 65, 65, 67, 68, 72, 73, 6, 8, 21, 34, + 47, 65, 87, 88, 89, 90, 11, 24, 37, 54, + 55, 56, 61, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, @@ -2789,19 +2789,18 @@ static const yytype_uint16 yyrline[] = 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 75, 75, + 74, 74, 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, - 75, 75, 76, 76, 76, 76, 76, 76, 76, 76, - 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 75, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, - 77, 77, 77, 77, 77, 77, 77, 77, 77, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 77, 77, 77, 77, 77, 77, 77, 77, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, @@ -2809,17 +2808,18 @@ static const yytype_uint16 yyrline[] = 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 80, 80, 80, 80, 80, 80, 80, 80, + 79, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80 + 80, 80, 80, 80, 80, 80 }; #endif @@ -3186,87 +3186,87 @@ static const yytype_uint16 yyr1[] = 748, 749, 749, 750, 750, 750, 751, 751, 752, 752, 753, 753, 754, 754, 755, 755, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 757, 757, 758, 758, - 758, 759, 759, 760, 760, 760, 760, 761, 761, 762, - 762, 763, 763, 764, 765, 765, 766, 766, 766, 766, - 766, 766, 766, 766, 766, 766, 766, 767, 767, 767, - 767, 768, 768, 769, 769, 769, 769, 769, 770, 770, - 770, 770, 770, 770, 771, 771, 772, 772, 773, 773, - 773, 773, 774, 774, 775, 776, 776, 777, 777, 778, - 778, 779, 779, 780, 780, 781, 782, 782, 783, 783, - 784, 784, 785, 785, 786, 786, 786, 786, 786, 786, - 786, 786, 786, 786, 787, 787, 788, 788, 788, 789, - 789, 789, 789, 789, 789, 789, 790, 790, 790, 790, - 791, 792, 792, 793, 793, 793, 793, 793, 793, 793, - 793, 793, 793, 793, 794, 794, 795, 795, 796, 796, - 797, 798, 799, 799, 800, 800, 801, 802, 803, 803, - 803, 803, 803, 803, 804, 804, 805, 805, 805, 805, - 806, 807, 807, 807, 808, 808, 809, 809, 810, 810, - 811, 811, 812, 812, 813, 813, 814, 814, 815, 815, - 816, 816, 817, 817, 818, 818, 819, 819, 820, 820, + 758, 759, 759, 760, 760, 760, 761, 761, 762, 762, + 763, 763, 764, 765, 765, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 767, 767, 767, 767, + 768, 768, 769, 769, 769, 769, 769, 770, 770, 770, + 770, 770, 770, 771, 771, 772, 772, 773, 773, 773, + 773, 774, 774, 775, 776, 776, 777, 777, 778, 778, + 779, 779, 780, 780, 781, 782, 782, 783, 783, 784, + 784, 785, 785, 786, 786, 786, 786, 786, 786, 786, + 786, 786, 786, 787, 787, 788, 788, 788, 789, 789, + 789, 789, 789, 789, 789, 790, 790, 790, 790, 791, + 792, 792, 793, 793, 793, 793, 793, 793, 793, 793, + 793, 793, 793, 794, 794, 795, 795, 796, 796, 797, + 798, 799, 799, 800, 800, 801, 802, 803, 803, 803, + 803, 803, 803, 804, 804, 805, 805, 805, 805, 806, + 807, 807, 807, 808, 808, 809, 809, 810, 810, 811, + 811, 812, 812, 813, 813, 814, 814, 815, 815, 816, + 816, 817, 817, 818, 818, 819, 819, 820, 820, 821, 821, 821, 821, 821, 821, 821, 821, 821, 821, 821, 821, 821, 821, 821, 821, 821, 821, 821, 821, 821, - 821, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, - 822, 822, 823, 823, 823, 823, 823, 823, 823, 823, + 822, 822, 822, 822, 822, 822, 822, 822, 822, 822, + 822, 823, 823, 823, 823, 823, 823, 823, 823, 823, 823, 823, 823, 823, 823, 823, 823, 823, 823, 823, - 823, 823, 823, 823, 823, 823, 823, 824, 824, 825, - 825, 825, 825, 825, 825, 826, 826, 826, 827, 827, - 827, 827, 827, 827, 827, 827, 827, 827, 827, 827, - 828, 829, 830, 831, 831, 831, 831, 831, 831, 832, - 832, 833, 833, 834, 834, 834, 834, 834, 834, 834, - 834, 834, 834, 834, 834, 834, 834, 835, 836, 836, - 837, 837, 838, 838, 838, 839, 839, 840, 840, 841, - 841, 842, 843, 843, 843, 844, 845, 845, 846, 846, - 847, 847, 847, 847, 848, 848, 849, 849, 849, 849, - 849, 850, 850, 850, 850, 850, 851, 851, 852, 852, - 853, 854, 854, 855, 855, 856, 857, 857, 858, 858, - 859, 859, 860, 860, 860, 861, 861, 862, 862, 862, + 823, 823, 823, 823, 823, 823, 824, 824, 825, 825, + 825, 825, 825, 825, 826, 826, 826, 827, 827, 827, + 827, 827, 827, 827, 827, 827, 827, 827, 827, 828, + 829, 830, 831, 831, 831, 831, 831, 831, 832, 832, + 833, 833, 834, 834, 834, 834, 834, 834, 834, 834, + 834, 834, 834, 834, 834, 834, 835, 836, 836, 837, + 837, 838, 838, 838, 839, 839, 840, 840, 841, 841, + 842, 843, 843, 843, 844, 845, 845, 846, 846, 847, + 847, 847, 847, 848, 848, 849, 849, 849, 849, 849, + 850, 850, 850, 850, 850, 851, 851, 852, 852, 853, + 854, 854, 855, 855, 856, 857, 857, 858, 858, 859, + 859, 860, 860, 860, 861, 861, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, - 862, 863, 863, 864, 864, 865, 865, 865, 865, 865, - 865, 865, 865, 866, 866, 867, 867, 868, 868, 869, - 869, 870, 870, 871, 871, 872, 872, 873, 873, 873, - 874, 874, 875, 875, 876, 876, 876, 876, 876, 876, - 876, 876, 876, 876, 876, 876, 876, 876, 876, 877, - 877, 878, 879, 879, 880, 880, 880, 880, 880, 880, - 881, 882, 883, 883, 883, 884, 884, 884, 884, 885, - 886, 886, 887, 888, 888, 889, 889, 890, 890, 891, - 892, 892, 550, 550, 550, 550, 893, 893, 894, 894, - 895, 895, 895, 896, 896, 896, 896, 896, 897, 897, - 898, 898, 899, 899, 900, 900, 901, 901, 902, 902, - 902, 903, 903, 904, 904, 905, 906, 906, 907, 907, - 908, 908, 908, 909, 909, 910, 910, 911, 911, 912, - 912, 913, 914, 914, 915, 915, 915, 915, 915, 915, - 915, 915, 915, 915, 915, 915, 915, 915, 916, 917, - 917, 917, 918, 918, 918, 919, 919, 919, 920, 920, - 921, 921, 922, 922, 923, 924, 924, 925, 926, 926, - 927, 927, 927, 927, 927, 927, 928, 928, 928, 929, - 929, 930, 930, 930, 930, 931, 931, 932, 933, 933, - 934, 934, 935, 935, 936, 936, 937, 937, 938, 938, - 938, 938, 938, 938, 939, 939, 940, 940, 941, 941, - 942, 942, 943, 943, 943, 943, 943, 943, 943, 943, - 943, 943, 944, 944, 945, 946, 946, 946, 946, 947, - 947, 948, 948, 948, 949, 949, 949, 949, 949, 949, + 863, 863, 864, 864, 865, 865, 865, 865, 865, 865, + 865, 865, 866, 866, 867, 867, 868, 868, 869, 869, + 870, 870, 871, 871, 872, 872, 873, 873, 873, 874, + 874, 875, 875, 876, 876, 876, 876, 876, 876, 876, + 876, 876, 876, 876, 876, 876, 876, 876, 877, 877, + 878, 879, 879, 880, 880, 880, 880, 880, 880, 881, + 882, 883, 883, 883, 884, 884, 884, 884, 885, 886, + 886, 887, 888, 888, 889, 889, 890, 890, 891, 892, + 892, 550, 550, 550, 550, 893, 893, 894, 894, 895, + 895, 895, 896, 896, 896, 896, 896, 897, 897, 898, + 898, 899, 899, 900, 900, 901, 901, 902, 902, 902, + 903, 903, 904, 904, 905, 906, 906, 907, 907, 908, + 908, 908, 909, 909, 910, 910, 911, 911, 912, 912, + 913, 914, 914, 915, 915, 915, 915, 915, 915, 915, + 915, 915, 915, 915, 915, 915, 915, 916, 917, 917, + 917, 918, 918, 918, 919, 919, 919, 920, 920, 921, + 921, 922, 922, 923, 924, 924, 925, 926, 926, 927, + 927, 927, 927, 927, 927, 928, 928, 928, 929, 929, + 930, 930, 930, 930, 931, 931, 932, 933, 933, 934, + 934, 935, 935, 936, 936, 937, 937, 938, 938, 938, + 938, 938, 938, 939, 939, 940, 940, 941, 941, 942, + 942, 943, 943, 943, 943, 943, 943, 943, 943, 943, + 943, 944, 944, 945, 946, 946, 946, 946, 947, 947, + 948, 948, 948, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, - 949, 949, 949, 949, 949, 950, 950, 950, 951, 951, - 952, 952, 953, 953, 954, 954, 954, 954, 955, 956, - 956, 957, 957, 957, 957, 957, 958, 958, 958, 958, - 959, 959, 960, 961, 961, 961, 961, 961, 961, 961, - 962, 962, 963, 963, 963, 963, 964, 964, 965, 965, - 966, 966, 966, 967, 967, 967, 967, 967, 968, 968, - 968, 968, 968, 969, 969, 970, 970, 971, 971, 972, - 972, 973, 973, 973, 974, 974, 975, 975, 976, 976, - 977, 977, 978, 978, 978, 979, 979, 980, 980, 981, - 981, 981, 981, 981, 982, 982, 983, 983, 983, 984, - 984, 984, 984, 984, 984, 984, 984, 985, 985, 986, - 986, 987, 987, 988, 988, 989, 989, 990, 991, 991, - 991, 991, 991, 992, 992, 992, 992, 993, 993, 993, - 994, 994, 994, 995, 996, 996, 996, 996, 996, 996, + 949, 949, 949, 949, 950, 950, 950, 951, 951, 952, + 952, 953, 953, 954, 954, 954, 954, 955, 956, 956, + 957, 957, 957, 957, 957, 958, 958, 958, 958, 959, + 959, 960, 961, 961, 961, 961, 961, 961, 961, 962, + 962, 963, 963, 963, 963, 964, 964, 965, 965, 966, + 966, 966, 967, 967, 967, 967, 967, 968, 968, 968, + 968, 968, 969, 969, 970, 970, 971, 971, 972, 972, + 973, 973, 973, 974, 974, 975, 975, 976, 976, 977, + 977, 978, 978, 978, 979, 979, 980, 980, 981, 981, + 981, 981, 981, 982, 982, 983, 983, 983, 984, 984, + 984, 984, 984, 984, 984, 984, 985, 985, 986, 986, + 987, 987, 988, 988, 989, 989, 990, 991, 991, 991, + 991, 991, 992, 992, 992, 992, 993, 993, 993, 994, + 994, 994, 995, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, @@ -3298,19 +3298,18 @@ static const yytype_uint16 yyr1[] = 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, - 996, 996, 996, 996, 996, 996, 996, 996, 997, 997, + 996, 996, 996, 996, 996, 996, 996, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, - 997, 997, 998, 998, 998, 998, 998, 998, 998, 998, - 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, + 997, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, + 998, 998, 998, 998, 998, 998, 998, 998, 998, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, - 999, 999, 999, 999, 999, 999, 999, 999, 999, 1000, - 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, + 999, 999, 999, 999, 999, 999, 999, 999, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, @@ -3318,17 +3317,18 @@ static const yytype_uint16 yyr1[] = 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, + 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, - 1001, 1001, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, + 1001, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, - 1002, 1002, 1002, 1002, 1002, 1002, 1002 + 1002, 1002, 1002, 1002, 1002, 1002 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -3407,87 +3407,87 @@ static const yytype_uint8 yyr2[] = 3, 2, 0, 1, 2, 0, 4, 5, 1, 2, 2, 0, 1, 3, 1, 2, 3, 3, 3, 3, 3, 3, 1, 4, 9, 9, 3, 0, 2, 2, - 0, 5, 3, 0, 1, 1, 3, 5, 3, 1, - 2, 1, 3, 5, 1, 2, 3, 4, 5, 4, - 5, 4, 6, 5, 4, 5, 5, 5, 2, 4, - 1, 1, 0, 1, 4, 5, 4, 0, 2, 2, - 2, 1, 1, 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, 1, 0, 2, 3, 5, 6, 2, 3, - 1, 5, 5, 5, 3, 3, 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, + 0, 5, 3, 1, 1, 3, 5, 3, 1, 2, + 1, 3, 5, 1, 2, 3, 4, 5, 4, 5, + 4, 6, 5, 4, 5, 5, 5, 2, 4, 1, + 1, 0, 1, 4, 5, 4, 0, 2, 2, 2, + 1, 1, 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, 1, 0, 2, 3, 5, 6, 2, 3, 1, + 5, 5, 5, 3, 3, 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, 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, + 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, 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, 3, 3, 3, 3, - 4, 3, 4, 3, 4, 5, 6, 6, 7, 6, - 7, 6, 7, 3, 4, 4, 6, 1, 5, 4, - 3, 5, 1, 3, 2, 2, 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, 3, 3, 3, 3, 4, + 3, 4, 3, 4, 5, 6, 6, 7, 6, 7, + 6, 7, 3, 4, 4, 6, 1, 5, 4, 3, + 5, 1, 3, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 2, 2, 5, 6, 6, 7, 1, 2, 1, - 1, 1, 2, 2, 4, 3, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 2, 4, 2, 2, - 3, 3, 4, 3, 6, 7, 9, 7, 7, 5, - 1, 1, 1, 5, 6, 6, 4, 4, 4, 4, - 6, 5, 5, 5, 4, 6, 4, 1, 7, 9, - 5, 0, 5, 4, 0, 1, 0, 2, 0, 1, - 3, 3, 2, 2, 0, 6, 1, 0, 3, 0, - 3, 3, 3, 0, 1, 4, 2, 2, 2, 2, - 2, 3, 2, 2, 3, 0, 4, 3, 1, 5, - 3, 1, 3, 1, 2, 3, 1, 3, 1, 2, - 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 5, 6, 6, 7, 1, 2, 1, 1, + 1, 2, 2, 4, 3, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 4, 2, 2, 3, + 3, 4, 3, 6, 7, 9, 7, 7, 5, 1, + 1, 1, 5, 6, 6, 4, 4, 4, 4, 6, + 5, 5, 5, 4, 6, 4, 1, 7, 9, 5, + 0, 5, 4, 0, 1, 0, 2, 0, 1, 3, + 3, 2, 2, 0, 6, 1, 0, 3, 0, 3, + 3, 3, 0, 1, 4, 2, 2, 2, 2, 2, + 3, 2, 2, 3, 0, 4, 3, 1, 5, 3, + 1, 3, 1, 2, 3, 1, 3, 1, 2, 1, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 4, 1, 4, 1, 4, 1, 2, 1, - 2, 1, 2, 1, 3, 1, 3, 1, 2, 1, - 3, 1, 2, 1, 0, 1, 3, 1, 3, 3, - 1, 3, 3, 0, 1, 1, 1, 1, 1, 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, 1, 1, 5, - 1, 2, 4, 2, 0, 1, 0, 1, 3, 1, - 1, 2, 3, 5, 7, 7, 1, 0, 0, 2, - 0, 2, 3, 3, 3, 5, 7, 7, 0, 2, - 1, 0, 1, 0, 1, 3, 1, 2, 3, 2, - 1, 4, 2, 1, 0, 3, 1, 3, 1, 2, - 4, 2, 0, 1, 3, 1, 3, 1, 2, 1, - 3, 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, 2, - 2, 3, 3, 0, 1, 1, 1, 5, 3, 0, - 1, 1, 1, 1, 1, 1, 4, 7, 6, 2, - 0, 1, 1, 1, 1, 13, 16, 1, 2, 0, - 1, 0, 1, 0, 2, 0, 1, 0, 6, 8, - 6, 8, 6, 8, 3, 2, 1, 0, 6, 6, - 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, - 1, 1, 4, 6, 3, 2, 4, 3, 5, 1, - 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 4, 1, 4, 1, 4, 1, 2, 1, 2, + 1, 2, 1, 3, 1, 3, 1, 2, 1, 3, + 1, 2, 1, 0, 1, 3, 1, 3, 3, 1, + 3, 3, 0, 1, 1, 1, 1, 1, 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, 1, 1, 5, 1, + 2, 4, 2, 0, 1, 0, 1, 3, 1, 1, + 2, 3, 5, 7, 7, 1, 0, 0, 2, 0, + 2, 3, 3, 3, 5, 7, 7, 0, 2, 1, + 0, 1, 0, 1, 3, 1, 2, 3, 2, 1, + 4, 2, 1, 0, 3, 1, 3, 1, 2, 4, + 2, 0, 1, 3, 1, 3, 1, 2, 1, 3, + 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, 2, 2, + 3, 3, 0, 1, 1, 1, 5, 3, 0, 1, + 1, 1, 1, 1, 1, 4, 7, 6, 2, 0, + 1, 1, 1, 1, 13, 16, 1, 2, 0, 1, + 0, 1, 0, 2, 0, 1, 0, 6, 8, 6, + 8, 6, 8, 3, 2, 1, 0, 6, 6, 1, + 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, + 1, 4, 6, 3, 2, 4, 3, 5, 1, 0, + 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 3, 1, 1, 1, 1, 1, 1, 2, 1, - 1, 2, 3, 3, 3, 3, 1, 3, 3, 2, - 3, 3, 1, 1, 1, 3, 5, 1, 1, 1, - 1, 3, 2, 4, 6, 6, 0, 1, 1, 1, - 0, 2, 2, 4, 6, 5, 4, 6, 1, 1, - 1, 1, 1, 1, 0, 1, 3, 1, 0, 7, - 3, 1, 2, 3, 2, 0, 2, 0, 2, 4, - 5, 8, 2, 3, 5, 1, 0, 2, 0, 2, - 3, 3, 3, 3, 1, 1, 1, 2, 3, 2, - 2, 2, 2, 3, 4, 3, 1, 1, 1, 1, - 1, 1, 0, 1, 3, 1, 3, 2, 9, 12, - 11, 12, 14, 3, 4, 4, 0, 7, 10, 9, - 2, 3, 0, 4, 1, 1, 1, 1, 1, 1, + 3, 1, 1, 1, 1, 1, 1, 2, 1, 1, + 2, 3, 3, 3, 3, 1, 3, 3, 2, 3, + 3, 1, 1, 1, 3, 5, 1, 1, 1, 1, + 3, 2, 4, 6, 6, 0, 1, 1, 1, 0, + 2, 2, 4, 6, 5, 4, 6, 1, 1, 1, + 1, 1, 1, 0, 1, 3, 1, 0, 7, 3, + 1, 2, 3, 2, 0, 2, 0, 2, 4, 5, + 8, 2, 3, 5, 1, 0, 2, 0, 2, 3, + 3, 3, 3, 1, 1, 1, 2, 3, 2, 2, + 2, 2, 3, 4, 3, 1, 1, 1, 1, 1, + 1, 0, 1, 3, 1, 3, 2, 9, 12, 11, + 12, 14, 3, 4, 4, 0, 7, 10, 9, 2, + 3, 0, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -3549,7 +3549,7 @@ static const yytype_uint8 yyr2[] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1 + 1, 1, 1, 1, 1, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -3557,364 +3557,364 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint16 yydefact[] = { - 156, 265, 0, 1413, 1412, 1486, 265, 0, 1347, 0, - 265, 501, 406, 0, 1508, 1507, 0, 208, 265, 0, - 156, 0, 1447, 0, 0, 0, 564, 567, 565, 0, - 0, 0, 265, 604, 0, 1509, 265, 0, 0, 596, - 566, 0, 1464, 0, 0, 0, 0, 0, 2, 4, + 156, 265, 0, 1412, 1411, 1485, 265, 0, 1346, 0, + 265, 501, 406, 0, 1507, 1506, 0, 208, 265, 0, + 156, 0, 1446, 0, 0, 0, 564, 567, 565, 0, + 0, 0, 265, 604, 0, 1508, 265, 0, 0, 596, + 566, 0, 1463, 0, 0, 0, 0, 0, 2, 4, 7, 21, 35, 31, 0, 20, 33, 18, 17, 38, 26, 6, 24, 37, 40, 19, 25, 15, 39, 13, 36, 540, 526, 609, 539, 0, 0, 155, 708, 547, - 34, 16, 30, 5, 11, 12, 28, 29, 27, 1370, + 34, 16, 30, 5, 11, 12, 28, 29, 27, 1369, 43, 32, 0, 41, 22, 8, 9, 23, 42, 44, - 1510, 1506, 10, 45, 14, 264, 263, 257, 0, 0, - 0, 0, 0, 1485, 0, 0, 268, 112, 1534, 1535, - 1536, 1537, 1538, 1539, 1540, 1541, 1542, 1543, 1544, 1912, - 1545, 1546, 1547, 1548, 1549, 1913, 1550, 1551, 1552, 1858, - 1859, 1914, 1860, 1861, 1553, 1554, 1555, 1556, 1557, 1558, - 1559, 1560, 1561, 1562, 1862, 1863, 1563, 1564, 1565, 1566, - 1567, 1864, 1915, 1865, 1568, 1569, 1570, 1571, 1572, 1916, - 1573, 1574, 1575, 1576, 1577, 1578, 1579, 1580, 1581, 1917, - 1582, 1583, 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, - 1866, 1592, 1593, 1867, 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, 1868, 1621, 1622, 1623, 1624, 1625, 1626, 1869, 1627, - 1628, 1629, 1870, 1630, 1631, 1632, 1918, 1919, 1633, 1634, - 1871, 1921, 1635, 1636, 1872, 1873, 1637, 1638, 1639, 1640, - 1641, 1642, 1643, 1644, 1645, 1922, 1646, 1647, 1648, 1649, - 1650, 1651, 1652, 1653, 1654, 1655, 1656, 1657, 1923, 1874, - 1658, 1659, 1660, 1661, 1662, 1875, 1876, 1877, 1663, 1924, - 1925, 1664, 1926, 1665, 1666, 1667, 1668, 1669, 1670, 1671, - 1927, 1672, 1928, 1673, 1674, 1675, 1676, 1677, 1678, 1679, - 1680, 1878, 1681, 1682, 1683, 1684, 1685, 1686, 1687, 1688, - 1689, 1690, 1691, 1692, 1693, 1694, 1695, 1696, 1697, 1698, - 1699, 1700, 1879, 1930, 1880, 1701, 1702, 1703, 1881, 1704, - 1705, 1931, 1706, 1882, 1707, 1883, 1708, 1709, 1710, 1711, - 1712, 1713, 1714, 1715, 1716, 1717, 1884, 1932, 1718, 1933, - 1885, 1719, 1720, 1721, 1722, 1723, 1724, 1725, 1726, 1727, - 1728, 1729, 1730, 1731, 1886, 1934, 1732, 1733, 1887, 1734, - 1735, 1736, 1737, 1738, 1739, 1740, 1741, 1742, 1743, 1744, - 1745, 1746, 1747, 1888, 1748, 1749, 1750, 1751, 1752, 1753, - 1754, 1755, 1756, 1757, 1758, 1759, 1760, 1761, 1762, 1763, - 1764, 1765, 1766, 1935, 1767, 1768, 1769, 1889, 1770, 1771, - 1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, - 1782, 1783, 1784, 1785, 1786, 1787, 1788, 1890, 1789, 1790, - 1936, 1791, 1792, 1891, 1793, 1794, 1795, 1796, 1797, 1798, - 1799, 1800, 1801, 1802, 1803, 1804, 1805, 1892, 1806, 1893, - 1807, 1808, 1809, 1938, 1810, 1811, 1812, 1813, 1814, 1815, - 1894, 1895, 1816, 1817, 1896, 1818, 1897, 1819, 1820, 1898, - 1821, 1822, 1823, 1824, 1825, 1826, 1827, 1828, 1829, 1830, - 1831, 1832, 1833, 1834, 1835, 1836, 1837, 1899, 1900, 1838, - 1839, 1939, 1840, 1841, 1842, 1843, 1844, 1845, 1846, 1847, - 1848, 1849, 1850, 1851, 1852, 1853, 1901, 1902, 1903, 1904, - 1905, 1906, 1907, 1908, 1909, 1910, 1911, 1854, 1855, 1856, - 1857, 0, 1517, 0, 1272, 113, 114, 1294, 112, 1871, - 1878, 1892, 1346, 1345, 113, 0, 260, 500, 0, 0, - 0, 0, 0, 0, 210, 0, 400, 399, 0, 1336, - 405, 0, 0, 0, 116, 108, 1734, 115, 1271, 106, - 122, 2082, 2083, 2084, 2085, 1969, 2086, 2087, 2088, 2089, - 1970, 2090, 1971, 1972, 1973, 1974, 1975, 1976, 2091, 2092, - 2093, 1978, 1977, 2094, 1979, 2095, 1980, 2096, 1981, 1982, - 2097, 2098, 1983, 1588, 1984, 1985, 2099, 2100, 2101, 2102, - 2103, 2104, 2105, 2106, 2107, 1986, 1987, 2108, 2109, 1988, - 2110, 2111, 1989, 2112, 1990, 1991, 1992, 2113, 2114, 1993, - 1994, 2115, 1995, 2116, 2117, 1996, 1997, 2000, 1998, 2118, - 1999, 2119, 2001, 2002, 2003, 2120, 2121, 2004, 2005, 2122, - 2006, 2007, 2008, 2009, 2010, 2123, 2011, 2124, 2012, 2013, - 2125, 2126, 2127, 2128, 2129, 2015, 2014, 2016, 2017, 2130, - 2131, 2132, 2133, 2018, 2019, 2020, 2134, 2135, 2021, 2136, - 2137, 2022, 2023, 2138, 2024, 2025, 2139, 2026, 2027, 2140, - 2028, 2029, 2141, 2142, 2143, 2030, 2144, 2031, 2032, 2145, - 2146, 2033, 2034, 2147, 2035, 2148, 2149, 2150, 2151, 2036, - 2037, 2152, 2038, 2153, 2154, 2155, 2156, 2039, 2040, 2041, - 2042, 2043, 2044, 2045, 2046, 2047, 2048, 2049, 1482, 124, + 1509, 1505, 10, 45, 14, 264, 263, 257, 0, 0, + 0, 0, 0, 1484, 0, 0, 268, 112, 1533, 1534, + 1535, 1536, 1537, 1538, 1539, 1540, 1541, 1542, 1543, 1911, + 1544, 1545, 1546, 1547, 1548, 1912, 1549, 1550, 1551, 1857, + 1858, 1913, 1859, 1860, 1552, 1553, 1554, 1555, 1556, 1557, + 1558, 1559, 1560, 1561, 1861, 1862, 1562, 1563, 1564, 1565, + 1566, 1863, 1914, 1864, 1567, 1568, 1569, 1570, 1571, 1915, + 1572, 1573, 1574, 1575, 1576, 1577, 1578, 1579, 1580, 1916, + 1581, 1582, 1583, 1584, 1585, 1586, 1587, 1588, 1589, 1590, + 1865, 1591, 1592, 1866, 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, 1867, 1620, 1621, 1622, 1623, 1624, 1625, 1868, 1626, + 1627, 1628, 1869, 1629, 1630, 1631, 1917, 1918, 1632, 1633, + 1870, 1920, 1634, 1635, 1871, 1872, 1636, 1637, 1638, 1639, + 1640, 1641, 1642, 1643, 1644, 1921, 1645, 1646, 1647, 1648, + 1649, 1650, 1651, 1652, 1653, 1654, 1655, 1656, 1922, 1873, + 1657, 1658, 1659, 1660, 1661, 1874, 1875, 1876, 1662, 1923, + 1924, 1663, 1925, 1664, 1665, 1666, 1667, 1668, 1669, 1670, + 1926, 1671, 1927, 1672, 1673, 1674, 1675, 1676, 1677, 1678, + 1679, 1877, 1680, 1681, 1682, 1683, 1684, 1685, 1686, 1687, + 1688, 1689, 1690, 1691, 1692, 1693, 1694, 1695, 1696, 1697, + 1698, 1699, 1878, 1929, 1879, 1700, 1701, 1702, 1880, 1703, + 1704, 1930, 1705, 1881, 1706, 1882, 1707, 1708, 1709, 1710, + 1711, 1712, 1713, 1714, 1715, 1716, 1883, 1931, 1717, 1932, + 1884, 1718, 1719, 1720, 1721, 1722, 1723, 1724, 1725, 1726, + 1727, 1728, 1729, 1730, 1885, 1933, 1731, 1732, 1886, 1733, + 1734, 1735, 1736, 1737, 1738, 1739, 1740, 1741, 1742, 1743, + 1744, 1745, 1746, 1887, 1747, 1748, 1749, 1750, 1751, 1752, + 1753, 1754, 1755, 1756, 1757, 1758, 1759, 1760, 1761, 1762, + 1763, 1764, 1765, 1934, 1766, 1767, 1768, 1888, 1769, 1770, + 1771, 1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, + 1781, 1782, 1783, 1784, 1785, 1786, 1787, 1889, 1788, 1789, + 1935, 1790, 1791, 1890, 1792, 1793, 1794, 1795, 1796, 1797, + 1798, 1799, 1800, 1801, 1802, 1803, 1804, 1891, 1805, 1892, + 1806, 1807, 1808, 1937, 1809, 1810, 1811, 1812, 1813, 1814, + 1893, 1894, 1815, 1816, 1895, 1817, 1896, 1818, 1819, 1897, + 1820, 1821, 1822, 1823, 1824, 1825, 1826, 1827, 1828, 1829, + 1830, 1831, 1832, 1833, 1834, 1835, 1836, 1898, 1899, 1837, + 1838, 1938, 1839, 1840, 1841, 1842, 1843, 1844, 1845, 1846, + 1847, 1848, 1849, 1850, 1851, 1852, 1900, 1901, 1902, 1903, + 1904, 1905, 1906, 1907, 1908, 1909, 1910, 1853, 1854, 1855, + 1856, 0, 1516, 0, 1271, 113, 114, 1293, 112, 1870, + 1877, 1891, 1345, 1344, 113, 0, 260, 500, 0, 0, + 0, 0, 0, 0, 210, 0, 400, 399, 0, 1335, + 405, 0, 0, 0, 116, 108, 1733, 115, 1270, 106, + 122, 2081, 2082, 2083, 2084, 1968, 2085, 2086, 2087, 2088, + 1969, 2089, 1970, 1971, 1972, 1973, 1974, 1975, 2090, 2091, + 2092, 1977, 1976, 2093, 1978, 2094, 1979, 2095, 1980, 1981, + 2096, 2097, 1982, 1587, 1983, 1984, 2098, 2099, 2100, 2101, + 2102, 2103, 2104, 2105, 2106, 1985, 1986, 2107, 2108, 1987, + 2109, 2110, 1988, 2111, 1989, 1990, 1991, 2112, 2113, 1992, + 1993, 2114, 1994, 2115, 2116, 1995, 1996, 1999, 1997, 2117, + 1998, 2118, 2000, 2001, 2002, 2119, 2120, 2003, 2004, 2121, + 2005, 2006, 2007, 2008, 2009, 2122, 2010, 2123, 2011, 2012, + 2124, 2125, 2126, 2127, 2128, 2014, 2013, 2015, 2016, 2129, + 2130, 2131, 2132, 2017, 2018, 2019, 2133, 2134, 2020, 2135, + 2136, 2021, 2022, 2137, 2023, 2024, 2138, 2025, 2026, 2139, + 2027, 2028, 2140, 2141, 2142, 2029, 2143, 2030, 2031, 2144, + 2145, 2032, 2033, 2146, 2034, 2147, 2148, 2149, 2150, 2035, + 2036, 2151, 2037, 2152, 2153, 2154, 2155, 2038, 2039, 2040, + 2041, 2042, 2043, 2044, 2045, 2046, 2047, 2048, 1481, 124, 123, 125, 0, 424, 425, 0, 435, 0, 417, 422, 418, 0, 444, 437, 445, 426, 416, 438, 427, 415, 209, 0, 446, 432, 420, 0, 0, 0, 0, 261, - 222, 406, 0, 156, 0, 1376, 1386, 1395, 1391, 1385, - 1393, 1383, 1399, 1389, 1375, 1397, 1384, 1388, 1381, 1398, - 1379, 1396, 1394, 1382, 1390, 1374, 1378, 1365, 1370, 1402, - 1392, 1400, 1387, 1401, 1403, 1377, 1404, 1380, 0, 1347, - 0, 1864, 1915, 1869, 0, 1882, 0, 1885, 1886, 1770, - 1893, 1896, 1897, 1898, 1899, 0, 778, 115, 110, 762, - 0, 542, 712, 722, 762, 767, 1051, 790, 1052, 0, - 117, 1449, 1448, 1442, 195, 1309, 1495, 1635, 1675, 1787, - 1894, 1816, 1838, 1513, 1496, 1489, 1494, 262, 603, 601, - 0, 1243, 1635, 1675, 1774, 1787, 1894, 1838, 1421, 1426, - 0, 268, 1515, 1500, 0, 1501, 115, 548, 595, 0, - 269, 1463, 0, 1468, 0, 1750, 575, 578, 1303, 576, + 222, 406, 0, 156, 0, 1375, 1385, 1394, 1390, 1384, + 1392, 1382, 1398, 1388, 1374, 1396, 1383, 1387, 1380, 1397, + 1378, 1395, 1393, 1381, 1389, 1373, 1377, 1364, 1369, 1401, + 1391, 1399, 1386, 1400, 1402, 1376, 1403, 1379, 0, 1346, + 0, 1863, 1914, 1868, 0, 1881, 0, 1884, 1885, 1769, + 1892, 1895, 1896, 1897, 1898, 0, 777, 115, 110, 761, + 0, 542, 712, 722, 761, 766, 1050, 789, 1051, 0, + 117, 1448, 1447, 1441, 195, 1308, 1494, 1634, 1674, 1786, + 1893, 1815, 1837, 1512, 1495, 1488, 1493, 262, 603, 601, + 0, 1242, 1634, 1674, 1773, 1786, 1893, 1837, 1420, 1425, + 0, 268, 1514, 1499, 0, 1500, 115, 548, 595, 0, + 269, 1462, 0, 1467, 0, 1749, 575, 578, 1302, 576, 540, 0, 0, 1, 156, 0, 162, 0, 599, 599, 0, 599, 0, 532, 0, 0, 540, 535, 539, 709, - 1369, 1478, 0, 1512, 1894, 1816, 1499, 1502, 1644, 0, - 0, 1644, 0, 1644, 0, 1644, 0, 0, 1488, 0, - 258, 1227, 0, 1273, 118, 0, 0, 1358, 1354, 1359, - 1355, 1360, 1353, 1352, 1361, 1357, 0, 0, 0, 371, - 404, 403, 402, 401, 406, 1644, 1320, 0, 206, 462, - 463, 0, 0, 0, 0, 0, 1331, 109, 107, 1644, - 1483, 433, 434, 0, 423, 419, 421, 0, 0, 1644, - 1298, 443, 439, 1644, 443, 1265, 1644, 0, 0, 214, - 0, 399, 1367, 1405, 2036, 1419, 0, 1420, 1410, 1373, - 1406, 1407, 156, 0, 499, 1344, 0, 0, 0, 1173, - 762, 767, 0, 0, 780, 0, 1193, 0, 1199, 0, - 0, 0, 762, 547, 0, 722, 779, 111, 0, 760, - 761, 650, 650, 604, 0, 585, 772, 0, 0, 775, - 773, 0, 775, 0, 0, 0, 775, 771, 730, 0, - 650, 0, 760, 763, 650, 0, 782, 1364, 0, 0, - 0, 0, 1492, 1490, 1491, 1497, 0, 1493, 0, 0, - 1275, 1277, 1278, 1141, 1288, 1029, 0, 1859, 1860, 1861, - 1216, 1862, 1863, 1865, 1866, 1867, 987, 1608, 1868, 1286, - 1870, 1872, 1873, 1875, 1876, 1877, 1878, 1879, 1880, 0, - 1287, 1883, 1713, 1888, 1889, 1891, 1894, 1895, 1285, 1900, - 0, 0, 0, 1254, 1164, 0, 1028, 0, 0, 0, - 1220, 1228, 1021, 0, 0, 826, 827, 848, 849, 828, - 854, 855, 857, 829, 0, 1250, 921, 1017, 1238, 1026, - 1034, 1030, 1031, 1071, 1032, 1050, 1035, 1108, 1027, 0, - 1033, 1019, 1246, 585, 1244, 0, 1020, 1274, 585, 1242, - 1424, 1422, 1429, 1423, 0, 1425, 0, 0, 0, 259, - 0, 111, 1471, 1470, 1462, 1460, 1461, 1459, 1458, 1465, - 0, 1467, 1370, 1159, 1161, 0, 577, 0, 0, 0, - 529, 528, 530, 3, 0, 0, 0, 1625, 0, 597, + 1368, 1477, 0, 1511, 1893, 1815, 1498, 1501, 1643, 0, + 0, 1643, 0, 1643, 0, 1643, 0, 0, 1487, 0, + 258, 1226, 0, 1272, 118, 0, 0, 1357, 1353, 1358, + 1354, 1359, 1352, 1351, 1360, 1356, 0, 0, 0, 371, + 404, 403, 402, 401, 406, 1643, 1319, 0, 206, 462, + 463, 0, 0, 0, 0, 0, 1330, 109, 107, 1643, + 1482, 433, 434, 0, 423, 419, 421, 0, 0, 1643, + 1297, 443, 439, 1643, 443, 1264, 1643, 0, 0, 214, + 0, 399, 1366, 1404, 2035, 1418, 0, 1419, 1409, 1372, + 1405, 1406, 156, 0, 499, 1343, 0, 0, 0, 1172, + 761, 766, 0, 0, 779, 0, 1192, 0, 1198, 0, + 0, 0, 761, 547, 0, 722, 778, 111, 0, 759, + 760, 650, 650, 604, 0, 585, 771, 0, 0, 774, + 772, 0, 774, 0, 0, 0, 774, 770, 730, 0, + 650, 0, 759, 762, 650, 0, 781, 1363, 0, 0, + 0, 0, 1491, 1489, 1490, 1496, 0, 1492, 0, 0, + 1274, 1276, 1277, 1140, 1287, 1028, 0, 1858, 1859, 1860, + 1215, 1861, 1862, 1864, 1865, 1866, 986, 1607, 1867, 1285, + 1869, 1871, 1872, 1874, 1875, 1876, 1877, 1878, 1879, 0, + 1286, 1882, 1712, 1887, 1888, 1890, 1893, 1894, 1284, 1899, + 0, 0, 0, 1253, 1163, 0, 1027, 0, 0, 0, + 1219, 1227, 1020, 0, 0, 825, 826, 847, 848, 827, + 853, 854, 856, 828, 0, 1249, 920, 1016, 1237, 1025, + 1033, 1029, 1030, 1070, 1031, 1049, 1034, 1107, 1026, 0, + 1032, 1018, 1245, 585, 1243, 0, 1019, 1273, 585, 1241, + 1423, 1421, 1428, 1422, 0, 1424, 0, 0, 0, 259, + 0, 111, 1470, 1469, 1461, 1459, 1460, 1458, 1457, 1464, + 0, 1466, 1369, 1158, 1160, 0, 577, 0, 0, 0, + 529, 528, 530, 3, 0, 0, 0, 1624, 0, 597, 598, 0, 0, 0, 0, 0, 0, 0, 0, 693, 624, 625, 627, 690, 694, 702, 0, 0, 0, 0, - 0, 536, 0, 1303, 1450, 1511, 1505, 1503, 0, 0, + 0, 536, 0, 1302, 1449, 1510, 1504, 1502, 0, 0, 0, 140, 140, 0, 0, 0, 0, 0, 100, 49, 93, 0, 0, 0, 0, 236, 249, 0, 0, 0, 0, 0, 246, 0, 0, 229, 51, 223, 225, 0, - 140, 0, 47, 0, 0, 0, 53, 1486, 0, 499, - 266, 267, 1226, 0, 120, 121, 119, 112, 0, 2050, - 1912, 1913, 1914, 1915, 1865, 1916, 1917, 0, 1918, 1919, - 1871, 1921, 1922, 1923, 1924, 1925, 1926, 1927, 1928, 1878, - 1930, 1931, 1932, 1933, 1934, 1935, 2076, 1936, 1892, 1938, - 1898, 0, 1939, 1043, 1167, 609, 1165, 1304, 0, 113, - 1291, 0, 1356, 0, 0, 0, 0, 497, 0, 0, - 0, 0, 1316, 0, 1644, 207, 211, 0, 1644, 202, - 1644, 371, 0, 1644, 371, 1644, 0, 1330, 1333, 0, - 436, 431, 429, 428, 430, 1644, 255, 0, 0, 1299, + 140, 0, 47, 0, 0, 0, 53, 1485, 0, 499, + 266, 267, 1225, 0, 120, 121, 119, 112, 0, 2049, + 1911, 1912, 1913, 1914, 1864, 1915, 1916, 0, 1917, 1918, + 1870, 1920, 1921, 1922, 1923, 1924, 1925, 1926, 1927, 1877, + 1929, 1930, 1931, 1932, 1933, 1934, 2075, 1935, 1891, 1937, + 1897, 0, 1938, 1042, 1166, 609, 1164, 1303, 0, 113, + 1290, 0, 1355, 0, 0, 0, 0, 497, 0, 0, + 0, 0, 1315, 0, 1643, 207, 211, 0, 1643, 202, + 1643, 371, 0, 1643, 371, 1643, 0, 1329, 1332, 0, + 436, 431, 429, 428, 430, 1643, 255, 0, 0, 1298, 441, 442, 0, 410, 0, 0, 412, 0, 0, 219, - 0, 217, 0, 406, 156, 0, 230, 1415, 1416, 1414, - 0, 0, 1409, 1372, 233, 250, 1418, 1408, 1417, 1371, - 1366, 0, 0, 1362, 485, 0, 0, 0, 1174, 897, - 896, 878, 879, 894, 895, 880, 881, 888, 889, 899, - 898, 886, 887, 882, 883, 876, 877, 892, 893, 884, - 885, 890, 891, 874, 875, 1188, 1175, 1176, 1177, 1178, - 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 0, - 0, 721, 719, 0, 0, 0, 0, 0, 0, 1220, - 0, 992, 1027, 0, 0, 0, 1159, 1198, 0, 0, - 0, 0, 0, 0, 1159, 1204, 0, 0, 746, 758, - 0, 643, 649, 720, 718, 0, 1243, 713, 0, 792, - 0, 772, 0, 771, 0, 0, 774, 768, 0, 769, - 0, 0, 0, 0, 770, 0, 0, 0, 0, 0, - 716, 0, 758, 0, 717, 789, 1432, 1440, 196, 0, - 1295, 1940, 1941, 1942, 836, 1943, 865, 843, 865, 865, - 1944, 1945, 1946, 1947, 832, 832, 845, 1948, 1949, 1950, - 1951, 1952, 833, 834, 870, 1953, 1954, 1955, 1956, 1957, - 0, 0, 1958, 865, 1959, 832, 1960, 1961, 1962, 837, - 1963, 800, 1964, 0, 1965, 835, 801, 1966, 873, 873, - 1967, 0, 860, 1968, 0, 1170, 810, 818, 819, 820, - 821, 846, 847, 822, 852, 853, 823, 920, 0, 832, - 1296, 1297, 156, 1498, 1514, 0, 1164, 1036, 864, 851, - 1215, 0, 859, 858, 0, 1164, 841, 840, 839, 1023, - 0, 838, 1121, 865, 865, 863, 946, 842, 0, 0, - 0, 0, 0, 869, 0, 867, 947, 925, 926, 0, - 0, 1253, 1262, 1159, 1163, 0, 1021, 1159, 0, 1038, - 1039, 0, 1111, 1113, 0, 0, 1221, 1276, 1022, 0, - 1281, 0, 0, 920, 920, 1249, 1141, 0, 1131, 1134, - 0, 0, 1138, 1139, 1140, 0, 0, 0, 1241, 0, - 1149, 1151, 0, 0, 962, 1147, 0, 965, 0, 0, - 0, 0, 1135, 1136, 1137, 1127, 1128, 1129, 1130, 1132, - 1133, 1145, 1126, 943, 0, 1018, 0, 1074, 0, 942, - 1247, 711, 0, 1279, 711, 1434, 1438, 1439, 1433, 1437, - 0, 1428, 1427, 1430, 1431, 1516, 0, 1472, 1456, 0, - 1453, 1162, 706, 579, 1267, 0, 583, 1477, 161, 160, + 0, 217, 0, 406, 156, 0, 230, 1414, 1415, 1413, + 0, 0, 1408, 1371, 233, 250, 1417, 1407, 1416, 1370, + 1365, 0, 0, 1361, 485, 0, 0, 0, 1173, 896, + 895, 877, 878, 893, 894, 879, 880, 887, 888, 898, + 897, 885, 886, 881, 882, 875, 876, 891, 892, 883, + 884, 889, 890, 873, 874, 1187, 1174, 1175, 1176, 1177, + 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 0, + 0, 721, 719, 0, 0, 0, 0, 0, 0, 1219, + 0, 991, 1026, 0, 0, 0, 1158, 1197, 0, 0, + 0, 0, 0, 0, 1158, 1203, 0, 0, 745, 757, + 0, 643, 649, 720, 718, 0, 1242, 713, 0, 791, + 0, 771, 0, 770, 0, 0, 773, 767, 0, 768, + 0, 0, 0, 0, 769, 0, 0, 0, 0, 0, + 716, 0, 757, 0, 717, 788, 1431, 1439, 196, 0, + 1294, 1939, 1940, 1941, 835, 1942, 864, 842, 864, 864, + 1943, 1944, 1945, 1946, 831, 831, 844, 1947, 1948, 1949, + 1950, 1951, 832, 833, 869, 1952, 1953, 1954, 1955, 1956, + 0, 0, 1957, 864, 1958, 831, 1959, 1960, 1961, 836, + 1962, 799, 1963, 0, 1964, 834, 800, 1965, 872, 872, + 1966, 0, 859, 1967, 0, 1169, 809, 817, 818, 819, + 820, 845, 846, 821, 851, 852, 822, 919, 0, 831, + 1295, 1296, 156, 1497, 1513, 0, 1163, 1035, 863, 850, + 1214, 0, 858, 857, 0, 1163, 840, 839, 838, 1022, + 0, 837, 1120, 864, 864, 862, 945, 841, 0, 0, + 0, 0, 0, 868, 0, 866, 946, 924, 925, 0, + 0, 1252, 1261, 1158, 1162, 0, 1020, 1158, 0, 1037, + 1038, 0, 1110, 1112, 0, 0, 1220, 1275, 1021, 0, + 1280, 0, 0, 919, 919, 1248, 1140, 0, 1130, 1133, + 0, 0, 1137, 1138, 1139, 0, 0, 0, 1240, 0, + 1148, 1150, 0, 0, 961, 1146, 0, 964, 0, 0, + 0, 0, 1134, 1135, 1136, 1126, 1127, 1128, 1129, 1131, + 1132, 1144, 1125, 942, 0, 1017, 0, 1073, 0, 941, + 1246, 711, 0, 1278, 711, 1433, 1437, 1438, 1432, 1436, + 0, 1427, 1426, 1429, 1430, 1515, 0, 1471, 1455, 0, + 1452, 1161, 706, 579, 1266, 0, 583, 1476, 161, 160, 0, 213, 0, 552, 551, 618, 610, 612, 618, 0, 550, 0, 666, 667, 0, 0, 0, 0, 699, 697, - 1275, 1288, 654, 628, 653, 0, 0, 632, 0, 658, - 921, 692, 534, 622, 623, 626, 533, 0, 695, 0, + 1274, 1287, 654, 628, 653, 0, 0, 632, 0, 658, + 920, 692, 534, 622, 623, 626, 533, 0, 695, 0, 705, 0, 571, 573, 556, 570, 568, 553, 561, 693, - 627, 0, 1479, 0, 0, 1443, 1504, 0, 0, 0, - 0, 0, 1644, 0, 0, 803, 84, 65, 323, 139, + 627, 0, 1478, 0, 0, 1442, 1503, 0, 0, 0, + 0, 0, 1643, 0, 0, 802, 84, 65, 323, 139, 0, 0, 0, 0, 0, 0, 0, 92, 89, 90, - 91, 0, 0, 0, 0, 1295, 234, 235, 248, 0, + 91, 0, 0, 0, 0, 1294, 234, 235, 248, 0, 239, 240, 237, 241, 242, 0, 0, 227, 228, 0, 0, 0, 0, 226, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1487, 1480, 1222, 1227, 609, 609, 609, + 0, 0, 0, 1486, 1479, 1221, 1226, 609, 609, 609, 0, 607, 608, 0, 0, 0, 0, 0, 484, 369, - 379, 0, 0, 0, 1320, 206, 0, 0, 0, 0, - 0, 0, 406, 1323, 1321, 1319, 1322, 1324, 1614, 190, + 379, 0, 0, 0, 1319, 206, 0, 0, 0, 0, + 0, 0, 406, 1322, 1320, 1318, 1321, 1323, 1613, 190, 0, 0, 0, 0, 0, 198, 201, 0, 368, 342, - 0, 0, 1335, 0, 0, 457, 455, 458, 447, 460, - 450, 0, 1644, 358, 1332, 0, 1484, 0, 0, 253, - 443, 1300, 0, 440, 443, 1266, 0, 443, 221, 0, - 0, 1368, 1411, 231, 251, 232, 252, 499, 494, 524, + 0, 0, 1334, 0, 0, 457, 455, 458, 447, 460, + 450, 0, 1643, 358, 1331, 0, 1483, 0, 0, 253, + 443, 1299, 0, 440, 443, 1265, 0, 443, 221, 0, + 0, 1367, 1410, 231, 251, 232, 252, 499, 494, 524, 0, 502, 507, 482, 0, 482, 0, 504, 508, 482, - 503, 0, 482, 498, 0, 1066, 0, 1056, 0, 0, - 781, 0, 0, 1057, 994, 995, 0, 0, 0, 0, + 503, 0, 482, 498, 0, 1065, 0, 1055, 0, 0, + 780, 0, 0, 1056, 993, 994, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1012, 1011, 1058, 785, 0, 788, - 0, 0, 1196, 1197, 0, 1059, 0, 0, 1203, 0, - 0, 0, 1064, 0, 723, 0, 0, 0, 638, 642, - 645, 0, 648, 585, 541, 1635, 1675, 0, 596, 596, - 596, 594, 584, 0, 670, 0, 0, 0, 747, 0, - 0, 749, 751, 0, 0, 754, 0, 729, 728, 0, - 0, 0, 0, 793, 0, 1271, 0, 0, 197, 0, - 0, 0, 818, 0, 0, 0, 808, 804, 0, 900, - 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, - 911, 912, 824, 1308, 0, 830, 1311, 0, 1312, 1313, - 1310, 1307, 1314, 1315, 0, 0, 0, 0, 1214, 1210, - 0, 0, 0, 0, 1116, 1118, 1120, 0, 862, 861, - 1125, 1131, 1134, 1138, 1139, 1140, 1135, 1136, 1137, 1127, - 1128, 1129, 1130, 1132, 1133, 0, 1153, 0, 1107, 0, - 0, 0, 0, 0, 0, 0, 1252, 0, 990, 0, - 1040, 1025, 0, 0, 1114, 1041, 1254, 1229, 0, 0, - 0, 1284, 1283, 922, 931, 934, 966, 967, 938, 939, - 940, 944, 1306, 1305, 1248, 0, 1240, 0, 0, 923, - 948, 953, 0, 1205, 1208, 983, 1207, 0, 971, 0, - 961, 0, 969, 973, 949, 964, 0, 945, 0, 1241, - 1150, 1152, 0, 1148, 0, 935, 936, 937, 927, 928, - 929, 930, 932, 933, 941, 1124, 1122, 1123, 0, 1227, - 0, 1239, 0, 0, 1076, 0, 0, 968, 1245, 0, - 792, 609, 792, 0, 920, 1473, 1303, 1466, 1303, 1455, - 1160, 1268, 1302, 581, 0, 0, 0, 1475, 147, 151, - 0, 1228, 181, 183, 711, 0, 616, 617, 621, 0, - 0, 621, 600, 549, 1889, 1770, 0, 0, 0, 0, - 659, 700, 0, 691, 656, 657, 0, 655, 1275, 660, - 1274, 661, 664, 665, 633, 1263, 701, 703, 0, 696, - 0, 1269, 555, 574, 0, 0, 0, 0, 0, 538, - 537, 707, 1450, 1450, 1452, 1451, 0, 50, 0, 1644, + 0, 0, 0, 0, 1011, 1010, 1057, 784, 0, 787, + 0, 0, 1195, 1196, 0, 1058, 0, 0, 1202, 0, + 0, 0, 1063, 0, 723, 0, 0, 0, 638, 642, + 645, 0, 648, 585, 541, 1634, 1674, 0, 596, 596, + 596, 594, 584, 0, 670, 0, 0, 0, 746, 0, + 0, 748, 750, 0, 0, 753, 0, 729, 728, 0, + 0, 0, 0, 792, 0, 1270, 0, 0, 197, 0, + 0, 0, 817, 0, 0, 0, 807, 803, 0, 899, + 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, + 910, 911, 823, 1307, 0, 829, 1310, 0, 1311, 1312, + 1309, 1306, 1313, 1314, 0, 0, 0, 0, 1213, 1209, + 0, 0, 0, 0, 1115, 1117, 1119, 0, 861, 860, + 1124, 1130, 1133, 1137, 1138, 1139, 1134, 1135, 1136, 1126, + 1127, 1128, 1129, 1131, 1132, 0, 1152, 0, 1106, 0, + 0, 0, 0, 0, 0, 0, 1251, 0, 989, 0, + 1039, 1024, 0, 0, 1113, 1040, 1253, 1228, 0, 0, + 0, 1283, 1282, 921, 930, 933, 965, 966, 937, 938, + 939, 943, 1305, 1304, 1247, 0, 1239, 0, 0, 922, + 947, 952, 0, 1204, 1207, 982, 1206, 0, 970, 0, + 960, 0, 968, 972, 948, 963, 0, 944, 0, 1240, + 1149, 1151, 0, 1147, 0, 934, 935, 936, 926, 927, + 928, 929, 931, 932, 940, 1123, 1121, 1122, 0, 1226, + 0, 1238, 0, 0, 1075, 0, 0, 967, 1244, 0, + 791, 609, 791, 0, 919, 1472, 1302, 1465, 1302, 1454, + 1159, 1267, 1301, 581, 0, 0, 0, 1474, 147, 151, + 0, 1227, 181, 183, 711, 0, 616, 617, 621, 0, + 0, 621, 600, 549, 1888, 1769, 0, 0, 0, 0, + 659, 700, 0, 691, 656, 657, 0, 655, 1274, 660, + 1273, 661, 664, 665, 633, 1262, 701, 703, 0, 696, + 0, 1268, 555, 574, 0, 0, 0, 0, 0, 538, + 537, 707, 1449, 1449, 1451, 1450, 0, 50, 0, 1643, 67, 0, 0, 0, 0, 0, 0, 273, 0, 373, - 273, 105, 1644, 443, 1644, 443, 1538, 1609, 1788, 0, + 273, 105, 1643, 443, 1643, 443, 1537, 1608, 1787, 0, 63, 347, 96, 0, 133, 376, 0, 332, 86, 101, 126, 0, 0, 52, 224, 238, 243, 129, 247, 244, - 1340, 245, 140, 0, 48, 0, 127, 0, 1338, 0, - 0, 54, 131, 1342, 1488, 0, 1226, 0, 607, 607, - 607, 0, 1166, 0, 0, 0, 1168, 1169, 961, 1350, - 1349, 1351, 1348, 470, 483, 0, 370, 0, 496, 473, - 474, 484, 1318, 211, 0, 202, 371, 0, 371, 0, - 1320, 0, 0, 192, 188, 206, 212, 0, 0, 0, + 1339, 245, 140, 0, 48, 0, 127, 0, 1337, 0, + 0, 54, 131, 1341, 1487, 0, 1225, 0, 607, 607, + 607, 0, 1165, 0, 0, 0, 1167, 1168, 960, 1349, + 1348, 1350, 1347, 470, 483, 0, 370, 0, 496, 473, + 474, 484, 1317, 211, 0, 202, 371, 0, 371, 0, + 1319, 0, 0, 192, 188, 206, 212, 0, 0, 0, 0, 0, 369, 361, 359, 392, 0, 366, 360, 0, - 0, 318, 0, 1532, 0, 0, 0, 0, 464, 0, - 0, 0, 0, 0, 0, 255, 256, 409, 1301, 411, - 0, 413, 220, 218, 1363, 2006, 490, 1164, 0, 488, + 0, 318, 0, 1531, 0, 0, 0, 0, 464, 0, + 0, 0, 0, 0, 0, 255, 256, 409, 1300, 411, + 0, 413, 220, 218, 1362, 2005, 490, 1163, 0, 488, 495, 489, 492, 493, 487, 486, 0, 481, 0, 517, - 0, 0, 0, 0, 0, 0, 0, 0, 1053, 1172, - 0, 1191, 1190, 993, 1000, 1003, 1007, 1008, 1009, 1192, - 0, 0, 0, 1004, 1005, 1006, 996, 997, 998, 999, - 1001, 1002, 1010, 790, 0, 0, 784, 1201, 1200, 1194, - 1195, 0, 1061, 1062, 1063, 1202, 0, 0, 759, 636, - 634, 637, 639, 635, 0, 0, 792, 596, 596, 596, - 596, 593, 0, 0, 0, 791, 0, 687, 755, 753, - 0, 777, 0, 750, 733, 756, 0, 741, 0, 748, - 797, 764, 0, 0, 766, 1441, 814, 0, 809, 805, - 0, 0, 0, 815, 0, 0, 0, 0, 0, 0, - 0, 1171, 0, 602, 1037, 0, 0, 0, 1211, 0, - 989, 831, 844, 0, 1119, 1042, 0, 1142, 1106, 872, - 871, 873, 873, 0, 0, 0, 0, 1261, 1219, 0, - 1067, 1217, 1160, 1110, 1112, 1262, 1024, 856, 920, 0, - 0, 0, 0, 0, 0, 0, 972, 963, 0, 970, - 974, 0, 0, 0, 957, 0, 0, 955, 984, 951, - 0, 0, 985, 1226, 0, 1230, 0, 0, 1075, 1084, - 714, 710, 670, 607, 670, 0, 1435, 1457, 1454, 582, - 156, 1476, 0, 170, 0, 0, 0, 0, 173, 187, - 184, 1475, 0, 0, 611, 613, 0, 1143, 621, 615, + 0, 0, 0, 0, 0, 0, 0, 0, 1052, 1171, + 0, 1190, 1189, 992, 999, 1002, 1006, 1007, 1008, 1191, + 0, 0, 0, 1003, 1004, 1005, 995, 996, 997, 998, + 1000, 1001, 1009, 789, 0, 0, 783, 1200, 1199, 1193, + 1194, 0, 1060, 1061, 1062, 1201, 0, 0, 758, 636, + 634, 637, 639, 635, 0, 0, 791, 596, 596, 596, + 596, 593, 0, 0, 0, 790, 0, 687, 754, 752, + 0, 776, 0, 749, 0, 755, 0, 740, 0, 747, + 796, 763, 0, 0, 765, 1440, 813, 0, 808, 804, + 0, 0, 0, 814, 0, 0, 0, 0, 0, 0, + 0, 1170, 0, 602, 1036, 0, 0, 0, 1210, 0, + 988, 830, 843, 0, 1118, 1041, 0, 1141, 1105, 871, + 870, 872, 872, 0, 0, 0, 0, 1260, 1218, 0, + 1066, 1216, 1159, 1109, 1111, 1261, 1023, 855, 919, 0, + 0, 0, 0, 0, 0, 0, 971, 962, 0, 969, + 973, 0, 0, 0, 956, 0, 0, 954, 983, 950, + 0, 0, 984, 1225, 0, 1229, 0, 0, 1074, 1083, + 714, 710, 670, 607, 670, 0, 1434, 1456, 1453, 582, + 156, 1475, 0, 170, 0, 0, 0, 0, 173, 187, + 184, 1474, 0, 0, 611, 613, 0, 1142, 621, 615, 663, 662, 0, 631, 698, 629, 0, 704, 0, 572, - 0, 558, 0, 732, 0, 0, 1444, 1445, 0, 0, + 0, 558, 0, 732, 0, 0, 1443, 1444, 0, 0, 0, 322, 0, 0, 0, 273, 0, 381, 0, 388, 0, 0, 373, 354, 85, 0, 0, 0, 59, 104, 77, 69, 55, 83, 0, 0, 88, 0, 81, 98, 99, 97, 102, 0, 283, 308, 0, 0, 319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 499, 1227, 1223, 1227, 0, 0, 0, 609, 605, 606, - 1044, 0, 469, 523, 520, 521, 519, 229, 380, 0, - 0, 0, 200, 368, 0, 1335, 449, 452, 1317, 406, + 499, 1226, 1222, 1226, 0, 0, 0, 609, 605, 606, + 1043, 0, 469, 523, 520, 521, 519, 229, 380, 0, + 0, 0, 200, 368, 0, 1334, 449, 452, 1316, 406, 0, 193, 0, 191, 211, 0, 0, 202, 371, 0, - 346, 342, 367, 340, 339, 341, 0, 1533, 222, 0, - 1527, 371, 1334, 0, 0, 465, 456, 0, 461, 0, - 0, 459, 0, 1329, 254, 443, 0, 477, 518, 525, + 346, 342, 367, 340, 339, 341, 0, 1532, 222, 0, + 1526, 371, 1333, 0, 0, 465, 456, 0, 461, 0, + 0, 459, 0, 1328, 254, 443, 0, 477, 518, 525, 505, 510, 0, 516, 512, 511, 506, 514, 513, 509, - 1054, 1065, 1189, 0, 0, 0, 0, 783, 786, 0, - 1060, 1055, 757, 0, 0, 670, 0, 0, 0, 0, - 587, 586, 592, 0, 0, 1078, 752, 0, 0, 0, - 739, 727, 734, 735, 0, 0, 0, 795, 794, 765, - 818, 0, 798, 818, 0, 818, 0, 816, 0, 825, - 913, 914, 915, 916, 917, 918, 919, 850, 0, 1213, - 1209, 1115, 1117, 1154, 868, 866, 988, 1251, 1159, 1256, - 1258, 0, 0, 0, 0, 1109, 991, 1282, 924, 0, - 0, 954, 1206, 975, 0, 0, 0, 950, 1142, 0, - 0, 0, 0, 0, 959, 0, 1234, 1227, 0, 1233, - 0, 0, 0, 0, 1049, 715, 687, 0, 687, 0, - 0, 1474, 0, 1469, 148, 149, 150, 0, 0, 0, + 1053, 1064, 1188, 0, 0, 0, 0, 782, 785, 0, + 1059, 1054, 756, 0, 0, 670, 0, 0, 0, 0, + 587, 586, 592, 0, 0, 1077, 751, 0, 0, 0, + 738, 727, 733, 734, 0, 0, 0, 794, 793, 764, + 817, 0, 797, 817, 0, 817, 0, 815, 0, 824, + 912, 913, 914, 915, 916, 917, 918, 849, 0, 1212, + 1208, 1114, 1116, 1153, 867, 865, 987, 1250, 1158, 1255, + 1257, 0, 0, 0, 0, 1108, 990, 1281, 923, 0, + 0, 953, 1205, 974, 0, 0, 0, 949, 1141, 0, + 0, 0, 0, 0, 958, 0, 1233, 1226, 0, 1232, + 0, 0, 0, 0, 1048, 715, 687, 0, 687, 0, + 0, 1473, 0, 1468, 148, 149, 150, 0, 0, 0, 165, 142, 0, 0, 182, 170, 158, 619, 620, 0, - 614, 630, 1264, 1270, 557, 0, 1021, 0, 0, 554, + 614, 630, 1263, 1269, 557, 0, 1020, 0, 0, 554, 0, 134, 273, 0, 0, 66, 0, 390, 334, 382, 365, 349, 0, 0, 0, 274, 0, 407, 0, 0, 355, 0, 0, 0, 0, 335, 0, 0, 294, 0, 0, 365, 0, 372, 290, 291, 0, 58, 78, 0, 74, 0, 103, 0, 0, 0, 0, 0, 61, 73, - 0, 56, 0, 443, 443, 64, 1295, 1940, 1941, 1942, - 1943, 1944, 1945, 1946, 1947, 1948, 1949, 2060, 1950, 1951, - 1952, 1953, 1954, 1955, 1956, 1957, 2069, 1958, 280, 1959, - 1713, 1960, 1961, 1962, 1963, 1964, 0, 1965, 801, 1966, - 1967, 2148, 1968, 1127, 1128, 279, 278, 375, 275, 383, - 277, 0, 1296, 276, 378, 333, 130, 1341, 0, 128, - 0, 1339, 137, 135, 132, 1343, 1481, 0, 0, 1047, - 1048, 1045, 607, 0, 0, 0, 499, 476, 0, 0, - 0, 1532, 0, 0, 1644, 0, 189, 0, 0, 203, - 1335, 199, 368, 0, 398, 318, 393, 0, 1532, 1530, - 0, 1335, 1526, 448, 451, 0, 0, 540, 453, 0, - 0, 0, 414, 491, 0, 515, 1013, 0, 0, 0, + 0, 56, 0, 443, 443, 64, 1294, 1939, 1940, 1941, + 1942, 1943, 1944, 1945, 1946, 1947, 1948, 2059, 1949, 1950, + 1951, 1952, 1953, 1954, 1955, 1956, 2068, 1957, 280, 1958, + 1712, 1959, 1960, 1961, 1962, 1963, 0, 1964, 800, 1965, + 1966, 2147, 1967, 1126, 1127, 279, 278, 375, 275, 383, + 277, 0, 1295, 276, 378, 333, 130, 1340, 0, 128, + 0, 1338, 137, 135, 132, 1342, 1480, 0, 0, 1046, + 1047, 1044, 607, 0, 0, 0, 499, 476, 0, 0, + 0, 1531, 0, 0, 1643, 0, 189, 0, 0, 203, + 1334, 199, 368, 0, 398, 318, 393, 0, 1531, 1529, + 0, 1334, 1525, 448, 451, 0, 0, 540, 453, 0, + 0, 0, 414, 491, 0, 515, 1012, 0, 0, 0, 0, 646, 0, 652, 687, 591, 590, 589, 588, 669, - 1583, 1872, 1769, 0, 673, 668, 671, 676, 678, 677, - 679, 675, 686, 0, 689, 776, 1155, 1157, 0, 0, - 0, 0, 740, 742, 0, 744, 0, 796, 812, 0, - 813, 0, 811, 806, 817, 1212, 1259, 1260, 1255, 0, - 921, 1218, 981, 979, 976, 0, 977, 958, 0, 0, - 956, 952, 0, 986, 0, 0, 1231, 0, 1070, 0, - 1073, 1087, 1083, 1082, 1078, 1044, 1078, 1436, 580, 169, - 146, 172, 171, 0, 1228, 179, 0, 0, 170, 0, + 1582, 1871, 1768, 0, 673, 668, 671, 676, 678, 677, + 679, 675, 686, 0, 689, 775, 1154, 1156, 0, 0, + 0, 0, 739, 741, 0, 743, 0, 795, 811, 0, + 812, 0, 810, 805, 816, 1211, 1258, 1259, 1254, 0, + 920, 1217, 980, 978, 975, 0, 976, 957, 0, 0, + 955, 951, 0, 985, 0, 0, 1230, 0, 1069, 0, + 1072, 1086, 1082, 1081, 1077, 1043, 1077, 1435, 580, 169, + 146, 172, 171, 0, 1227, 179, 0, 0, 170, 0, 174, 466, 0, 0, 569, 731, 562, 563, 0, 386, 68, 0, 365, 0, 273, 351, 350, 353, 348, 352, 0, 408, 0, 0, 292, 0, 299, 337, 338, 336, 293, 365, 371, 295, 0, 0, 0, 70, 60, 57, - 62, 71, 0, 0, 72, 75, 797, 87, 80, 1295, - 2069, 2078, 0, 0, 0, 0, 0, 1225, 1224, 0, + 62, 71, 0, 0, 72, 75, 796, 87, 80, 1294, + 2068, 2077, 0, 0, 0, 0, 0, 1224, 1223, 0, 472, 471, 522, 468, 479, 229, 0, 0, 0, 342, - 1529, 0, 0, 0, 368, 194, 0, 0, 0, 0, - 1532, 0, 0, 270, 0, 315, 0, 215, 1531, 0, - 0, 1518, 0, 0, 1327, 1328, 0, 478, 1014, 0, - 1015, 787, 0, 0, 644, 1078, 0, 0, 0, 680, - 674, 0, 1077, 1079, 0, 641, 1158, 736, 0, 738, - 0, 762, 0, 762, 745, 807, 799, 1257, 1068, 0, - 978, 982, 980, 960, 1227, 1235, 1227, 1232, 1072, 1086, - 1089, 689, 1280, 689, 0, 0, 157, 0, 0, 154, - 141, 159, 1144, 559, 560, 0, 273, 0, 364, 387, + 1528, 0, 0, 0, 368, 194, 0, 0, 0, 0, + 1531, 0, 0, 270, 0, 315, 0, 215, 1530, 0, + 0, 1517, 0, 0, 1326, 1327, 0, 478, 1013, 0, + 1014, 786, 0, 0, 644, 1077, 0, 0, 0, 680, + 674, 0, 1076, 1078, 0, 641, 1157, 735, 0, 737, + 0, 761, 0, 761, 744, 806, 798, 1256, 1067, 0, + 977, 981, 979, 959, 1226, 1234, 1226, 1231, 1071, 1085, + 1088, 689, 1279, 689, 0, 0, 157, 0, 0, 154, + 141, 159, 1143, 559, 560, 0, 273, 0, 364, 387, 304, 282, 0, 0, 0, 289, 296, 397, 298, 0, - 79, 95, 0, 0, 377, 138, 136, 1046, 499, 0, - 205, 1335, 318, 1526, 0, 0, 0, 0, 342, 222, - 1528, 331, 324, 325, 326, 327, 328, 329, 330, 345, - 344, 316, 317, 0, 0, 0, 0, 454, 1329, 0, - 176, 185, 0, 176, 1016, 647, 0, 689, 0, 0, - 0, 672, 0, 0, 688, 0, 545, 1156, 0, 726, + 79, 95, 0, 0, 377, 138, 136, 1045, 499, 0, + 205, 1334, 318, 1525, 0, 0, 0, 0, 342, 222, + 1527, 331, 324, 325, 326, 327, 328, 329, 330, 345, + 344, 316, 317, 0, 0, 0, 0, 454, 1328, 0, + 176, 185, 0, 176, 1015, 647, 0, 689, 0, 0, + 0, 672, 0, 0, 688, 0, 545, 1155, 0, 726, 724, 0, 725, 0, 0, 0, 0, 609, 641, 641, 143, 0, 144, 180, 0, 0, 0, 371, 389, 363, 0, 356, 302, 301, 303, 307, 0, 305, 0, 321, 0, 314, 282, 0, 82, 0, 384, 467, 475, 0, - 272, 1520, 368, 0, 204, 1526, 318, 1532, 1526, 0, - 1523, 0, 0, 0, 0, 178, 1335, 0, 178, 0, - 641, 682, 0, 681, 1081, 1080, 643, 737, 0, 1069, - 1237, 1236, 0, 1093, 544, 543, 0, 0, 0, 0, + 272, 1519, 368, 0, 204, 1525, 318, 1531, 1525, 0, + 1522, 0, 0, 0, 0, 178, 1334, 0, 178, 0, + 641, 682, 0, 681, 1080, 1079, 643, 736, 0, 1068, + 1236, 1235, 0, 1092, 544, 543, 0, 0, 0, 0, 397, 0, 343, 0, 0, 304, 0, 297, 394, 395, 396, 0, 310, 300, 311, 76, 94, 385, 0, 368, - 1521, 271, 216, 1519, 1524, 1525, 0, 176, 175, 618, - 177, 792, 186, 618, 651, 546, 683, 640, 743, 1088, - 0, 0, 0, 0, 0, 153, 792, 164, 0, 314, + 1520, 271, 216, 1518, 1523, 1524, 0, 176, 175, 618, + 177, 791, 186, 618, 651, 546, 683, 640, 742, 1087, + 0, 0, 0, 0, 0, 153, 791, 164, 0, 314, 362, 357, 281, 306, 320, 0, 0, 0, 312, 0, - 313, 1526, 0, 178, 621, 1325, 621, 1858, 1584, 1823, - 0, 1105, 1094, 1105, 1105, 1085, 145, 152, 0, 273, - 286, 0, 285, 0, 374, 309, 1522, 1335, 618, 166, - 167, 0, 1098, 1097, 1096, 1100, 1099, 0, 1092, 1090, - 1091, 792, 391, 284, 288, 287, 792, 621, 0, 0, - 1102, 0, 1103, 163, 1326, 168, 1095, 1101, 1104 + 313, 1525, 0, 178, 621, 1324, 621, 1857, 1583, 1822, + 0, 1104, 1093, 1104, 1104, 1084, 145, 152, 0, 273, + 286, 0, 285, 0, 374, 309, 1521, 1334, 618, 166, + 167, 0, 1097, 1096, 1095, 1099, 1098, 0, 1091, 1089, + 1090, 791, 391, 284, 288, 287, 791, 621, 0, 0, + 1101, 0, 1102, 163, 1325, 168, 1094, 1100, 1103 }; /* YYDEFGOTO[NTERM-NUM]. */ @@ -4392,7 +4392,7 @@ static const yytype_int16 yypgoto[] = 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 -2082 +#define YYTABLE_NINF -2081 static const yytype_int16 yytable[] = { 525, 1133, 57, 913, 65, 82, 962, 1237, 1200, 719, @@ -4411,21 +4411,21 @@ static const yytype_int16 yytable[] = 2993, 90, 91, 972, 93, 810, 810, 1376, 98, 102, 975, 1012, 104, 2674, 2675, 2676, 1033, 2489, 964, 2688, -454, 818, 818, 2884, 2819, 2337, -527, 2889, -371, 2333, - 1054, 1572, 1573, 1054, 2221, -1351, -531, -1929, 900, -1929, - 2224, 2172, 2439, 1210, 3434, -2069, -2069, 3233, 1585, 1211, - -865, -870, 1340, 2332, 820, -870, -1292, -1273, 1054, 1421, - 2696, 537, -1920, -873, -1289, -1289, -1937, 982, -1293, -1292, - -2060, -2060, -2055, -2055, -2078, -2078, -1290, -1290, 2126, -1920, - 1210, -1937, -2080, -2080, -1293, -832, 1211, 2706, 2692, -845, - -860, 3220, 2116, 820, 820, 23, 1146, -873, 1769, 2690, + 1054, 1572, 1573, 1054, 2221, -1350, -531, -1928, 900, -1928, + 2224, 2172, 2439, 1210, 3434, -2068, -2068, 3233, 1585, 1211, + -864, -869, 1340, 2332, 820, -869, -1291, -1272, 1054, 1421, + 2696, 537, -1919, -872, -1288, -1288, -1936, 982, -1292, -1291, + -2059, -2059, -2054, -2054, -2077, -2077, -1289, -1289, 2126, -1919, + 1210, -1936, -2079, -2079, -1292, -831, 1211, 2706, 2692, -844, + -859, 3220, 2116, 820, 820, 23, 1146, -872, 1769, 2690, 3168, 1758, 1679, 2697, 2683, 2116, 820, 3515, 3237, 1805, 861, 1627, 1189, 1926, 1604, -480, 1629, 1192, 1928, 1461, 981, 2507, 1675, 1356, 820, 953, -527, 1153, 1054, 2782, - 1817, 1340, -229, 3569, 1256, -1125, -531, -229, 820, 1818, - 2155, 2743, 2745, -1125, 2748, 1778, 1637, 1356, 2156, 1701, + 1817, 1340, -229, 3569, 1256, -1124, -531, -229, 820, 1818, + 2155, 2743, 2745, -1124, 2748, 1778, 1637, 1356, 2156, 1701, 2468, 2469, 1054, 1340, 1212, 1331, 2329, 2234, 1627, 1007, - 875, 2475, 1628, 1629, 1926, 2479, 875, -1146, 1927, 1928, - 3203, 2713, 3179, 1769, 3311, -1146, -664, 1753, 538, 820, + 875, 2475, 1628, 1629, 1926, 2479, 875, -1145, 1927, 1928, + 3203, 2713, 3179, 1769, 3311, -1145, -664, 1753, 538, 820, 1639, 1698, 1787, 1627, 2662, 1790, 1791, 1628, 1629, 1154, 880, 1212, 1033, 1637, 1332, 3394, 1761, 3134, 1966, 3136, 2449, 1250, 3540, 1577, 1012, 3039, 3151, 3324, 1151, 2451, @@ -4433,9 +4433,9 @@ static const yytype_int16 yytable[] = 3, 4, 1751, 2313, 1013, 3354, 2165, 1639, -609, 1747, 1748, 1966, 1370, -609, 2927, 3355, 1676, 2901, 26, 27, 28, 2856, 2630, 2858, 2103, 838, 3291, 3564, 3293, 3458, - 1712, 876, 1639, 113, -802, 1019, 1778, 876, 3341, 3013, + 1712, 876, 1639, 113, -801, 1019, 1778, 876, 3341, 3013, 3468, 3165, 2898, 1599, 2765, 2452, 2227, 2196, 3402, 880, - -2054, -2054, 1627, 1801, 2564, 3177, 1464, 105, 2857, 2412, + -2053, -2053, 1627, 1801, 2564, 3177, 1464, 105, 2857, 2412, 3438, 3257, 1471, 3141, 879, 1627, 1821, 3231, 879, 2183, 2656, 1020, 2907, 3454, 3455, 3202, 1862, 1590, 2897, 788, 3340, 3185, 3571, 2657, -609, 33, 2127, 1462, 2928, 3190, @@ -4447,10 +4447,10 @@ static const yytype_int16 yytable[] = 1677, 2627, 880, 2627, 1014, 2754, 880, 3367, 3049, 2813, 1214, 3040, 1595, 1333, 1215, 40, 2166, 1778, 2631, 1210, 3183, 3322, 2259, 2228, 1808, 1211, 43, -527, 2314, 3508, - -802, 2903, 2929, 2904, 1926, 1251, 3469, -531, 1927, 1928, + -801, 2903, 2929, 2904, 1926, 1251, 3469, -531, 1927, 1928, 2450, 1776, 3356, 1589, 3523, 3255, 1216, 1240, -684, 2453, 3565, 1215, 3541, 2321, 1053, 2330, 1820, 1926, 1776, 3345, - 928, 1927, 1928, 3395, 988, -2082, -2082, -2082, 1341, 2124, + 928, 1927, 1928, 3395, 988, -2081, -2081, -2081, 1341, 2124, 1749, 1148, 3346, 2235, 3064, 1750, 2782, 954, 3481, 3516, 3169, 46, 1697, 1241, 1048, 3043, 1026, 1806, 3214, 2129, 1341, 1690, 1616, 2483, 2318, 862, 719, 3572, 2047, 2131, @@ -4458,17 +4458,17 @@ static const yytype_int16 yytable[] = 3028, 2076, 1883, 2312, 1754, 1764, 2555, 1217, 1887, 3300, 911, 3055, 3470, 2836, 912, 948, 1973, 3554, 3044, 1334, 1212, 950, 877, 1585, 2378, 2009, 981, 3482, 2502, 3542, - 3332, 3312, 2752, 1994, -1125, 2576, -527, 2684, 2685, 2157, + 3332, 3312, 2752, 1994, -1124, 2576, -527, 2684, 2685, 2157, 535, 1342, 1568, 881, 1217, 2221, -531, 881, 2755, 1803, 2602, 3236, 2663, 2991, 539, 3014, 2420, 789, 3543, 1776, - 819, 2407, 1476, 3192, 3193, 2597, -1146, 2709, 2797, 2704, + 819, 2407, 1476, 3192, 3193, 2597, -1145, 2709, 2797, 2704, 1590, -454, -454, 2413, 2171, -527, 1306, -527, 2993, -371, - -1929, 2384, -1929, 2058, 2059, -531, -1351, -531, 1582, 2698, - 1582, 2591, 1591, -865, -870, 3159, 3303, 1622, 911, -1292, - -1273, 3304, 912, 2441, 1590, -1920, 1592, 1574, 2126, -1937, - 2446, -1293, -1292, 1779, 1477, 2044, 1604, 1001, 1715, 3427, - 1345, 2688, -1920, 871, -1937, 1604, 1591, -1293, 1575, 1256, - 2097, 1256, 1580, -860, 1891, 3277, 1672, 2173, 1797, 2079, + -1928, 2384, -1928, 2058, 2059, -531, -1350, -531, 1582, 2698, + 1582, 2591, 1591, -864, -869, 3159, 3303, 1622, 911, -1291, + -1272, 3304, 912, 2441, 1590, -1919, 1592, 1574, 2126, -1936, + 2446, -1292, -1291, 1779, 1477, 2044, 1604, 1001, 1715, 3427, + 1345, 2688, -1919, 871, -1936, 1604, 1591, -1292, 1575, 1256, + 2097, 1256, 1580, -859, 1891, 3277, 1672, 2173, 1797, 2079, 1594, 975, 2132, 3419, 1660, 1884, 1943, 980, 2480, 3426, 3217, 3306, 2480, 2133, 1179, 1715, 858, 1004, 1360, 1361, 3493, 1185, 1798, 3347, 1716, 2776, 3348, -229, -229, 2098, @@ -4492,21 +4492,21 @@ static const yytype_int16 yytable[] = 2310, 820, 108, 1217, 3421, 1719, 2456, 907, 1399, 1400, 2377, 2342, 916, 909, 2379, 2139, 50, 2381, 3336, 3566, 51, 1299, 52, 2524, 55, 1778, 1457, 3309, 2247, 56, - 59, 60, 980, 1468, 61, 63, 66, -1929, 917, 525, + 59, 60, 980, 1468, 61, 63, 66, -1928, 917, 525, 525, 2076, 1719, 67, 23, 525, 2389, 940, 525, 525, 80, 525, 525, 525, 525, 2283, 2394, 1352, 1309, 2827, 77, 81, 83, 84, 784, 90, 91, 525, 93, 1778, 1769, 1779, 98, 102, 525, 2294, 104, 939, 2911, 1793, 2301, 1772, 1938, 1939, 1940, 1941, 1942, 1943, 3296, 1794, 523, 525, 1299, 1560, 915, 1949, 3480, 523, 2577, 3483, - 2578, -2082, -2082, -2082, 918, 1938, 1939, 1940, 1941, 1942, + 2578, -2081, -2081, -2081, 918, 1938, 1939, 1940, 1941, 1942, 1943, 1893, 2672, 525, 2547, 2286, 1054, 3285, 1454, 2548, 2289, 2914, 816, 2673, 871, 2661, 1895, 1461, 3286, 816, 1213, 1054, 525, 919, 810, 3501, 1480, 1803, 1776, 2140, 1484, 810, 2037, 525, 525, 525, 941, 525, 525, 940, 818, 719, 3125, 2665, 2677, 1888, 2141, 818, 1889, 2259, 3323, 2142, 1590, 546, 3502, 971, 927, 1882, 2608, 3398, - 3415, 2445, 109, 1385, 1386, 541, 920, 1882, -2051, -2051, + 3415, 2445, 109, 1385, 1386, 541, 920, 1882, -2050, -2050, 3249, 2597, 525, 110, 1591, 942, 1610, 26, 27, 28, 934, 550, 3546, 2637, 541, 2638, -209, 2669, 1594, 2143, 525, 525, 1210, 1779, 1703, 1704, 2664, 1710, 1211, 888, @@ -4522,12 +4522,12 @@ static const yytype_int16 yytable[] = 1628, 1629, 2395, 921, 1187, 2396, -608, 1042, 1043, 1044, -540, 1299, 1047, 1212, 922, 1470, 951, 116, 941, 1469, 1299, 536, 1838, 1474, 40, 1022, 2359, 952, 2360, 749, - 544, 1637, 2543, 2919, 1210, 43, 1140, 1141, -2082, 1143, - 1211, 1145, 1776, 837, 1299, -2052, -2052, 851, 822, 923, + 544, 1637, 2543, 2919, 1210, 43, 1140, 1141, -2081, 1143, + 1211, 1145, 1776, 837, 1299, -2051, -2051, 851, 822, 923, 956, 2920, 2573, 1188, 955, -608, 2144, 942, 2433, -540, - 957, 2434, 1399, 1400, 988, 1639, 1560, 911, -540, -1273, + 957, 2434, 1399, 1400, 988, 1639, 1560, 911, -540, -1272, 1308, 912, 924, 1839, 1843, 2481, 1844, 1846, 2482, 2649, - 2484, 2651, 719, 2482, 1847, 2652, -2053, -2053, 2653, 1308, + 2484, 2651, 719, 2482, 1847, 2652, -2052, -2052, 2653, 1308, 46, 719, 2700, 2646, 2658, 2648, -208, 2659, 3060, 958, 925, 1210, 3562, 2725, 2076, 968, 2009, 1211, 980, 2789, 2777, 986, 2482, 2790, 2784, 2793, 2034, 1876, 2794, 987, @@ -4535,88 +4535,88 @@ static const yytype_int16 yytable[] = 525, 2127, 77, 930, 3029, 931, 784, 2396, 908, 546, 3549, 547, 3550, 944, 992, 1212, 3030, 977, 550, 2327, 3053, 995, 2921, 3054, 1026, 3061, 2611, 996, 3062, 2128, - 1898, 2922, -2082, 2989, 1885, 3116, 1886, 550, 2034, 932, - 1213, 933, 1985, 1463, 1986, 3250, 997, 1988, 2034, -2082, - 525, 525, 1992, 3575, -2082, 1995, 525, 1996, 525, 3525, + 1898, 2922, -2081, 2989, 1885, 3116, 1886, 550, 2034, 932, + 1213, 933, 1985, 1463, 1986, 3250, 997, 1988, 2034, -2081, + 525, 525, 1992, 3575, -2081, 1995, 525, 1996, 525, 3525, 998, 2000, 2938, 525, 525, 525, 525, 999, 2931, 3251, 2695, 2457, 2482, 2458, 3537, 2459, 1006, 2460, 525, 525, - 1000, 523, 1212, 525, 3006, 525, -2056, -2056, 525, -540, - 2895, 3280, -2082, 525, 2034, 525, 525, 3287, 525, 2246, - 2009, 3297, 525, 1215, 3298, 1001, 523, 2596, 523, -2057, - -2057, 523, 1223, 816, 2814, 2815, 523, 3016, 1040, 523, + 1000, 523, 1212, 525, 3006, 525, -2055, -2055, 525, -540, + 2895, 3280, -2081, 525, 2034, 525, 525, 3287, 525, 2246, + 2009, 3297, 525, 1215, 3298, 1001, 523, 2596, 523, -2056, + -2056, 523, 1223, 816, 2814, 2815, 523, 3016, 1040, 523, 3330, 523, 2930, 2396, 2939, 523, 1035, 3331, 3364, 3573, 2327, 2034, 1224, 3424, 3574, 1216, 2396, 1046, 816, 3436, - 816, 818, 3437, 816, 2129, -2058, -2058, 1648, 816, 2130, + 816, 818, 3437, 816, 2129, -2057, -2057, 1648, 816, 2130, 810, 816, 810, 816, 2131, 810, 1560, 816, 911, 3384, 810, 3385, 912, 810, 1045, 810, 818, 1604, 818, 810, 3462, 818, 1213, 3463, 1608, 1048, 818, 3506, 1225, 818, - 3437, 818, -2059, -2059, 3547, 818, 1836, 3437, 525, 525, + 3437, 818, -2058, -2058, 3547, 818, 1836, 3437, 525, 525, 2803, 2805, 2806, 2802, 2804, 2801, 2800, 525, 525, 1182, - 1049, 1184, 2036, 2040, 1144, 525, 1217, -2061, -2061, 1150, - 77, 2038, 525, 2039, 2043, -2062, -2062, -2063, -2063, -2064, - -2064, 2042, -2065, -2065, 1161, 1837, -2066, -2066, 1167, -2067, - -2067, 2292, -2068, -2068, 1168, 1215, -2070, -2070, 719, 1213, - 1170, 1210, 525, -2071, -2071, 525, 1171, 1211, 1172, -2082, + 1049, 1184, 2036, 2040, 1144, 525, 1217, -2060, -2060, 1150, + 77, 2038, 525, 2039, 2043, -2061, -2061, -2062, -2062, -2063, + -2063, 2042, -2064, -2064, 1161, 1837, -2065, -2065, 1167, -2066, + -2066, 2292, -2067, -2067, 1168, 1215, -2069, -2069, 719, 1213, + 1170, 1210, 525, -2070, -2070, 525, 1171, 1211, 1172, -2081, 1560, 525, 525, 525, 525, 525, 525, 525, 525, 719, - 3222, -2072, -2072, 525, 525, 525, 1174, 2293, 525, 1175, + 3222, -2071, -2071, 525, 525, 525, 1174, 2293, 525, 1175, 2735, 1183, 525, 1202, 1226, 525, 525, 525, 525, 525, - 525, 525, 525, 525, -2073, -2073, 525, 1205, 523, 981, - -2074, -2074, 1207, 525, 2113, 1299, -2075, -2075, 1365, 2597, - -2077, -2077, 1215, 2168, 2203, -2079, -2079, 2132, 1208, 888, - 1209, 1839, -2081, -2081, 525, 1823, 1824, 1221, 2133, 3196, + 525, 525, 525, 525, -2072, -2072, 525, 1205, 523, 981, + -2073, -2073, 1207, 525, 2113, 1299, -2074, -2074, 1365, 2597, + -2076, -2076, 1215, 2168, 2203, -2078, -2078, 2132, 1208, 888, + 1209, 1839, -2080, -2080, 525, 1823, 1824, 1221, 2133, 3196, 2066, 2067, 2068, 1227, 2069, 2070, 2071, 2072, 2073, 2074, 2222, 2223, 2097, 1228, 1216, -659, -659, 525, 1217, -663, -663, -662, -662, 1395, 1396, 1229, 1248, 1626, 525, 525, - 1627, 1158, 1212, 1222, 1628, 1629, 1302, -2082, 1399, 1400, + 1627, 1158, 1212, 1222, 1628, 1629, 1302, -2081, 1399, 1400, 3160, 3156, 3157, 2938, 1655, 1656, 1657, 1658, 1659, 1660, 2727, 2729, 3533, 3534, 3559, 3560, 1239, 1230, 1683, 1684, 2616, 2617, 1305, 1243, 1247, 1637, 1306, 1311, 1560, 1313, - 1317, 1329, -2082, 1327, 1337, 1330, 1338, 719, 1344, 719, + 1317, 1329, -2081, 1327, 1337, 1330, 1338, 719, 1344, 719, 1348, 1347, 1353, 2888, 1372, 1217, 1371, 1377, 1435, 1451, 1448, 1458, 1450, 1465, 1466, 2012, 1472, 1473, 1479, 1639, - 1485, 1483, 1562, 1563, 1565, -836, -843, 1574, 3012, 1578, + 1485, 1483, 1562, 1563, 1565, -835, -842, 1574, 3012, 1578, 3213, 1232, 2271, 1624, 2275, 3052, 46, -684, 3023, 525, - -685, -833, -834, 1299, 1588, -837, 525, 525, 3524, 2251, - 1589, -835, 3526, 3041, -540, 1668, 1233, 1609, 1619, 2260, + -685, -832, -833, 1299, 1588, -836, 525, 525, 3524, 2251, + 1589, -834, 3526, 3041, -540, 1668, 1233, 1609, 1619, 2260, 1621, 2263, 1666, 1365, 2274, 1682, 541, 1692, 1670, -540, 2278, 1691, 2280, 1696, -540, 1235, 1700, 3363, 3276, 1702, 3127, 1186, 1188, 1737, 2542, 2287, 820, 1299, 1739, 1741, - 2290, -1337, 1775, 1756, 2295, 2296, 2297, 2298, 1781, 2302, + 2290, -1336, 1775, 1756, 2295, 2296, 2297, 2298, 1781, 2302, 2303, 2363, 1774, 1776, 1782, 719, 1783, 3567, 1788, 1213, - 1795, 1800, 1299, 525, 1796, 113, -2082, 1810, 1816, 1826, + 1795, 1800, 1299, 525, 1796, 113, -2081, 1810, 1816, 1826, 1827, 980, 1828, 1832, 1835, -540, 1841, 1842, 1850, 542, - 1851, 1858, 1860, -2082, 1854, 1857, 1861, 1560, -2082, 1863, + 1851, 1858, 1860, -2081, 1854, 1857, 1861, 1560, -2081, 1863, 1864, 525, 525, 1365, 525, -540, 1365, 1365, 1877, 1560, 525, 525, 525, 525, 525, 525, 2597, 1878, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 2299, 2470, - 1882, 1431, 1215, 525, 525, 2473, -2082, 525, 1890, 1560, + 1882, 1431, 1215, 525, 525, 2473, -2081, 525, 1890, 1560, 1954, 2989, 1626, 970, 525, 1627, 1560, 1915, 1917, 1628, 1629, 3512, 1965, 2362, -540, 1918, 1920, 1923, 1946, 1983, 1955, 1962, 1987, -540, 2300, 1993, 525, 14, 15, 1997, 525, 1998, 525, 1999, 23, 2004, 525, 1568, 2010, 2867, - 1637, 2007, 2015, 1575, 1560, 1580, 3363, -2082, 1560, 2011, + 1637, 2007, 2015, 1575, 1560, 1580, 3363, -2081, 1560, 2011, 525, 1648, 1299, 523, 1560, 2013, 2014, 2016, 2046, 523, 2047, 1054, 1627, 3197, 3198, 3328, 2080, 2081, 2084, 3188, 2087, 2090, 2093, 23, 1639, 2092, 2095, 1560, 2094, 2135, 2136, 545, 541, 2115, 2138, 816, 2162, 2163, 3363, 525, 525, 816, 2169, 2181, 23, 1217, 3097, 810, 1430, 1894, - 1896, 984, 2182, 810, 1549, 2186, 879, -1337, 2199, 2212, + 1896, 984, 2182, 810, 1549, 2186, 879, -1336, 2199, 2212, 2202, 2213, 2211, 818, 2214, 2216, 2215, 2233, 2237, 818, 2238, 2241, 2248, 2252, 2253, 2254, 880, 525, 2334, 2324, 525, 546, 1037, 971, 2328, 525, 525, 3363, 2343, 2552, 2345, 871, 1608, 2346, 2349, 542, 2347, 2350, 2348, 2364, - 548, 2365, 2367, -2082, 2372, 2373, 549, 1142, 2376, 550, + 548, 2365, 2367, -2081, 2372, 2373, 549, 1142, 2376, 550, 525, 525, 3417, 2370, 2371, 525, 2374, 2380, 2397, 2405, - 1951, -2082, 1926, 2435, -540, 1950, 2442, 26, 27, 28, - 2443, 525, 2444, 1730, 525, 525, 525, 2466, -2082, 2448, - 2454, 2474, 1431, -2082, 2486, 2488, 2455, 2493, 3379, 2341, + 1951, -2081, 1926, 2435, -540, 1950, 2442, 26, 27, 28, + 2443, 525, 2444, 1730, 525, 525, 525, 2466, -2081, 2448, + 2454, 2474, 1431, -2081, 2486, 2488, 2455, 2493, 3379, 2341, 2472, 2494, 525, 719, 2495, 822, 2497, 2498, 523, 525, 2499, 2500, 525, 2503, 2511, 2504, 26, 27, 28, 2512, 2515, 2514, 3174, 1600, 2516, 2517, 2868, 2544, 2518, 525, - 2519, -2082, 2520, 2521, 2539, 523, 2551, 26, 27, 28, + 2519, -2081, 2520, 2521, 2539, 523, 2551, 26, 27, 28, 2522, 1551, 525, 911, 33, 2560, 1170, 912, 2568, 2536, 2582, 2537, 523, 2561, 2579, 2566, 2567, 2580, 2989, 525, - 525, -2082, 2584, 2585, 2590, 2592, 1557, 816, 1655, 1656, + 525, -2081, 2584, 2585, 2590, 2592, 1557, 816, 1655, 1656, 1657, 1658, 1659, 1660, 2593, -665, 525, 2603, 525, 810, 2604, 38, 2606, 33, 816, 2607, 1648, 1549, 2610, 2614, 1885, 525, 1362, 2615, 35, 818, 810, 2620, 1754, 2623, @@ -4628,7 +4628,7 @@ static const yytype_int16 yytable[] = 2742, 2750, 549, 40, 1299, 550, 2753, 2756, 2773, 2774, 2099, 2914, 871, 2915, 43, 2785, 45, 2760, 2786, 2759, 1680, 2761, 2834, 2762, 40, 981, 2810, 1549, 2799, 2823, - 46, 44, 2835, 2791, 1843, 43, 1844, 1846, -2082, 2847, + 46, 44, 2835, 2791, 1843, 43, 1844, 1846, -2081, 2847, 719, 2807, 2817, 2848, 1847, 1560, 2824, 2832, 2838, 2853, 2862, 2879, 44, 2855, 2859, 45, 2881, 2885, 2883, 2893, 2926, 2942, 2900, 2906, 2899, 525, 3009, 1620, 3010, 46, @@ -4639,21 +4639,21 @@ static const yytype_int16 yytable[] = 1223, 3104, 3107, 3149, 2220, 2220, 3128, 3135, 3138, 3147, 3140, 2718, 3153, 3154, 1898, 3171, 3155, 525, 3161, 3378, 1224, 3162, 3163, 3167, 3172, 3181, 3173, 3184, 3186, 3187, - 3191, -2050, -2051, -2052, -2053, -2054, -2082, 3205, -2055, -2056, - 523, -2057, -2058, 1655, 1656, 1657, 1658, 1659, 1660, -2059, - -2061, -2062, 3206, -2063, 1551, 3221, -2064, 525, 3207, 2917, - 3380, 3499, 3382, -2065, 2918, -2066, 1225, 3208, 1365, 1924, - 1925, -2067, 816, 1560, 1152, 1945, -2068, -2070, 1365, 1557, - -2071, 1365, 3223, -2072, 871, -2073, 3238, 3204, -2074, 3460, - 525, 3240, -2075, -2076, -2077, -2078, 525, 525, 3453, 3243, - 818, 3464, -2079, -2080, -2081, -1290, 3210, 2850, 525, 3242, + 3191, -2049, -2050, -2051, -2052, -2053, -2081, 3205, -2054, -2055, + 523, -2056, -2057, 1655, 1656, 1657, 1658, 1659, 1660, -2058, + -2060, -2061, 3206, -2062, 1551, 3221, -2063, 525, 3207, 2917, + 3380, 3499, 3382, -2064, 2918, -2065, 1225, 3208, 1365, 1924, + 1925, -2066, 816, 1560, 1152, 1945, -2067, -2069, 1365, 1557, + -2070, 1365, 3223, -2071, 871, -2072, 3238, 3204, -2073, 3460, + 525, 3240, -2074, -2075, -2076, -2077, 525, 525, 3453, 3243, + 818, 3464, -2078, -2079, -2080, -1289, 3210, 2850, 525, 3242, 3252, 3253, 3211, 2919, 3264, 3219, 3224, 3226, 3246, 3256, 871, 3258, 525, 3270, 3260, 525, 3266, 525, 3267, 3272, 3275, 2920, 3448, 3271, 1560, 525, 2934, 1549, 525, 525, 3279, 3294, 3299, 525, 525, 1053, 3295, 3302, 1926, 3305, 525, 541, 1927, 1928, 3307, 3319, 1929, 1930, 1931, 3320, - 3329, -1289, 1226, 3327, 3335, 525, 3337, 3338, 3351, 3352, - 3353, 2887, 3365, 2829, 3366, 525, -1337, 1365, 521, 532, + 3329, -1288, 1226, 3327, 3335, 525, 3337, 3338, 3351, 3352, + 3353, 2887, 3365, 2829, 3366, 525, -1336, 1365, 521, 532, 2036, 2040, 3369, 3372, 557, 3373, 3375, 2871, 77, 2038, 557, 2039, 2043, 3381, 807, 525, 821, 3386, 3180, 2042, 824, 557, 833, 3406, 3410, 833, 3416, 3412, 852, 856, @@ -4718,7 +4718,7 @@ static const yytype_int16 yytable[] = 0, 0, 0, 0, 0, 0, 0, 0, 1020, 46, 1557, 0, 1230, 0, 0, 33, 0, 0, 0, 719, 0, 0, 0, 0, 1021, 0, 35, 0, 0, 0, - 0, -1811, 3333, 0, 1022, 0, 0, 0, 0, 525, + 0, -1810, 3333, 0, 1022, 0, 0, 0, 0, 525, 0, 0, 0, 3318, 0, 0, 0, 0, 37, 525, 0, 525, 38, 525, 1898, 0, 0, 525, 0, 525, 0, 525, 523, 0, 3325, 3326, 1232, 0, 1023, 0, @@ -4728,33 +4728,33 @@ static const yytype_int16 yytable[] = 719, 0, 0, 0, 0, 525, 3390, 0, 3392, 0, 1235, 1552, 2936, 44, 1024, 2937, 0, 0, 0, 0, 0, 1025, 818, 0, 0, 0, 0, 960, 557, 557, - 0, -1811, 0, 0, 0, 3399, 0, 45, 0, 0, + 0, -1810, 0, 0, 0, 3399, 0, 45, 0, 0, 0, 0, 1018, 0, 0, 1365, 0, 0, 3425, 0, 0, 46, 525, 0, 0, 0, 0, 0, 0, 0, 0, 0, 525, 1026, 3428, 0, 1549, 0, 0, 983, - 532, 0, 0, 0, 525, 521, 0, 856, -1811, 0, + 532, 0, 0, 0, 525, 521, 0, 856, -1810, 0, 0, 0, 1027, 0, 0, 0, 807, 0, 525, 0, - 1009, 1009, 0, -1811, 0, 1009, 1032, 0, -1811, 0, - 0, 0, 0, -1811, 0, 1552, 525, 0, 833, 833, - 833, 523, -1811, 833, 1019, 0, 0, -1811, 0, 0, + 1009, 1009, 0, -1810, 0, 1009, 1032, 0, -1810, 0, + 0, 0, 0, -1810, 0, 1552, 525, 0, 833, 833, + 833, 523, -1810, 833, 1019, 0, 0, -1810, 0, 0, 0, 0, 0, 833, 833, 1776, 833, 0, 833, 0, 525, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 856, 0, 0, 816, 0, 525, 557, 0, 0, -1811, + 856, 0, 0, 816, 0, 525, 557, 0, 0, -1810, 1020, 1028, 0, 523, 2992, 0, 719, 0, 856, 0, - 929, 0, 0, 0, 0, 936, 1021, 0, 937, -1811, + 929, 0, 0, 0, 0, 936, 1021, 0, 937, -1810, 0, 818, 856, 821, 0, 0, 1022, 0, 0, 525, 3099, 0, 0, 0, 0, 816, 0, 0, 0, 3521, 0, 3399, 0, 525, 525, 525, 0, 0, 0, 0, 1431, 1431, 523, 1551, 1549, 0, 0, 856, 1304, 1223, - 1023, 0, 0, 818, 0, 3536, 3505, 0, -1811, 1315, - 525, -1811, 0, 856, 856, 856, 856, -1811, 1557, 1224, + 1023, 0, 0, 818, 0, 3536, 3505, 0, -1810, 1315, + 525, -1810, 0, 856, 856, 856, 856, -1810, 1557, 1224, 0, 0, 0, 0, 816, 0, 2654, 0, 558, 1336, 0, 0, 71, 1552, 558, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 558, 1024, 0, 0, 0, - 0, 525, 818, 1025, 0, 1549, 0, -1811, 0, 558, + 0, 525, 818, 1025, 0, 1549, 0, -1810, 0, 558, 558, 1009, 1032, 0, 856, 1225, 0, 1429, 0, 0, 0, 0, 0, 1009, 1009, 0, 0, 0, 2686, 557, - 0, 0, -1811, 0, 0, 807, 0, 0, 0, 0, + 0, 0, -1810, 0, 0, 807, 0, 0, 0, 0, 0, 0, 807, 0, 0, 1026, 2701, 2840, 2841, 0, 0, 0, 557, 0, 0, 0, 0, 0, 0, 0, 1365, 0, 0, 0, 1027, 1365, 0, 0, 0, 1564, @@ -4762,21 +4762,21 @@ static const yytype_int16 yytable[] = 0, 1551, 0, 0, 0, 0, 0, 0, 0, 0, 858, 1362, 0, 1901, 0, 0, 0, 0, 0, 0, 0, 2740, 0, 2741, 0, 0, 1557, 2746, 0, 2749, - 1549, 1226, 1894, 1896, 0, 0, 0, 0, -1811, 0, - 557, 0, 0, 0, 0, 0, 0, 0, -1811, 0, + 1549, 1226, 1894, 1896, 0, 0, 0, 0, -1810, 0, + 557, 0, 0, 0, 0, 0, 0, 0, -1810, 0, 0, 23, 1552, 1028, 0, 0, 0, 0, 1431, 0, - 1902, 0, 1551, 0, 1552, 0, 0, 0, -1811, 0, - -1811, -1811, 0, 0, 0, 0, 994, 0, 0, 0, + 1902, 0, 1551, 0, 1552, 0, 0, 0, -1810, 0, + -1810, -1810, 0, 0, 0, 0, 994, 0, 0, 0, 1227, 1903, 0, 3086, 0, 0, 0, 1557, 0, 0, 1228, 1685, 0, 1687, 1552, 0, 0, 0, 0, 1904, - 0, 1552, 1229, 1905, 0, 0, 0, -1811, 557, 557, - -1811, -1811, -1811, 0, 0, 856, 71, 870, 0, 0, + 0, 1552, 1229, 1905, 0, 0, 0, -1810, 557, 557, + -1810, -1810, -1810, 0, 0, 856, 71, 870, 0, 0, 0, 0, 0, 0, 0, 0, 1906, 0, 3110, 1907, 1549, 0, 0, 0, 1230, 0, 0, 0, 1429, 1552, 0, 0, 0, 1552, 0, 1908, 0, 0, 0, 1552, 856, 1765, 0, 0, 0, 0, 0, 990, 0, 0, 0, 0, 0, 856, 0, 3056, 0, 1551, 1002, 0, - 0, 1203, 1552, 0, 1554, 0, 0, -1813, 0, 0, + 0, 1203, 1552, 0, 1554, 0, 0, -1812, 0, 0, 856, 0, 0, 3391, 856, 0, 0, 0, 1232, 1813, 1555, 0, 1557, 0, 26, 27, 28, 0, 0, 0, 0, 0, 0, 722, 0, 0, 1303, 0, 0, 1549, @@ -4786,33 +4786,33 @@ static const yytype_int16 yytable[] = 0, 1894, 1896, 0, 0, 0, 1910, 1829, 0, 856, 0, 0, 0, 1365, 0, 0, 0, 0, 856, 0, 723, 33, 0, 0, 0, 1637, 0, 1551, 1911, 1873, - 0, 0, -2082, 1424, 0, 0, 724, -1813, 960, 2985, + 0, 0, -2081, 1424, 0, 0, 724, -1812, 960, 2985, 0, 0, 0, 960, 0, 557, 557, 0, 557, 960, 0, 0, 1557, 0, 0, 0, 0, 1912, 38, 1639, 0, 0, 0, 0, 0, 0, 1053, 0, 0, 1926, 0, 0, 2686, 1927, 1928, 0, 1549, 1929, 1930, 1931, - 0, 0, 0, 0, -1813, 725, 3176, 0, 0, 0, - 0, 40, 0, 0, 0, 726, 0, 0, 0, -1813, - 0, 0, 43, 0, -1813, 71, 1551, 0, 727, -1813, - 1549, 0, 0, 728, 0, 0, 0, 1554, -1813, 44, - 0, 0, 1431, -1813, 2839, 0, 0, 0, 1429, 1429, + 0, 0, 0, 0, -1812, 725, 3176, 0, 0, 0, + 0, 40, 0, 0, 0, 726, 0, 0, 0, -1812, + 0, 0, 43, 0, -1812, 71, 1551, 0, 727, -1812, + 1549, 0, 0, 728, 0, 0, 0, 1554, -1812, 44, + 0, 0, 1431, -1812, 2839, 0, 0, 0, 1429, 1429, 0, 1557, 0, 1555, 1429, 0, 521, 809, 0, 0, 0, 0, 729, 45, 809, 0, 0, 0, 0, 1009, - 0, 557, 1969, 0, 0, -1813, -2082, 46, 0, 856, + 0, 557, 1969, 0, 0, -1812, -2081, 46, 0, 856, 0, 807, 0, 807, 0, 0, 807, 0, 0, 0, - 0, 807, 0, -2082, 807, -1813, 807, 0, -2082, 1567, + 0, 807, 0, -2081, 807, -1812, 807, 0, -2081, 1567, 807, 0, 557, 0, 557, 730, 0, 0, 0, 731, 0, 1579, 1549, 0, 0, 0, 0, 0, 0, 0, 0, 558, 0, 0, 0, 0, 0, 1554, 0, 0, - 0, 0, 0, 1551, 0, 0, -2082, 0, 1606, 0, - 0, 0, 0, 1555, -1813, 0, 0, -1813, 0, 3248, - 0, 0, 0, -1813, 0, 1549, 0, 0, 1557, 0, + 0, 0, 0, 1551, 0, 0, -2081, 0, 1606, 0, + 0, 0, 0, 1555, -1812, 0, 0, -1812, 0, 3248, + 0, 0, 0, -1812, 0, 1549, 0, 0, 1557, 0, 0, 0, 3137, 0, 0, 0, 0, 1551, 0, 1757, 1552, 0, 0, 544, 0, 0, 0, 1932, 0, 732, 0, 0, 1784, 0, 0, 0, 0, 0, 0, 0, - 1365, 1648, 1557, -1813, 733, 0, 0, 0, 0, 0, + 1365, 1648, 1557, -1812, 733, 0, 0, 0, 0, 0, 1933, 0, 0, 1809, 0, 0, 0, 0, 0, 2075, - 0, 0, 0, 0, 0, 0, 0, 0, -1813, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -1812, 0, 0, 2086, 0, 0, 886, 886, 0, 886, 0, 734, 0, 1556, 735, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 736, 0, 0, 737, 0, 0, 1551, @@ -4820,18 +4820,18 @@ static const yytype_int16 yytable[] = 960, 0, 0, 1429, 738, 0, 0, 0, 1834, 0, 1934, 0, 0, 0, 1557, 0, 858, 1853, 739, 0, 0, 0, 0, 0, 740, 741, 0, 0, 0, 0, - 0, 0, 1551, -2082, 0, 742, 0, 0, 0, 0, - 0, 743, 0, 0, -1813, 0, 0, 2175, 1552, 856, - 0, 856, 558, 558, -1813, 0, 0, 1557, 0, 0, + 0, 0, 1551, -2081, 0, 742, 0, 0, 0, 0, + 0, 743, 0, 0, -1812, 0, 0, 2175, 1552, 856, + 0, 856, 558, 558, -1812, 0, 0, 1557, 0, 0, 0, 856, 0, 2191, 0, 0, 0, 0, 0, 744, - 3225, 0, 0, 0, -1813, 1429, -1813, -1813, 0, 0, + 3225, 0, 0, 0, -1812, 1429, -1812, -1812, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1362, 0, 0, 856, 0, 557, 1555, 0, 0, 0, 0, 0, 1552, - 0, 0, 0, -1813, 2242, 2244, -1813, -1813, -1813, 0, + 0, 0, 0, -1812, 2242, 2244, -1812, -1812, -1812, 0, 1765, 557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 557, 2261, 557, 2265, 1551, 557, 71, 0, 0, - 0, -2082, 557, 0, 557, 0, 0, 0, 1655, 1656, + 0, -2081, 557, 0, 557, 0, 0, 0, 1655, 1656, 1657, 1658, 1659, 1660, 1556, 0, 960, 557, 1981, 0, 1557, 960, 557, 0, 0, 0, 557, 557, 557, 557, 558, 557, 557, 0, 0, 0, 0, 0, 3292, 0, @@ -4844,7 +4844,7 @@ static const yytype_int16 yytable[] = 0, 0, 0, 809, 1556, 809, 0, 2985, 809, 0, 0, 0, 0, 809, 0, 1549, 809, 0, 809, 0, 0, 0, 809, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, -1828, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -1827, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1429, 1429, 1429, 1429, 1429, 1429, 0, 0, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 0, 0, 0, 0, @@ -4854,49 +4854,49 @@ static const yytype_int16 yytable[] = 0, 0, 0, 0, 0, 71, 0, 0, 807, 0, 0, 0, 0, 0, 807, 0, 0, 0, 0, 0, 557, 0, 0, 0, 0, 557, 0, 0, 0, 0, - 0, 0, 3418, -1828, 2490, 2490, 0, 0, 0, 0, + 0, 0, 3418, -1827, 2490, 2490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2176, 0, 2178, 0, 1551, 1552, 0, 0, 0, 0, 1626, 0, 2188, 1627, 0, 0, 1611, 1628, 1629, 1630, 1631, 1632, 1633, 1634, 0, 0, 0, 0, 0, 1557, 0, 0, - -1828, 0, 0, 0, 0, 2123, 1635, 0, 0, 0, - 0, 0, 0, 0, 0, -1828, 1637, 0, 0, 2225, - -1828, 0, 0, 1638, 0, -1828, 557, 0, 0, 0, - 2528, 0, 0, 0, -1828, 557, 0, 0, 0, -1828, + -1827, 0, 0, 0, 0, 2123, 1635, 0, 0, 0, + 0, 0, 0, 0, 0, -1827, 1637, 0, 0, 2225, + -1827, 0, 0, 1638, 0, -1827, 557, 0, 0, 0, + 2528, 0, 0, 0, -1827, 557, 0, 0, 0, -1827, 0, 0, 0, 0, 1556, 0, 0, 0, 1554, 0, 1639, 0, 558, 558, 0, 0, 0, 0, 1429, 1429, 1554, 0, 0, 0, 1555, 0, 0, 0, 0, 0, - 0, -1828, 0, 0, 886, 0, 1555, 2075, 1626, 0, + 0, -1827, 0, 0, 886, 0, 1555, 2075, 1626, 0, 1552, 1627, 0, 1429, 2985, 1628, 1629, 0, 0, 0, - 1554, -1828, 1053, 0, 0, 1926, 0, 1554, 0, 1927, + 1554, -1827, 1053, 0, 0, 1926, 0, 1554, 0, 1927, 1928, 0, 0, 1929, 1930, 1931, 1555, 0, 0, 0, 807, 0, 0, 1555, 1552, 0, 1637, 2335, 2336, 2338, - 2339, 2340, 557, -2082, 0, 0, 0, 807, 0, 0, + 2339, 2340, 557, -2081, 0, 0, 0, 807, 0, 0, 0, 2191, 0, 0, 0, 1554, 0, 0, 1556, 1554, - -1828, 0, 0, -1828, 0, 1554, 0, 1640, 0, -1828, + -1827, 0, 0, -1827, 0, 1554, 0, 1640, 0, -1827, 1639, 1555, 0, 0, 0, 1555, 0, 0, 0, 0, 0, 1555, 0, 0, 1641, 0, 0, 0, 1554, 1642, 0, 557, 0, 0, 1429, 0, 0, 557, 0, 0, - 0, 0, 0, 0, 1555, 0, 0, 0, 0, -1828, + 0, 0, 0, 0, 1555, 0, 0, 0, 0, -1827, 0, 0, 1643, 1644, 0, 0, 1552, 1829, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1645, 0, 0, - 0, 2344, 0, 0, -1828, 2842, 0, 0, 0, 0, + 0, 2344, 0, 0, -1827, 2842, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 558, 558, 0, 558, 0, 0, 0, 0, 0, 0, 1552, - 0, 0, 0, 0, 0, 1646, 0, -2082, 1647, 0, + 0, 0, 0, 0, 0, 1646, 0, -2081, 1647, 0, 0, 0, 0, 0, 0, 0, 0, 2461, 0, 0, - 0, 0, 1648, 0, -2082, 1649, 0, 0, 1829, -2082, + 0, 0, 1648, 0, -2081, 1649, 0, 0, 1829, -2081, 0, 0, 858, 0, 0, 856, 1556, 0, 0, 0, 0, 0, 0, 2236, 0, 0, 1315, 0, 0, 1829, 856, 856, 856, 0, 0, 0, 0, 0, 0, 0, - -1828, 0, 0, 557, 0, 856, 1933, -2082, 856, 0, - -1828, 0, 0, 0, 0, 856, 0, 0, 0, 0, + -1827, 0, 0, 557, 0, 856, 1933, -2081, 856, 0, + -1827, 0, 0, 0, 0, 856, 0, 0, 0, 0, 0, 960, 0, 0, 0, 0, 0, 0, 0, 0, - -1828, 0, -1828, -1828, 0, 558, 0, 0, 0, 0, + -1827, 0, -1827, -1827, 0, 558, 0, 0, 0, 0, 0, 0, 1552, 1829, 1829, 0, 1829, 0, 0, 0, 809, 0, 0, 0, 0, 0, 809, 0, 0, 0, - 0, 0, 1648, 0, 1650, 0, 2001, 0, 2005, -1828, - 0, 0, -1828, -1828, -1828, 521, 1934, 0, 0, 0, + 0, 0, 1648, 0, 1650, 0, 2001, 0, 2005, -1827, + 0, 0, -1827, -1827, -1827, 521, 1934, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2763, 0, 0, 0, 0, 0, 0, 0, 856, 856, 856, 0, 0, 0, 0, @@ -4905,7 +4905,7 @@ static const yytype_int16 yytable[] = 0, 1926, 0, 0, 0, 1927, 1928, 1556, 0, 1929, 1930, 1931, 0, 856, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2830, 2075, 0, 0, - 0, 0, 0, 0, -2082, 0, 0, 1556, 0, 0, + 0, 0, 0, 0, -2081, 0, 0, 1556, 0, 0, 0, 0, 1651, 0, 1556, 1652, 1653, 1654, 0, 1655, 1656, 1657, 1658, 1659, 1660, 1606, 1554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1429, 1429, 2513, 0, @@ -4916,7 +4916,7 @@ static const yytype_int16 yytable[] = 0, 0, 0, 0, 0, 1556, 0, 856, 0, 809, 0, 557, 0, 0, 0, 557, 557, 0, 0, 557, 0, 0, 0, 1829, 1765, 1829, 0, 1873, 0, 0, - 0, 0, -2082, 0, 0, 0, 0, 0, 0, 1655, + 0, 0, -2081, 0, 0, 0, 0, 0, 0, 1655, 1656, 1657, 1658, 1659, 1660, 0, 557, 0, 2944, 1935, 1936, 1937, 0, 1938, 1939, 1940, 1941, 1942, 1943, 1552, 0, 557, 557, 557, 557, 557, 557, 557, 557, 557, @@ -4936,35 +4936,35 @@ static const yytype_int16 yytable[] = 0, 0, 2770, 2771, 2772, 0, 0, 0, 11, 1432, 0, 0, 0, 0, 1626, 0, 0, 1627, 0, 0, 0, 1628, 1629, 3108, 0, 2528, 0, 1626, 0, 0, - 1627, 0, 0, 0, 1628, 1629, 14, 15, -2082, -2082, - -2082, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1554, 0, 1637, 0, 3132, 0, 807, 0, 0, -2082, + 1627, 0, 0, 0, 1628, 1629, 14, 15, -2081, -2081, + -2081, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1554, 0, 1637, 0, 3132, 0, 807, 0, 0, -2081, 0, 0, 1016, 0, 0, 1637, 1555, 1017, 0, 0, 3144, 0, 1638, 0, 2191, 0, 0, 0, 0, 0, 2075, 0, 23, 0, 1626, 0, 1639, 1627, 0, 0, 0, 1628, 1629, 0, 1765, 0, 0, 0, 0, 1639, 1829, 0, 0, 0, 0, 0, 0, 0, 0, 0, 558, 0, 0, 960, 557, 1429, 0, 0, 0, 0, - 0, 856, 1637, 1556, 0, 0, 1018, 0, 0, -2082, + 0, 856, 1637, 1556, 0, 0, 1018, 0, 0, -2081, 0, 0, 0, 0, 0, 0, 0, 0, 3195, 0, 0, 0, 0, 0, 2477, 0, 2882, 0, 1606, 2005, 1554, 2843, 0, 0, 0, 0, 1639, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1555, 0, 0, 1626, 0, 0, 1627, 0, 0, 0, 1628, 1629, 1630, 1631, - 1632, 1633, 1634, -2082, 1606, 1935, 1936, 1937, 0, 1938, + 1632, 1633, 1634, -2081, 1606, 1935, 1936, 1937, 0, 1938, 1939, 1940, 1941, 1942, 1943, 0, 1640, 1635, 1019, 0, - -2082, 0, 0, 71, 0, -2082, 1196, 1637, 0, 71, + -2081, 0, 0, 71, 0, -2081, 1196, 1637, 0, 71, 1432, 0, 0, 1641, 1638, 0, 3212, 0, 1642, 0, 1829, 3122, 0, 0, 0, 26, 27, 28, 0, 1554, 558, 0, 0, 2352, 1020, 2886, 0, 0, 0, 1611, - 3025, 1639, 0, -2082, 0, 1555, 0, 0, 0, 0, - 1021, 3244, 0, -2082, 0, 0, 1645, 0, 1429, 0, + 3025, 1639, 0, -2081, 0, 1555, 0, 0, 0, 0, + 1021, 3244, 0, -2081, 0, 0, 1645, 0, 1429, 0, 1022, 1556, 0, 0, 0, 0, 0, 0, 0, 0, - -2082, 0, 0, 0, 1053, -2082, 0, 1926, 0, 0, + -2081, 0, 0, 0, 1053, -2081, 0, 1926, 0, 0, 0, 1927, 1928, 0, 3261, 1929, 1930, 1931, 0, 0, 557, 0, 33, 0, 1023, 0, 0, 557, 1648, 0, 0, 0, 3118, 35, 0, 0, 3065, 3066, 3067, 3068, - 0, 1648, 0, -2082, 0, 1197, 0, 71, 0, 0, + 0, 1648, 0, -2081, 0, 1197, 0, 71, 0, 0, 0, 0, 1556, 0, 0, 37, 558, 0, 0, 38, 0, 0, 3289, 0, 0, 0, 1554, 0, 1640, 0, 1024, 0, 0, 0, 0, 0, 71, 1025, 0, 39, @@ -4973,24 +4973,24 @@ static const yytype_int16 yytable[] = 1554, 0, 0, 43, 0, 558, 0, 0, 0, 0, 0, 2613, 0, 1643, 1644, 557, 1555, 0, 0, 1026, 44, 0, 0, 0, 0, 0, 0, 0, 1645, 0, - -2082, 1606, 0, 0, 0, 0, 557, 557, 1027, 0, + -2081, 1606, 0, 0, 0, 0, 557, 557, 1027, 0, 1115, 1115, 0, 1650, 45, 0, 0, 0, 0, 0, 0, 0, 0, 856, 0, 1765, 0, 1556, 46, 0, 557, 0, 0, 0, 0, 0, 1646, 0, 0, 1647, 1432, 1432, 0, 0, 856, 0, 1432, 3360, 0, 0, 0, 0, 1554, 1648, 0, 0, 1649, 0, 0, 0, 3182, 0, 0, 0, 0, 0, 0, 1429, 1555, 0, - -2082, 557, 1009, 0, 1009, 0, 0, 1028, 809, 0, + -2081, 557, 1009, 0, 1009, 0, 0, 1028, 809, 0, 0, 1252, 1198, 0, 0, 1294, 1301, 0, 1933, 0, 0, 0, 870, 0, 0, 1554, 0, 0, 0, 3144, - 0, 0, 0, 0, 0, 0, 856, 558, -2082, 0, + 0, 0, 0, 0, 0, 0, 856, 558, -2081, 0, 0, 1555, 0, 0, 0, 1655, 1656, 1657, 1658, 1659, - 1660, 1651, 0, 0, -2082, -2082, -2082, 1556, 1655, 1656, + 1660, 1651, 0, 0, -2081, -2081, -2081, 1556, 1655, 1656, 1657, 1658, 1659, 1660, 1053, 0, 856, 1926, 1351, 0, 0, 1927, 1928, 0, 0, 1929, 1930, 1931, 0, 0, 0, 0, 0, 0, 0, 1650, 1375, 0, 1934, 0, 0, 0, 1423, 0, 0, 1425, 0, 0, 1436, 1439, - 1444, 1447, 0, 0, 3261, 0, 0, 0, -2082, 0, + 1444, 1447, 0, 0, 3261, 0, 0, 0, -2081, 0, 0, 0, 0, 0, 0, 1655, 1656, 1657, 1658, 1659, 1660, 0, 0, 0, 0, 0, 3360, 0, 1554, 0, 0, 0, 0, 0, 0, 0, 1556, 0, 1486, 1294, @@ -5032,7 +5032,7 @@ static const yytype_int16 yytable[] = 71, 1227, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1228, 0, 0, 1053, 1556, 71, 1926, 0, 0, 0, 1927, 1928, 1229, 0, 1929, 1930, 1931, 0, 0, - 0, 0, 0, 0, 0, -2082, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -2081, 0, 0, 0, 0, 0, 0, 3119, 0, 1213, 0, 0, 0, 0, 0, 1444, 0, 1444, 1444, 0, 1230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1115, 1115, 0, 0, 0, @@ -5068,15 +5068,15 @@ static const yytype_int16 yytable[] = 0, 0, 0, 0, 0, 0, 0, 13, 1641, 558, 0, 0, 0, 1642, 0, 0, 0, 0, 0, 0, 0, 0, 14, 15, 16, 0, 0, 0, 0, 0, - 558, 558, 0, 17, 0, 0, -2082, -2082, 0, 18, + 558, 558, 0, 17, 0, 0, -2081, -2081, 0, 18, 0, 0, 0, 0, 0, 0, 0, 19, 0, 20, 21, 1645, 0, 0, 558, 0, 0, 1433, 0, 0, 0, 0, 0, 0, 22, 0, 2306, 0, 23, 0, 1294, 0, 1625, 2316, 2317, 0, 0, 1626, 0, 0, 1627, 0, 0, 0, 1628, 1629, 1630, 1631, 1632, 1633, - 1634, 0, -2082, 0, 24, 558, 0, 0, 0, 0, + 1634, 0, -2081, 0, 24, 558, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1635, 1648, 0, 0, 1636, - -1446, 0, 0, 0, 1294, 1637, 0, 0, 0, 0, + -1445, 0, 0, 0, 1294, 1637, 0, 0, 0, 0, 0, 0, 1638, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 1351, 2383, 0, 0, 0, 0, 0, 0, 0, 0, 1639, @@ -5842,8 +5842,8 @@ static const yytype_int16 yytable[] = 0, 1096, 1097, 1098, 1099, 117, 1050, 820, 1051, 1052, 1053, 1054, 1055, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 118, 119, 120, 121, 122, 123, - 124, 125, -1132, 126, 127, 128, 0, 0, 0, 0, - -1132, 1056, 0, 0, 129, 130, 131, 0, 132, 133, + 124, 125, -1131, 126, 127, 128, 0, 0, 0, 0, + -1131, 1056, 0, 0, 129, 130, 131, 0, 132, 133, 134, 135, 136, 137, 138, 139, 1057, 141, 1058, 1059, 0, 144, 145, 146, 147, 148, 149, 1060, 790, 150, 151, 152, 153, 1061, 1062, 156, 0, 157, 158, 159, @@ -5879,7 +5879,7 @@ static const yytype_int16 yytable[] = 1084, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 0, 0, 421, 422, 423, 424, 425, 426, 427, 428, 429, 0, 430, 431, 432, 1085, - 434, -1132, 435, 436, 437, 438, 439, 440, 441, 442, + 434, -1131, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 800, 0, 0, 450, 451, 0, 452, 453, 454, 455, 456, 457, 458, 0, 459, 1086, 1087, 0, 0, 462, 463, 801, 465, 802, @@ -6892,7 +6892,7 @@ static const yytype_int16 yytable[] = 0, 0, 0, 0, 118, 119, 120, 121, 122, 123, 124, 125, 0, 126, 127, 128, 0, 0, 0, 0, 0, 1056, 0, 0, 129, 130, 131, 0, 132, 133, - 134, 135, 136, 137, 138, -2082, 1057, 141, 1058, 1059, + 134, 135, 136, 137, 138, -2081, 1057, 141, 1058, 1059, 0, 144, 145, 146, 147, 148, 149, 1060, 790, 150, 151, 152, 153, 1061, 1062, 156, 0, 157, 158, 159, 160, 791, 0, 792, 0, 1063, 164, 165, 166, 167, @@ -6904,13 +6904,13 @@ static const yytype_int16 yytable[] = 210, 0, 211, 212, 213, 0, 214, 215, 216, 0, 217, 218, 219, 220, 1068, 222, 223, 224, 225, 226, 227, 793, 1069, 229, 0, 230, 231, 1070, 233, 0, - 234, 0, 235, 236, 0, 237, 238, 239, 240, -2082, + 234, 0, 235, 236, 0, 237, 238, 239, 240, -2081, 242, 0, 243, 0, 1071, 1072, 246, 247, 0, 248, - 249, 250, 251, 252, 253, 254, -2082, 256, 257, 258, + 249, 250, 251, 252, 253, 254, -2081, 256, 257, 258, 259, 0, 260, 261, 262, 263, 264, 265, 266, 0, 267, 268, 269, 270, 271, 272, 273, 274, 1073, 1074, 0, 1075, 0, 278, 0, 0, 281, 282, 283, 284, - 285, 286, 287, 288, 0, 0, 289, 290, 291, -2082, + 285, 286, 287, 288, 0, 0, 289, 290, 291, -2081, 0, 293, 294, 295, 296, 297, 298, 299, 300, 1076, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, @@ -6926,7 +6926,7 @@ static const yytype_int16 yytable[] = 398, 399, 400, 0, 401, 402, 403, 404, 405, 406, 1084, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 0, 0, 421, 422, 423, 424, - 425, 426, 427, 428, 429, 0, -2082, 431, 432, 1085, + 425, 426, 427, 428, 429, 0, -2081, 431, 432, 1085, 434, 0, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 800, 0, 0, 450, 451, 0, 452, 453, 454, 455, 456, 457, 458, 0, @@ -6937,7 +6937,7 @@ static const yytype_int16 yytable[] = 491, 492, 493, 494, 495, 496, 497, 498, 0, 0, 499, 0, 0, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, - 517, 518, 519, 520, -2082, 0, 0, 0, 0, 0, + 517, 518, 519, 520, -2081, 0, 0, 0, 0, 0, 0, 1091, 1092, 1093, 0, 0, 0, 0, 1094, 0, 1095, 0, 0, 0, 0, 1096, 1097, 1098, 1099, 117, 1050, 820, 1051, 1052, 0, 1054, 1055, 0, 0, 0, @@ -7064,7 +7064,7 @@ static const yytype_int16 yytable[] = 233, 0, 234, 0, 235, 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, 3090, 1071, 1072, 246, 247, 0, 248, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, -733, 260, 261, 262, 263, 264, 265, + 257, 258, 259, 0, 260, 261, 262, 263, 264, 265, 266, 0, 267, 268, 269, 270, 271, 272, 273, 274, 1073, 1074, 0, 1075, 0, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 0, 0, 289, 290, @@ -10799,7 +10799,7 @@ static const yytype_int16 yytable[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 118, 119, 120, 121, 122, 123, 124, 125, 0, 126, 127, 128, 0, 0, 0, 1491, 0, - 0, -803, 0, 1492, 130, 131, 0, 132, 133, 134, + 0, -802, 0, 1492, 130, 131, 0, 132, 133, 134, 1493, 136, 137, 138, 0, 1494, 1495, 1496, 1497, 0, 144, 145, 146, 147, 148, 149, 0, 0, 150, 151, 152, 153, 1498, 1499, 156, 0, 157, 158, 159, 160, @@ -10812,7 +10812,7 @@ static const yytype_int16 yytable[] = 0, 211, 212, 213, 0, 214, 215, 216, 0, 217, 218, 219, 220, 0, 222, 223, 224, 225, 226, 227, 0, 0, 229, 0, 230, 231, 1506, 233, 0, 234, - 0, 235, 1507, 0, 1508, 238, 239, -803, 1509, 242, + 0, 235, 1507, 0, 1508, 238, 239, -802, 1509, 242, 0, 243, 0, 0, 0, 246, 247, 0, 248, 249, 250, 251, 252, 253, 254, 1510, 256, 257, 258, 259, 0, 260, 261, 262, 263, 264, 265, 266, 0, 267, @@ -11654,9 +11654,9 @@ static const yytype_int16 yytable[] = 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, -1446, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -1445, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, -1446, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -1445, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -14360,7 +14360,7 @@ static const yytype_int16 yycheck[] = 166, -1, 168, -1, 170, 171, -1, 173, 174, 175, 176, 177, 178, -1, 180, 181, 182, 183, 184, 185, -1, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, + 196, 197, 198, -1, 200, 201, 202, 203, 204, 205, 206, -1, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, -1, 219, -1, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, -1, -1, 234, 235, @@ -25435,22 +25435,22 @@ YYLTYPE yylloc; ;} break; - case 734: + case 733: #line 1135 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 735: + case 734: #line 1136 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 736: + case 735: #line 1137 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(2) - (3)].list); ;} break; - case 737: + case 736: #line 1141 "third_party/libpg_query/grammar/statements/select.y" { PGPivot *n = makeNode(PGPivot); @@ -25460,7 +25460,7 @@ YYLTYPE yylloc; ;} break; - case 738: + case 737: #line 1149 "third_party/libpg_query/grammar/statements/select.y" { PGPivot *n = makeNode(PGPivot); @@ -25470,31 +25470,31 @@ YYLTYPE yylloc; ;} break; - case 739: + case 738: #line 1158 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 740: + case 739: #line 1162 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node)); ;} break; - case 741: + case 740: #line 1168 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;} break; - case 742: + case 741: #line 1169 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(2) - (3)].list); ;} break; - case 743: + case 742: #line 1174 "third_party/libpg_query/grammar/statements/select.y" { PGPivot *n = makeNode(PGPivot); @@ -25504,28 +25504,28 @@ YYLTYPE yylloc; ;} break; - case 744: + case 743: #line 1183 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 745: + case 744: #line 1187 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node)); ;} break; - case 746: + case 745: #line 1212 "third_party/libpg_query/grammar/statements/select.y" { (yyval.jexpr) = (yyvsp[(2) - (3)].jexpr); ;} break; - case 747: + case 746: #line 1216 "third_party/libpg_query/grammar/statements/select.y" { /* CROSS JOIN is same as unqualified inner join */ @@ -25541,7 +25541,7 @@ YYLTYPE yylloc; ;} break; - case 748: + case 747: #line 1229 "third_party/libpg_query/grammar/statements/select.y" { PGJoinExpr *n = makeNode(PGJoinExpr); @@ -25558,7 +25558,7 @@ YYLTYPE yylloc; ;} break; - case 749: + case 748: #line 1243 "third_party/libpg_query/grammar/statements/select.y" { /* letting join_type reduce to empty doesn't work */ @@ -25576,7 +25576,7 @@ YYLTYPE yylloc; ;} break; - case 750: + case 749: #line 1258 "third_party/libpg_query/grammar/statements/select.y" { PGJoinExpr *n = makeNode(PGJoinExpr); @@ -25591,7 +25591,7 @@ YYLTYPE yylloc; ;} break; - case 751: + case 750: #line 1270 "third_party/libpg_query/grammar/statements/select.y" { /* letting join_type reduce to empty doesn't work */ @@ -25607,7 +25607,7 @@ YYLTYPE yylloc; ;} break; - case 752: + case 751: #line 1283 "third_party/libpg_query/grammar/statements/select.y" { PGJoinExpr *n = makeNode(PGJoinExpr); @@ -25624,7 +25624,7 @@ YYLTYPE yylloc; ;} break; - case 753: + case 752: #line 1297 "third_party/libpg_query/grammar/statements/select.y" { PGJoinExpr *n = makeNode(PGJoinExpr); @@ -25641,7 +25641,7 @@ YYLTYPE yylloc; ;} break; - case 754: + case 753: #line 1311 "third_party/libpg_query/grammar/statements/select.y" { /* POSITIONAL JOIN is a coordinated scan */ @@ -25657,7 +25657,7 @@ YYLTYPE yylloc; ;} break; - case 755: + case 754: #line 1324 "third_party/libpg_query/grammar/statements/select.y" { /* ANTI JOIN is a filter */ @@ -25675,7 +25675,7 @@ YYLTYPE yylloc; ;} break; - case 756: + case 755: #line 1339 "third_party/libpg_query/grammar/statements/select.y" { /* SEMI JOIN is also a filter */ @@ -25694,7 +25694,7 @@ YYLTYPE yylloc; ;} break; - case 757: + case 756: #line 1358 "third_party/libpg_query/grammar/statements/select.y" { (yyval.alias) = makeNode(PGAlias); @@ -25703,7 +25703,7 @@ YYLTYPE yylloc; ;} break; - case 758: + case 757: #line 1364 "third_party/libpg_query/grammar/statements/select.y" { (yyval.alias) = makeNode(PGAlias); @@ -25711,7 +25711,7 @@ YYLTYPE yylloc; ;} break; - case 759: + case 758: #line 1369 "third_party/libpg_query/grammar/statements/select.y" { (yyval.alias) = makeNode(PGAlias); @@ -25720,7 +25720,7 @@ YYLTYPE yylloc; ;} break; - case 760: + case 759: #line 1375 "third_party/libpg_query/grammar/statements/select.y" { (yyval.alias) = makeNode(PGAlias); @@ -25728,31 +25728,31 @@ YYLTYPE yylloc; ;} break; - case 761: + case 760: #line 1381 "third_party/libpg_query/grammar/statements/select.y" { (yyval.alias) = (yyvsp[(1) - (1)].alias); ;} break; - case 762: + case 761: #line 1382 "third_party/libpg_query/grammar/statements/select.y" { (yyval.alias) = NULL; ;} break; - case 763: + case 762: #line 1391 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2((yyvsp[(1) - (1)].alias), NIL); ;} break; - case 764: + case 763: #line 1395 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2(NULL, (yyvsp[(3) - (4)].list)); ;} break; - case 765: + case 764: #line 1399 "third_party/libpg_query/grammar/statements/select.y" { PGAlias *a = makeNode(PGAlias); @@ -25761,7 +25761,7 @@ YYLTYPE yylloc; ;} break; - case 766: + case 765: #line 1405 "third_party/libpg_query/grammar/statements/select.y" { PGAlias *a = makeNode(PGAlias); @@ -25770,64 +25770,64 @@ YYLTYPE yylloc; ;} break; - case 767: + case 766: #line 1411 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2(NULL, NIL); ;} break; - case 768: + case 767: #line 1416 "third_party/libpg_query/grammar/statements/select.y" { (yyval.jtype) = PG_JOIN_FULL; ;} break; - case 769: + case 768: #line 1417 "third_party/libpg_query/grammar/statements/select.y" { (yyval.jtype) = PG_JOIN_LEFT; ;} break; - case 770: + case 769: #line 1418 "third_party/libpg_query/grammar/statements/select.y" { (yyval.jtype) = PG_JOIN_RIGHT; ;} break; - case 771: + case 770: #line 1419 "third_party/libpg_query/grammar/statements/select.y" { (yyval.jtype) = PG_JOIN_SEMI; ;} break; - case 772: + case 771: #line 1420 "third_party/libpg_query/grammar/statements/select.y" { (yyval.jtype) = PG_JOIN_ANTI; ;} break; - case 773: + case 772: #line 1421 "third_party/libpg_query/grammar/statements/select.y" { (yyval.jtype) = PG_JOIN_INNER; ;} break; - case 774: + case 773: #line 1425 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 775: + case 774: #line 1426 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 776: + case 775: #line 1438 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) (yyvsp[(3) - (4)].list); ;} break; - case 777: + case 776: #line 1439 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 778: + case 777: #line 1445 "third_party/libpg_query/grammar/statements/select.y" { /* inheritance query, implicitly */ @@ -25837,7 +25837,7 @@ YYLTYPE yylloc; ;} break; - case 779: + case 778: #line 1452 "third_party/libpg_query/grammar/statements/select.y" { /* inheritance query, explicitly */ @@ -25847,7 +25847,7 @@ YYLTYPE yylloc; ;} break; - case 780: + case 779: #line 1459 "third_party/libpg_query/grammar/statements/select.y" { /* no inheritance */ @@ -25857,7 +25857,7 @@ YYLTYPE yylloc; ;} break; - case 781: + case 780: #line 1466 "third_party/libpg_query/grammar/statements/select.y" { /* no inheritance, SQL99-style syntax */ @@ -25867,7 +25867,7 @@ YYLTYPE yylloc; ;} break; - case 782: + case 781: #line 1498 "third_party/libpg_query/grammar/statements/select.y" { PGRangeFunction *n = makeNode(PGRangeFunction); @@ -25881,7 +25881,7 @@ YYLTYPE yylloc; ;} break; - case 783: + case 782: #line 1509 "third_party/libpg_query/grammar/statements/select.y" { PGRangeFunction *n = makeNode(PGRangeFunction); @@ -25895,66 +25895,66 @@ YYLTYPE yylloc; ;} break; - case 784: + case 783: #line 1522 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].list)); ;} break; - case 785: + case 784: #line 1526 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].list)); ;} break; - case 786: + case 785: #line 1527 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); ;} break; - case 787: + case 786: #line 1530 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (4)].list); ;} break; - case 788: + case 787: #line 1531 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 789: + case 788: #line 1534 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = true; ;} break; - case 790: + case 789: #line 1535 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = false; ;} break; - case 791: + case 790: #line 1540 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 792: + case 791: #line 1541 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 793: + case 792: #line 1547 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 794: + case 793: #line 1551 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;} break; - case 795: + case 794: #line 1557 "third_party/libpg_query/grammar/statements/select.y" { PGColumnDef *n = makeNode(PGColumnDef); @@ -25975,7 +25975,7 @@ YYLTYPE yylloc; ;} break; - case 796: + case 795: #line 1578 "third_party/libpg_query/grammar/statements/select.y" { PGCollateClause *n = makeNode(PGCollateClause); @@ -25986,36 +25986,36 @@ YYLTYPE yylloc; ;} break; - case 797: + case 796: #line 1585 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 798: + case 797: #line 1598 "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 799: + case 798: #line 1601 "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 802: + case 801: #line 1608 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 803: + case 802: #line 1609 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = NULL; ;} break; - case 804: + case 803: #line 1612 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (2)].typnam); @@ -26023,7 +26023,7 @@ YYLTYPE yylloc; ;} break; - case 805: + case 804: #line 1617 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(2) - (3)].typnam); @@ -26032,7 +26032,7 @@ YYLTYPE yylloc; ;} break; - case 806: + case 805: #line 1624 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (5)].typnam); @@ -26040,7 +26040,7 @@ YYLTYPE yylloc; ;} break; - case 807: + case 806: #line 1629 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(2) - (6)].typnam); @@ -26049,7 +26049,7 @@ YYLTYPE yylloc; ;} break; - case 808: + case 807: #line 1635 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (2)].typnam); @@ -26057,7 +26057,7 @@ YYLTYPE yylloc; ;} break; - case 809: + case 808: #line 1640 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(2) - (3)].typnam); @@ -26066,14 +26066,14 @@ YYLTYPE yylloc; ;} break; - case 810: + case 809: #line 1646 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = makeTypeNameFromNameList((yyvsp[(1) - (1)].list)); ;} break; - case 811: + case 810: #line 1650 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("struct"); @@ -26083,7 +26083,7 @@ YYLTYPE yylloc; ;} break; - case 812: + case 811: #line 1657 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("map"); @@ -26093,7 +26093,7 @@ YYLTYPE yylloc; ;} break; - case 813: + case 812: #line 1664 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("union"); @@ -26103,57 +26103,57 @@ YYLTYPE yylloc; ;} break; - case 814: + case 813: #line 1673 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2(makeString((yyvsp[(1) - (3)].str)), makeString((yyvsp[(3) - (3)].str))); ;} break; - case 815: + case 814: #line 1674 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), makeString((yyvsp[(3) - (3)].str))); ;} break; - case 816: + case 815: #line 1679 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), makeInteger(-1)); ;} break; - case 817: + case 816: #line 1681 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (4)].list), makeInteger((yyvsp[(3) - (4)].ival))); ;} break; - case 818: + case 817: #line 1683 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 819: + case 818: #line 1687 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 820: + case 819: #line 1688 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 821: + case 820: #line 1689 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 822: + case 821: #line 1690 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 823: + case 822: #line 1691 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 824: + case 823: #line 1693 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (2)].typnam); @@ -26161,7 +26161,7 @@ YYLTYPE yylloc; ;} break; - case 825: + case 824: #line 1698 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (4)].typnam); @@ -26170,27 +26170,27 @@ YYLTYPE yylloc; ;} break; - case 826: + case 825: #line 1717 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 827: + case 826: #line 1718 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 828: + case 827: #line 1719 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 829: + case 828: #line 1720 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 830: + case 829: #line 1732 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = makeTypeName((yyvsp[(1) - (2)].str)); @@ -26199,17 +26199,17 @@ YYLTYPE yylloc; ;} break; - case 831: + case 830: #line 1745 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(2) - (3)].list); ;} break; - case 832: + case 831: #line 1746 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 833: + case 832: #line 1753 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("int4"); @@ -26217,7 +26217,7 @@ YYLTYPE yylloc; ;} break; - case 834: + case 833: #line 1758 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("int4"); @@ -26225,7 +26225,7 @@ YYLTYPE yylloc; ;} break; - case 835: + case 834: #line 1763 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("int2"); @@ -26233,7 +26233,7 @@ YYLTYPE yylloc; ;} break; - case 836: + case 835: #line 1768 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("int8"); @@ -26241,7 +26241,7 @@ YYLTYPE yylloc; ;} break; - case 837: + case 836: #line 1773 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("float4"); @@ -26249,7 +26249,7 @@ YYLTYPE yylloc; ;} break; - case 838: + case 837: #line 1778 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(2) - (2)].typnam); @@ -26257,7 +26257,7 @@ YYLTYPE yylloc; ;} break; - case 839: + case 838: #line 1783 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("float8"); @@ -26265,7 +26265,7 @@ YYLTYPE yylloc; ;} break; - case 840: + case 839: #line 1788 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("numeric"); @@ -26274,7 +26274,7 @@ YYLTYPE yylloc; ;} break; - case 841: + case 840: #line 1794 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("numeric"); @@ -26283,7 +26283,7 @@ YYLTYPE yylloc; ;} break; - case 842: + case 841: #line 1800 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("numeric"); @@ -26292,7 +26292,7 @@ YYLTYPE yylloc; ;} break; - case 843: + case 842: #line 1806 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("bool"); @@ -26300,7 +26300,7 @@ YYLTYPE yylloc; ;} break; - case 844: + case 843: #line 1813 "third_party/libpg_query/grammar/statements/select.y" { /* @@ -26324,35 +26324,35 @@ YYLTYPE yylloc; ;} break; - case 845: + case 844: #line 1834 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("float4"); ;} break; - case 846: + case 845: #line 1844 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 847: + case 846: #line 1848 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 848: + case 847: #line 1856 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 849: + case 848: #line 1860 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); @@ -26360,7 +26360,7 @@ YYLTYPE yylloc; ;} break; - case 850: + case 849: #line 1868 "third_party/libpg_query/grammar/statements/select.y" { const char *typname; @@ -26372,7 +26372,7 @@ YYLTYPE yylloc; ;} break; - case 851: + case 850: #line 1880 "third_party/libpg_query/grammar/statements/select.y" { /* bit defaults to bit(1), varbit to no limit */ @@ -26389,28 +26389,28 @@ YYLTYPE yylloc; ;} break; - case 852: + case 851: #line 1901 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 853: + case 852: #line 1905 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 854: + case 853: #line 1911 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 855: + case 854: #line 1915 "third_party/libpg_query/grammar/statements/select.y" { /* Length was not specified so allow to be unrestricted. @@ -26424,7 +26424,7 @@ YYLTYPE yylloc; ;} break; - case 856: + case 855: #line 1928 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName((yyvsp[(1) - (4)].conststr)); @@ -26433,7 +26433,7 @@ YYLTYPE yylloc; ;} break; - case 857: + case 856: #line 1936 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName((yyvsp[(1) - (1)].conststr)); @@ -26444,47 +26444,47 @@ YYLTYPE yylloc; ;} break; - case 858: + case 857: #line 1946 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = (yyvsp[(2) - (2)].boolean) ? "varchar": "bpchar"; ;} break; - case 859: + case 858: #line 1948 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = (yyvsp[(2) - (2)].boolean) ? "varchar": "bpchar"; ;} break; - case 860: + case 859: #line 1950 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "varchar"; ;} break; - case 861: + case 860: #line 1952 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = (yyvsp[(3) - (3)].boolean) ? "varchar": "bpchar"; ;} break; - case 862: + case 861: #line 1954 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = (yyvsp[(3) - (3)].boolean) ? "varchar": "bpchar"; ;} break; - case 863: + case 862: #line 1956 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = (yyvsp[(2) - (2)].boolean) ? "varchar": "bpchar"; ;} break; - case 864: + case 863: #line 1960 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = true; ;} break; - case 865: + case 864: #line 1961 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = false; ;} break; - case 866: + case 865: #line 1969 "third_party/libpg_query/grammar/statements/select.y" { if ((yyvsp[(5) - (5)].boolean)) @@ -26496,7 +26496,7 @@ YYLTYPE yylloc; ;} break; - case 867: + case 866: #line 1978 "third_party/libpg_query/grammar/statements/select.y" { if ((yyvsp[(2) - (2)].boolean)) @@ -26507,7 +26507,7 @@ YYLTYPE yylloc; ;} break; - case 868: + case 867: #line 1986 "third_party/libpg_query/grammar/statements/select.y" { if ((yyvsp[(5) - (5)].boolean)) @@ -26519,7 +26519,7 @@ YYLTYPE yylloc; ;} break; - case 869: + case 868: #line 1995 "third_party/libpg_query/grammar/statements/select.y" { if ((yyvsp[(2) - (2)].boolean)) @@ -26530,7 +26530,7 @@ YYLTYPE yylloc; ;} break; - case 870: + case 869: #line 2006 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("interval"); @@ -26538,87 +26538,87 @@ YYLTYPE yylloc; ;} break; - case 871: + case 870: #line 2013 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = true; ;} break; - case 872: + case 871: #line 2014 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = false; ;} break; - case 873: + case 872: #line 2015 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = false; ;} break; - case 900: + case 899: #line 2059 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(YEAR), (yylsp[(1) - (1)]))); ;} break; - case 901: + case 900: #line 2061 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(MONTH), (yylsp[(1) - (1)]))); ;} break; - case 902: + case 901: #line 2063 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(DAY), (yylsp[(1) - (1)]))); ;} break; - case 903: + case 902: #line 2065 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(HOUR), (yylsp[(1) - (1)]))); ;} break; - case 904: + case 903: #line 2067 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(MINUTE), (yylsp[(1) - (1)]))); ;} break; - case 905: + case 904: #line 2069 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(SECOND), (yylsp[(1) - (1)]))); ;} break; - case 906: + case 905: #line 2071 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(MILLISECOND), (yylsp[(1) - (1)]))); ;} break; - case 907: + case 906: #line 2073 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(MICROSECOND), (yylsp[(1) - (1)]))); ;} break; - case 908: + case 907: #line 2075 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(WEEK), (yylsp[(1) - (1)]))); ;} break; - case 909: + case 908: #line 2077 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(QUARTER), (yylsp[(1) - (1)]))); ;} break; - case 910: + case 909: #line 2079 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(DECADE), (yylsp[(1) - (1)]))); ;} break; - case 911: + case 910: #line 2081 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(CENTURY), (yylsp[(1) - (1)]))); ;} break; - case 912: + case 911: #line 2083 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(MILLENNIUM), (yylsp[(1) - (1)]))); ;} break; - case 913: + case 912: #line 2085 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(YEAR) | @@ -26626,7 +26626,7 @@ YYLTYPE yylloc; ;} break; - case 914: + case 913: #line 2090 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(DAY) | @@ -26634,7 +26634,7 @@ YYLTYPE yylloc; ;} break; - case 915: + case 914: #line 2095 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(DAY) | @@ -26643,7 +26643,7 @@ YYLTYPE yylloc; ;} break; - case 916: + case 915: #line 2101 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(DAY) | @@ -26653,7 +26653,7 @@ YYLTYPE yylloc; ;} break; - case 917: + case 916: #line 2108 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(HOUR) | @@ -26661,7 +26661,7 @@ YYLTYPE yylloc; ;} break; - case 918: + case 917: #line 2113 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(HOUR) | @@ -26670,7 +26670,7 @@ YYLTYPE yylloc; ;} break; - case 919: + case 918: #line 2119 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(MINUTE) | @@ -26678,22 +26678,22 @@ YYLTYPE yylloc; ;} break; - case 920: + case 919: #line 2124 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 921: + case 920: #line 2155 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 922: + case 921: #line 2158 "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 923: + case 922: #line 2160 "third_party/libpg_query/grammar/statements/select.y" { PGCollateClause *n = makeNode(PGCollateClause); @@ -26704,7 +26704,7 @@ YYLTYPE yylloc; ;} break; - case 924: + case 923: #line 2168 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("timezone"), @@ -26713,122 +26713,122 @@ YYLTYPE yylloc; ;} break; - case 925: + case 924: #line 2183 "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 926: + case 925: #line 2185 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = doNegate((yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;} break; - case 927: + case 926: #line 2187 "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 928: + case 927: #line 2189 "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 929: + case 928: #line 2191 "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 930: + case 929: #line 2193 "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 931: + case 930: #line 2195 "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 932: + case 931: #line 2197 "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 933: + case 932: #line 2199 "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 934: + case 933: #line 2201 "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 935: + case 934: #line 2203 "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 936: + case 935: #line 2205 "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 937: + case 936: #line 2207 "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 938: + case 937: #line 2209 "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 939: + case 938: #line 2211 "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 940: + case 939: #line 2213 "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 941: + case 940: #line 2216 "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 942: + case 941: #line 2218 "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 943: + case 942: #line 2220 "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 944: + case 943: #line 2223 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeAndExpr((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 945: + case 944: #line 2225 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeOrExpr((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 946: + case 945: #line 2227 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeNotExpr((yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;} break; - case 947: + case 946: #line 2229 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeNotExpr((yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;} break; - case 948: + case 947: #line 2231 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_GLOB, "~~~", @@ -26836,7 +26836,7 @@ YYLTYPE yylloc; ;} break; - case 949: + case 948: #line 2236 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_LIKE, "~~", @@ -26844,7 +26844,7 @@ YYLTYPE yylloc; ;} break; - case 950: + case 949: #line 2241 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("like_escape"), @@ -26854,7 +26854,7 @@ YYLTYPE yylloc; ;} break; - case 951: + case 950: #line 2248 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_LIKE, "!~~", @@ -26862,7 +26862,7 @@ YYLTYPE yylloc; ;} break; - case 952: + case 951: #line 2253 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("not_like_escape"), @@ -26872,7 +26872,7 @@ YYLTYPE yylloc; ;} break; - case 953: + case 952: #line 2260 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_ILIKE, "~~*", @@ -26880,7 +26880,7 @@ YYLTYPE yylloc; ;} break; - case 954: + case 953: #line 2265 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("ilike_escape"), @@ -26890,7 +26890,7 @@ YYLTYPE yylloc; ;} break; - case 955: + case 954: #line 2272 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_ILIKE, "!~~*", @@ -26898,7 +26898,7 @@ YYLTYPE yylloc; ;} break; - case 956: + case 955: #line 2277 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("not_ilike_escape"), @@ -26908,7 +26908,7 @@ YYLTYPE yylloc; ;} break; - case 957: + case 956: #line 2285 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("similar_escape"), @@ -26919,7 +26919,7 @@ YYLTYPE yylloc; ;} break; - case 958: + case 957: #line 2293 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("similar_escape"), @@ -26930,7 +26930,7 @@ YYLTYPE yylloc; ;} break; - case 959: + case 958: #line 2301 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("similar_escape"), @@ -26941,7 +26941,7 @@ YYLTYPE yylloc; ;} break; - case 960: + case 959: #line 2309 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("similar_escape"), @@ -26952,7 +26952,7 @@ YYLTYPE yylloc; ;} break; - case 961: + case 960: #line 2327 "third_party/libpg_query/grammar/statements/select.y" { PGNullTest *n = makeNode(PGNullTest); @@ -26963,7 +26963,7 @@ YYLTYPE yylloc; ;} break; - case 962: + case 961: #line 2335 "third_party/libpg_query/grammar/statements/select.y" { PGNullTest *n = makeNode(PGNullTest); @@ -26974,7 +26974,7 @@ YYLTYPE yylloc; ;} break; - case 963: + case 962: #line 2343 "third_party/libpg_query/grammar/statements/select.y" { PGNullTest *n = makeNode(PGNullTest); @@ -26985,7 +26985,7 @@ YYLTYPE yylloc; ;} break; - case 964: + case 963: #line 2351 "third_party/libpg_query/grammar/statements/select.y" { PGNullTest *n = makeNode(PGNullTest); @@ -26996,7 +26996,7 @@ YYLTYPE yylloc; ;} break; - case 965: + case 964: #line 2359 "third_party/libpg_query/grammar/statements/select.y" { PGNullTest *n = makeNode(PGNullTest); @@ -27007,7 +27007,7 @@ YYLTYPE yylloc; ;} break; - case 966: + case 965: #line 2367 "third_party/libpg_query/grammar/statements/select.y" { PGLambdaFunction *n = makeNode(PGLambdaFunction); @@ -27018,14 +27018,14 @@ YYLTYPE yylloc; ;} break; - case 967: + case 966: #line 2375 "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 968: + case 967: #line 2379 "third_party/libpg_query/grammar/statements/select.y" { if (list_length((yyvsp[(1) - (3)].list)) != 2) @@ -27044,7 +27044,7 @@ YYLTYPE yylloc; ;} break; - case 969: + case 968: #line 2395 "third_party/libpg_query/grammar/statements/select.y" { PGBooleanTest *b = makeNode(PGBooleanTest); @@ -27055,7 +27055,7 @@ YYLTYPE yylloc; ;} break; - case 970: + case 969: #line 2403 "third_party/libpg_query/grammar/statements/select.y" { PGBooleanTest *b = makeNode(PGBooleanTest); @@ -27066,7 +27066,7 @@ YYLTYPE yylloc; ;} break; - case 971: + case 970: #line 2411 "third_party/libpg_query/grammar/statements/select.y" { PGBooleanTest *b = makeNode(PGBooleanTest); @@ -27077,7 +27077,7 @@ YYLTYPE yylloc; ;} break; - case 972: + case 971: #line 2419 "third_party/libpg_query/grammar/statements/select.y" { PGBooleanTest *b = makeNode(PGBooleanTest); @@ -27088,7 +27088,7 @@ YYLTYPE yylloc; ;} break; - case 973: + case 972: #line 2427 "third_party/libpg_query/grammar/statements/select.y" { PGBooleanTest *b = makeNode(PGBooleanTest); @@ -27099,7 +27099,7 @@ YYLTYPE yylloc; ;} break; - case 974: + case 973: #line 2435 "third_party/libpg_query/grammar/statements/select.y" { PGBooleanTest *b = makeNode(PGBooleanTest); @@ -27110,35 +27110,35 @@ YYLTYPE yylloc; ;} break; - case 975: + case 974: #line 2443 "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 976: + case 975: #line 2447 "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 977: + case 976: #line 2451 "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 978: + case 977: #line 2455 "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 979: + case 978: #line 2459 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_BETWEEN, @@ -27149,7 +27149,7 @@ YYLTYPE yylloc; ;} break; - case 980: + case 979: #line 2467 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_NOT_BETWEEN, @@ -27160,7 +27160,7 @@ YYLTYPE yylloc; ;} break; - case 981: + case 980: #line 2475 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_BETWEEN_SYM, @@ -27171,7 +27171,7 @@ YYLTYPE yylloc; ;} break; - case 982: + case 981: #line 2483 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_NOT_BETWEEN_SYM, @@ -27182,7 +27182,7 @@ YYLTYPE yylloc; ;} break; - case 983: + case 982: #line 2491 "third_party/libpg_query/grammar/statements/select.y" { /* in_expr returns a PGSubLink or a list of a_exprs */ @@ -27205,7 +27205,7 @@ YYLTYPE yylloc; ;} break; - case 984: + case 983: #line 2511 "third_party/libpg_query/grammar/statements/select.y" { /* in_expr returns a PGSubLink or a list of a_exprs */ @@ -27230,7 +27230,7 @@ YYLTYPE yylloc; ;} break; - case 985: + case 984: #line 2533 "third_party/libpg_query/grammar/statements/select.y" { PGSubLink *n = makeNode(PGSubLink); @@ -27244,7 +27244,7 @@ YYLTYPE yylloc; ;} break; - case 986: + case 985: #line 2544 "third_party/libpg_query/grammar/statements/select.y" { if ((yyvsp[(3) - (6)].subquerytype) == PG_ANY_SUBLINK) @@ -27254,7 +27254,7 @@ YYLTYPE yylloc; ;} break; - case 987: + case 986: #line 2551 "third_party/libpg_query/grammar/statements/select.y" { /* @@ -27271,7 +27271,7 @@ YYLTYPE yylloc; ;} break; - case 988: + case 987: #line 2565 "third_party/libpg_query/grammar/statements/select.y" { PGAStar *star = makeNode(PGAStar); @@ -27283,7 +27283,7 @@ YYLTYPE yylloc; ;} break; - case 989: + case 988: #line 2574 "third_party/libpg_query/grammar/statements/select.y" { PGAStar *star = makeNode(PGAStar); @@ -27294,7 +27294,7 @@ YYLTYPE yylloc; ;} break; - case 990: + case 989: #line 2582 "third_party/libpg_query/grammar/statements/select.y" { PGAStar *star = makeNode(PGAStar); @@ -27305,7 +27305,7 @@ YYLTYPE yylloc; ;} break; - case 991: + case 990: #line 2590 "third_party/libpg_query/grammar/statements/select.y" { PGAStar *star = makeNode(PGAStar); @@ -27317,140 +27317,140 @@ YYLTYPE yylloc; ;} break; - case 992: + case 991: #line 2610 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 993: + case 992: #line 2612 "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 994: + case 993: #line 2614 "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 995: + case 994: #line 2616 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = doNegate((yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;} break; - case 996: + case 995: #line 2618 "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 997: + case 996: #line 2620 "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 998: + case 997: #line 2622 "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 999: + case 998: #line 2624 "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 1000: + case 999: #line 2626 "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 1001: + case 1000: #line 2628 "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 1002: + case 1001: #line 2630 "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 1003: + case 1002: #line 2632 "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 1004: + case 1003: #line 2634 "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 1005: + case 1004: #line 2636 "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 1006: + case 1005: #line 2638 "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 1007: + case 1006: #line 2640 "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 1008: + case 1007: #line 2642 "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 1009: + case 1008: #line 2644 "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 1010: + case 1009: #line 2646 "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 1011: + case 1010: #line 2648 "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 1012: + case 1011: #line 2650 "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 1013: + case 1012: #line 2652 "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 1014: + case 1013: #line 2656 "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 1015: + case 1014: #line 2660 "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 1016: + case 1015: #line 2664 "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 1018: + case 1017: #line 2679 "third_party/libpg_query/grammar/statements/select.y" { if ((yyvsp[(2) - (2)].list)) @@ -27465,17 +27465,17 @@ YYLTYPE yylloc; ;} break; - case 1019: + case 1018: #line 2692 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 1020: + case 1019: #line 2693 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 1021: + case 1020: #line 2695 "third_party/libpg_query/grammar/statements/select.y" { PGSubLink *n = makeNode(PGSubLink); @@ -27489,7 +27489,7 @@ YYLTYPE yylloc; ;} break; - case 1022: + case 1021: #line 2706 "third_party/libpg_query/grammar/statements/select.y" { /* @@ -27516,7 +27516,7 @@ YYLTYPE yylloc; ;} break; - case 1023: + case 1022: #line 2730 "third_party/libpg_query/grammar/statements/select.y" { PGSubLink *n = makeNode(PGSubLink); @@ -27530,7 +27530,7 @@ YYLTYPE yylloc; ;} break; - case 1024: + case 1023: #line 2741 "third_party/libpg_query/grammar/statements/select.y" { PGGroupingFunc *g = makeNode(PGGroupingFunc); @@ -27540,21 +27540,21 @@ YYLTYPE yylloc; ;} break; - case 1025: + case 1024: #line 2751 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (3)].node); ;} break; - case 1026: + case 1025: #line 2755 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 1027: + case 1026: #line 2758 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("row"), (yyvsp[(1) - (1)].list), (yylsp[(1) - (1)])); @@ -27562,14 +27562,14 @@ YYLTYPE yylloc; ;} break; - case 1028: + case 1027: #line 2766 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeParamRef(0, (yylsp[(1) - (1)])); ;} break; - case 1029: + case 1028: #line 2770 "third_party/libpg_query/grammar/statements/select.y" { PGParamRef *p = makeNode(PGParamRef); @@ -27579,47 +27579,47 @@ YYLTYPE yylloc; ;} break; - case 1030: + case 1029: #line 2777 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 1031: + case 1030: #line 2781 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 1032: + case 1031: #line 2785 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 1033: + case 1032: #line 2789 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 1034: + case 1033: #line 2790 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 1035: + case 1034: #line 2793 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 1036: + case 1035: #line 2797 "third_party/libpg_query/grammar/statements/select.y" { PGSubLink *n = makeNode(PGSubLink); @@ -27633,7 +27633,7 @@ YYLTYPE yylloc; ;} break; - case 1037: + case 1036: #line 2807 "third_party/libpg_query/grammar/statements/select.y" { PGList *func_name = list_make1(makeString("construct_array")); @@ -27642,7 +27642,7 @@ YYLTYPE yylloc; ;} break; - case 1038: + case 1037: #line 2813 "third_party/libpg_query/grammar/statements/select.y" { PGPositionalReference *n = makeNode(PGPositionalReference); @@ -27652,14 +27652,14 @@ YYLTYPE yylloc; ;} break; - case 1039: + case 1038: #line 2820 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeNamedParamRef((yyvsp[(2) - (2)].str), (yylsp[(1) - (2)])); ;} break; - case 1040: + case 1039: #line 2825 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("list_value"), (yyvsp[(2) - (3)].list), (yylsp[(2) - (3)])); @@ -27667,7 +27667,7 @@ YYLTYPE yylloc; ;} break; - case 1041: + case 1040: #line 2832 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *f = makeFuncCall(SystemFuncName("struct_pack"), (yyvsp[(2) - (3)].list), (yylsp[(2) - (3)])); @@ -27675,7 +27675,7 @@ YYLTYPE yylloc; ;} break; - case 1042: + case 1041: #line 2839 "third_party/libpg_query/grammar/statements/select.y" { PGList *key_list = NULL; @@ -27695,14 +27695,14 @@ YYLTYPE yylloc; ;} break; - case 1043: + case 1042: #line 2859 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeFuncCall((yyvsp[(1) - (3)].list), NIL, (yylsp[(1) - (3)])); ;} break; - case 1044: + case 1043: #line 2863 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall((yyvsp[(1) - (6)].list), (yyvsp[(3) - (6)].list), (yylsp[(1) - (6)])); @@ -27712,7 +27712,7 @@ YYLTYPE yylloc; ;} break; - case 1045: + case 1044: #line 2870 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall((yyvsp[(1) - (7)].list), list_make1((yyvsp[(4) - (7)].node)), (yylsp[(1) - (7)])); @@ -27723,7 +27723,7 @@ YYLTYPE yylloc; ;} break; - case 1046: + case 1045: #line 2878 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall((yyvsp[(1) - (9)].list), lappend((yyvsp[(3) - (9)].list), (yyvsp[(6) - (9)].node)), (yylsp[(1) - (9)])); @@ -27734,7 +27734,7 @@ YYLTYPE yylloc; ;} break; - case 1047: + case 1046: #line 2886 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall((yyvsp[(1) - (7)].list), (yyvsp[(4) - (7)].list), (yylsp[(1) - (7)])); @@ -27748,7 +27748,7 @@ YYLTYPE yylloc; ;} break; - case 1048: + case 1047: #line 2897 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall((yyvsp[(1) - (7)].list), (yyvsp[(4) - (7)].list), (yylsp[(1) - (7)])); @@ -27759,7 +27759,7 @@ YYLTYPE yylloc; ;} break; - case 1049: + case 1048: #line 2917 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = (PGFuncCall *) (yyvsp[(1) - (5)].node); @@ -27798,22 +27798,22 @@ YYLTYPE yylloc; ;} break; - case 1050: + case 1049: #line 2953 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 1051: + case 1050: #line 2963 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 1052: + case 1051: #line 2964 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 1053: + case 1052: #line 2972 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("pg_collation_for"), @@ -27822,24 +27822,24 @@ YYLTYPE yylloc; ;} break; - case 1054: + case 1053: #line 2978 "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 1055: + case 1054: #line 2980 "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 1056: + case 1055: #line 2982 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("date_part"), (yyvsp[(3) - (4)].list), (yylsp[(1) - (4)])); ;} break; - case 1057: + case 1056: #line 2986 "third_party/libpg_query/grammar/statements/select.y" { /* overlay(A PLACING B FROM C FOR D) is converted to @@ -27851,7 +27851,7 @@ YYLTYPE yylloc; ;} break; - case 1058: + case 1057: #line 2995 "third_party/libpg_query/grammar/statements/select.y" { /* position(A in B) is converted to position_inverse(A, B) */ @@ -27859,7 +27859,7 @@ YYLTYPE yylloc; ;} break; - case 1059: + case 1058: #line 3000 "third_party/libpg_query/grammar/statements/select.y" { /* substring(A from B for C) is converted to @@ -27869,7 +27869,7 @@ YYLTYPE yylloc; ;} break; - case 1060: + case 1059: #line 3007 "third_party/libpg_query/grammar/statements/select.y" { /* TREAT(expr AS target) converts expr of a particular type to target, @@ -27887,7 +27887,7 @@ YYLTYPE yylloc; ;} break; - case 1061: + case 1060: #line 3022 "third_party/libpg_query/grammar/statements/select.y" { /* various trim expressions are defined in SQL @@ -27897,35 +27897,35 @@ YYLTYPE yylloc; ;} break; - case 1062: + case 1061: #line 3029 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("ltrim"), (yyvsp[(4) - (5)].list), (yylsp[(1) - (5)])); ;} break; - case 1063: + case 1062: #line 3033 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("rtrim"), (yyvsp[(4) - (5)].list), (yylsp[(1) - (5)])); ;} break; - case 1064: + case 1063: #line 3037 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("trim"), (yyvsp[(3) - (4)].list), (yylsp[(1) - (4)])); ;} break; - case 1065: + case 1064: #line 3041 "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 1066: + case 1065: #line 3045 "third_party/libpg_query/grammar/statements/select.y" { PGCoalesceExpr *c = makeNode(PGCoalesceExpr); @@ -27935,7 +27935,7 @@ YYLTYPE yylloc; ;} break; - case 1067: + case 1066: #line 3055 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("row"), (yyvsp[(1) - (1)].list), (yylsp[(1) - (1)])); @@ -27943,7 +27943,7 @@ YYLTYPE yylloc; ;} break; - case 1068: + case 1067: #line 3063 "third_party/libpg_query/grammar/statements/select.y" { PGLambdaFunction *lambda = makeNode(PGLambdaFunction); @@ -27955,7 +27955,7 @@ YYLTYPE yylloc; ;} break; - case 1069: + case 1068: #line 3072 "third_party/libpg_query/grammar/statements/select.y" { PGLambdaFunction *lambda = makeNode(PGLambdaFunction); @@ -27973,62 +27973,62 @@ YYLTYPE yylloc; ;} break; - case 1070: + case 1069: #line 3093 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(4) - (5)].list); ;} break; - case 1071: + case 1070: #line 3094 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 1072: + case 1071: #line 3098 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(4) - (5)].node); ;} break; - case 1073: + case 1072: #line 3099 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(3) - (4)].node); ;} break; - case 1074: + case 1073: #line 3100 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 1075: + case 1074: #line 3104 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = true; ;} break; - case 1076: + case 1075: #line 3105 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = false; ;} break; - case 1077: + case 1076: #line 3112 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(2) - (2)].list); ;} break; - case 1078: + case 1077: #line 3113 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 1079: + case 1078: #line 3117 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].windef)); ;} break; - case 1080: + case 1079: #line 3119 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].windef)); ;} break; - case 1081: + case 1080: #line 3124 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = (yyvsp[(3) - (3)].windef); @@ -28037,12 +28037,12 @@ YYLTYPE yylloc; ;} break; - case 1082: + case 1081: #line 3132 "third_party/libpg_query/grammar/statements/select.y" { (yyval.windef) = (yyvsp[(2) - (2)].windef); ;} break; - case 1083: + case 1082: #line 3134 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = makeNode(PGWindowDef); @@ -28058,12 +28058,12 @@ YYLTYPE yylloc; ;} break; - case 1084: + case 1083: #line 3147 "third_party/libpg_query/grammar/statements/select.y" { (yyval.windef) = NULL; ;} break; - case 1085: + case 1084: #line 3152 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = makeNode(PGWindowDef); @@ -28080,27 +28080,27 @@ YYLTYPE yylloc; ;} break; - case 1086: + case 1085: #line 3177 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1087: + case 1086: #line 3178 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = NULL; ;} break; - case 1088: + case 1087: #line 3181 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (3)].list); ;} break; - case 1089: + case 1088: #line 3182 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 1090: + case 1089: #line 3191 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = (yyvsp[(2) - (3)].windef); @@ -28111,7 +28111,7 @@ YYLTYPE yylloc; ;} break; - case 1091: + case 1090: #line 3199 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = (yyvsp[(2) - (3)].windef); @@ -28122,7 +28122,7 @@ YYLTYPE yylloc; ;} break; - case 1092: + case 1091: #line 3207 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = (yyvsp[(2) - (3)].windef); @@ -28133,7 +28133,7 @@ YYLTYPE yylloc; ;} break; - case 1093: + case 1092: #line 3215 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = makeNode(PGWindowDef); @@ -28145,7 +28145,7 @@ YYLTYPE yylloc; ;} break; - case 1094: + case 1093: #line 3226 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = (yyvsp[(1) - (1)].windef); @@ -28166,7 +28166,7 @@ YYLTYPE yylloc; ;} break; - case 1095: + case 1094: #line 3244 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n1 = (yyvsp[(2) - (4)].windef); @@ -28207,7 +28207,7 @@ YYLTYPE yylloc; ;} break; - case 1096: + case 1095: #line 3290 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = makeNode(PGWindowDef); @@ -28219,7 +28219,7 @@ YYLTYPE yylloc; ;} break; - case 1097: + case 1096: #line 3299 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = makeNode(PGWindowDef); @@ -28231,7 +28231,7 @@ YYLTYPE yylloc; ;} break; - case 1098: + case 1097: #line 3308 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = makeNode(PGWindowDef); @@ -28243,7 +28243,7 @@ YYLTYPE yylloc; ;} break; - case 1099: + case 1098: #line 3317 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = makeNode(PGWindowDef); @@ -28255,7 +28255,7 @@ YYLTYPE yylloc; ;} break; - case 1100: + case 1099: #line 3326 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = makeNode(PGWindowDef); @@ -28267,52 +28267,52 @@ YYLTYPE yylloc; ;} break; - case 1101: + case 1100: #line 3337 "third_party/libpg_query/grammar/statements/select.y" { (yyval.ival) = FRAMEOPTION_EXCLUDE_CURRENT_ROW; ;} break; - case 1102: + case 1101: #line 3338 "third_party/libpg_query/grammar/statements/select.y" { (yyval.ival) = FRAMEOPTION_EXCLUDE_GROUP; ;} break; - case 1103: + case 1102: #line 3339 "third_party/libpg_query/grammar/statements/select.y" { (yyval.ival) = FRAMEOPTION_EXCLUDE_TIES; ;} break; - case 1104: + case 1103: #line 3340 "third_party/libpg_query/grammar/statements/select.y" { (yyval.ival) = 0; ;} break; - case 1105: + case 1104: #line 3341 "third_party/libpg_query/grammar/statements/select.y" { (yyval.ival) = 0; ;} break; - case 1106: + case 1105: #line 3355 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (4)].list); ;} break; - case 1107: + case 1106: #line 3356 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 1108: + case 1107: #line 3359 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list);;} break; - case 1109: + case 1108: #line 3360 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(2) - (5)].list), (yyvsp[(4) - (5)].node)); ;} break; - case 1110: + case 1109: #line 3364 "third_party/libpg_query/grammar/statements/select.y" { PGNamedArgExpr *na = makeNode(PGNamedArgExpr); @@ -28324,320 +28324,320 @@ YYLTYPE yylloc; ;} break; - case 1111: + case 1110: #line 3374 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 1112: + case 1111: #line 3375 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;} break; - case 1113: + case 1112: #line 3379 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 1114: + case 1113: #line 3380 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (2)].list); ;} break; - case 1115: + case 1114: #line 3385 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); ;} break; - case 1116: + case 1115: #line 3391 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].list)); ;} break; - case 1117: + case 1116: #line 3392 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); ;} break; - case 1118: + case 1117: #line 3397 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 1119: + case 1118: #line 3398 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (2)].list); ;} break; - case 1120: + case 1119: #line 3403 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 1121: + case 1120: #line 3404 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NULL; ;} break; - case 1122: + case 1121: #line 3407 "third_party/libpg_query/grammar/statements/select.y" { (yyval.subquerytype) = PG_ANY_SUBLINK; ;} break; - case 1123: + case 1122: #line 3408 "third_party/libpg_query/grammar/statements/select.y" { (yyval.subquerytype) = PG_ANY_SUBLINK; ;} break; - case 1124: + case 1123: #line 3409 "third_party/libpg_query/grammar/statements/select.y" { (yyval.subquerytype) = PG_ALL_SUBLINK; ;} break; - case 1125: + case 1124: #line 3412 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1126: + case 1125: #line 3413 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) (yyvsp[(1) - (1)].conststr); ;} break; - case 1127: + case 1126: #line 3416 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "+"; ;} break; - case 1128: + case 1127: #line 3417 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "-"; ;} break; - case 1129: + case 1128: #line 3418 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "*"; ;} break; - case 1130: + case 1129: #line 3419 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "/"; ;} break; - case 1131: + case 1130: #line 3420 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "//"; ;} break; - case 1132: + case 1131: #line 3421 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "%"; ;} break; - case 1133: + case 1132: #line 3422 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "^"; ;} break; - case 1134: + case 1133: #line 3423 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "**"; ;} break; - case 1135: + case 1134: #line 3424 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "<"; ;} break; - case 1136: + case 1135: #line 3425 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = ">"; ;} break; - case 1137: + case 1136: #line 3426 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "="; ;} break; - case 1138: + case 1137: #line 3427 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "<="; ;} break; - case 1139: + case 1138: #line 3428 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = ">="; ;} break; - case 1140: + case 1139: #line 3429 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "<>"; ;} break; - case 1141: + case 1140: #line 3433 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;} break; - case 1142: + case 1141: #line 3435 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (4)].list); ;} break; - case 1143: + case 1142: #line 3440 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;} break; - case 1144: + case 1143: #line 3442 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (4)].list); ;} break; - case 1145: + case 1144: #line 3447 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;} break; - case 1146: + case 1145: #line 3449 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (4)].list); ;} break; - case 1147: + case 1146: #line 3451 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString("~~")); ;} break; - case 1148: + case 1147: #line 3453 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString("!~~")); ;} break; - case 1149: + case 1148: #line 3455 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString("~~~")); ;} break; - case 1150: + case 1149: #line 3457 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString("!~~~")); ;} break; - case 1151: + case 1150: #line 3459 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString("~~*")); ;} break; - case 1152: + case 1151: #line 3461 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString("!~~*")); ;} break; - case 1153: + case 1152: #line 3475 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;} break; - case 1154: + case 1153: #line 3477 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lcons(makeString((yyvsp[(1) - (3)].str)), (yyvsp[(3) - (3)].list)); ;} break; - case 1155: + case 1154: #line 3482 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 1156: + case 1155: #line 3486 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;} break; - case 1157: + case 1156: #line 3493 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 1158: + case 1157: #line 3498 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (2)].list); ;} break; - case 1159: + case 1158: #line 3504 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 1160: + case 1159: #line 3508 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;} break; - case 1161: + case 1160: #line 3515 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 1162: + case 1161: #line 3520 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (2)].list); ;} break; - case 1163: + case 1162: #line 3527 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 1164: + case 1163: #line 3531 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NULL; ;} break; - case 1165: + case 1164: #line 3540 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 1166: + case 1165: #line 3544 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;} break; - case 1167: + case 1166: #line 3550 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 1168: + case 1167: #line 3554 "third_party/libpg_query/grammar/statements/select.y" { PGNamedArgExpr *na = makeNode(PGNamedArgExpr); @@ -28649,7 +28649,7 @@ YYLTYPE yylloc; ;} break; - case 1169: + case 1168: #line 3563 "third_party/libpg_query/grammar/statements/select.y" { PGNamedArgExpr *na = makeNode(PGNamedArgExpr); @@ -28661,140 +28661,140 @@ YYLTYPE yylloc; ;} break; - case 1170: + case 1169: #line 3573 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].typnam)); ;} break; - case 1171: + case 1170: #line 3574 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].typnam)); ;} break; - case 1172: + case 1171: #line 3579 "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 1173: + case 1172: #line 3582 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 1174: + case 1173: #line 3589 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1175: + case 1174: #line 3590 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "year"; ;} break; - case 1176: + case 1175: #line 3591 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "month"; ;} break; - case 1177: + case 1176: #line 3592 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "day"; ;} break; - case 1178: + case 1177: #line 3593 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "hour"; ;} break; - case 1179: + case 1178: #line 3594 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "minute"; ;} break; - case 1180: + case 1179: #line 3595 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "second"; ;} break; - case 1181: + case 1180: #line 3596 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "millisecond"; ;} break; - case 1182: + case 1181: #line 3597 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "microsecond"; ;} break; - case 1183: + case 1182: #line 3598 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "week"; ;} break; - case 1184: + case 1183: #line 3599 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "quarter"; ;} break; - case 1185: + case 1184: #line 3600 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "decade"; ;} break; - case 1186: + case 1185: #line 3601 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "century"; ;} break; - case 1187: + case 1186: #line 3602 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "millennium"; ;} break; - case 1188: + case 1187: #line 3603 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1189: + case 1188: #line 3614 "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 1190: + case 1189: #line 3618 "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 1191: + case 1190: #line 3625 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 1192: + case 1191: #line 3631 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); ;} break; - case 1193: + case 1192: #line 3632 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 1194: + case 1193: #line 3649 "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 1195: + case 1194: #line 3653 "third_party/libpg_query/grammar/statements/select.y" { /* not legal per SQL99, but might as well allow it */ @@ -28802,14 +28802,14 @@ YYLTYPE yylloc; ;} break; - case 1196: + case 1195: #line 3658 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node)); ;} break; - case 1197: + case 1196: #line 3662 "third_party/libpg_query/grammar/statements/select.y" { /* @@ -28827,44 +28827,44 @@ YYLTYPE yylloc; ;} break; - case 1198: + case 1197: #line 3677 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 1199: + case 1198: #line 3681 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 1200: + case 1199: #line 3685 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 1201: + case 1200: #line 3688 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 1202: + case 1201: #line 3691 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(3) - (3)].list), (yyvsp[(1) - (3)].node)); ;} break; - case 1203: + case 1202: #line 3692 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(2) - (2)].list); ;} break; - case 1204: + case 1203: #line 3693 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 1205: + case 1204: #line 3697 "third_party/libpg_query/grammar/statements/select.y" { PGSubLink *n = makeNode(PGSubLink); @@ -28874,17 +28874,17 @@ YYLTYPE yylloc; ;} break; - case 1206: + case 1205: #line 3703 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *)(yyvsp[(2) - (3)].list); ;} break; - case 1208: + case 1207: #line 3705 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *)(yyvsp[(1) - (1)].node); ;} break; - case 1209: + case 1208: #line 3716 "third_party/libpg_query/grammar/statements/select.y" { PGCaseExpr *c = makeNode(PGCaseExpr); @@ -28897,17 +28897,17 @@ YYLTYPE yylloc; ;} break; - case 1210: + case 1209: #line 3729 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 1211: + case 1210: #line 3730 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node)); ;} break; - case 1212: + case 1211: #line 3735 "third_party/libpg_query/grammar/statements/select.y" { PGCaseWhen *w = makeNode(PGCaseWhen); @@ -28918,58 +28918,58 @@ YYLTYPE yylloc; ;} break; - case 1213: + case 1212: #line 3745 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 1214: + case 1213: #line 3746 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 1215: + case 1214: #line 3749 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 1216: + case 1215: #line 3750 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 1217: + case 1216: #line 3754 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 1218: + case 1217: #line 3755 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;} break; - case 1219: + case 1218: #line 3759 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeColumnRef((yyvsp[(1) - (1)].str), NIL, (yylsp[(1) - (1)]), yyscanner); ;} break; - case 1220: + case 1219: #line 3765 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeColumnRef((yyvsp[(1) - (1)].str), NIL, (yylsp[(1) - (1)]), yyscanner); ;} break; - case 1221: + case 1220: #line 3769 "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 1222: + case 1221: #line 3776 "third_party/libpg_query/grammar/statements/select.y" { PGAIndices *ai = makeNode(PGAIndices); @@ -28980,7 +28980,7 @@ YYLTYPE yylloc; ;} break; - case 1223: + case 1222: #line 3784 "third_party/libpg_query/grammar/statements/select.y" { PGAIndices *ai = makeNode(PGAIndices); @@ -28991,7 +28991,7 @@ YYLTYPE yylloc; ;} break; - case 1224: + case 1223: #line 3791 "third_party/libpg_query/grammar/statements/select.y" { PGAIndices *ai = makeNode(PGAIndices); @@ -29003,7 +29003,7 @@ YYLTYPE yylloc; ;} break; - case 1225: + case 1224: #line 3799 "third_party/libpg_query/grammar/statements/select.y" { PGAIndices *ai = makeNode(PGAIndices); @@ -29014,42 +29014,42 @@ YYLTYPE yylloc; ;} break; - case 1226: + case 1225: #line 3809 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 1227: + case 1226: #line 3810 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 1228: + case 1227: #line 3815 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 1229: + case 1228: #line 3816 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node)); ;} break; - case 1230: + case 1229: #line 3820 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NULL; ;} break; - case 1231: + case 1230: #line 3821 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(NULL); ;} break; - case 1232: + case 1231: #line 3822 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(2) - (3)].list); ;} break; - case 1233: + case 1232: #line 3827 "third_party/libpg_query/grammar/statements/select.y" { if ((yyvsp[(3) - (3)].list)) { @@ -29061,7 +29061,7 @@ YYLTYPE yylloc; ;} break; - case 1234: + case 1233: #line 3836 "third_party/libpg_query/grammar/statements/select.y" { PGAIndices *ai = makeNode(PGAIndices); @@ -29072,7 +29072,7 @@ YYLTYPE yylloc; ;} break; - case 1235: + case 1234: #line 3844 "third_party/libpg_query/grammar/statements/select.y" { PGAIndices *ai = makeNode(PGAIndices); @@ -29083,7 +29083,7 @@ YYLTYPE yylloc; ;} break; - case 1236: + case 1235: #line 3851 "third_party/libpg_query/grammar/statements/select.y" { PGAIndices *ai = makeNode(PGAIndices); @@ -29095,7 +29095,7 @@ YYLTYPE yylloc; ;} break; - case 1237: + case 1236: #line 3860 "third_party/libpg_query/grammar/statements/select.y" { PGAIndices *ai = makeNode(PGAIndices); @@ -29106,47 +29106,47 @@ YYLTYPE yylloc; ;} break; - case 1238: + case 1237: #line 3875 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 1239: + case 1238: #line 3876 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node)); ;} break; - case 1242: + case 1241: #line 3892 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 1243: + case 1242: #line 3893 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 1244: + case 1243: #line 3897 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].target)); ;} break; - case 1245: + case 1244: #line 3898 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].target)); ;} break; - case 1246: + case 1245: #line 3902 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 1247: + case 1246: #line 3903 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (2)].list); ;} break; - case 1248: + case 1247: #line 3907 "third_party/libpg_query/grammar/statements/select.y" { (yyval.target) = makeNode(PGResTarget); @@ -29157,7 +29157,7 @@ YYLTYPE yylloc; ;} break; - case 1249: + case 1248: #line 3923 "third_party/libpg_query/grammar/statements/select.y" { (yyval.target) = makeNode(PGResTarget); @@ -29168,7 +29168,7 @@ YYLTYPE yylloc; ;} break; - case 1250: + case 1249: #line 3931 "third_party/libpg_query/grammar/statements/select.y" { (yyval.target) = makeNode(PGResTarget); @@ -29179,117 +29179,117 @@ YYLTYPE yylloc; ;} break; - case 1251: + case 1250: #line 3940 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (4)].list); ;} break; - case 1252: + case 1251: #line 3941 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(2) - (2)].str))); ;} break; - case 1253: + case 1252: #line 3944 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 1254: + case 1253: #line 3945 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NULL; ;} break; - case 1255: + case 1254: #line 3948 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2((yyvsp[(1) - (3)].node), makeString((yyvsp[(3) - (3)].str))); ;} break; - case 1256: + case 1255: #line 3952 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].list)); ;} break; - case 1257: + case 1256: #line 3953 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); ;} break; - case 1258: + case 1257: #line 3957 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 1259: + case 1258: #line 3958 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (2)].list); ;} break; - case 1260: + case 1259: #line 3961 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (4)].list); ;} break; - case 1261: + case 1260: #line 3962 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(2) - (2)].list)); ;} break; - case 1262: + case 1261: #line 3963 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NULL; ;} break; - case 1263: + case 1262: #line 3973 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].range)); ;} break; - case 1264: + case 1263: #line 3974 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].range)); ;} break; - case 1265: + case 1264: #line 3979 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;} break; - case 1266: + case 1265: #line 3981 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), makeString((yyvsp[(3) - (3)].str))); ;} break; - case 1267: + case 1266: #line 3986 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 1268: + case 1267: #line 3987 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (2)].list); ;} break; - case 1269: + case 1268: #line 3991 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 1270: + case 1269: #line 3992 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(2) - (3)].list); ;} break; - case 1271: + case 1270: #line 3995 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1272: + case 1271: #line 4007 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;} break; - case 1273: + case 1272: #line 4010 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = check_func_name(lcons(makeString((yyvsp[(1) - (2)].str)), (yyvsp[(2) - (2)].list)), @@ -29297,21 +29297,21 @@ YYLTYPE yylloc; ;} break; - case 1274: + case 1273: #line 4021 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeIntConst((yyvsp[(1) - (1)].ival), (yylsp[(1) - (1)])); ;} break; - case 1275: + case 1274: #line 4025 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeFloatConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)])); ;} break; - case 1276: + case 1275: #line 4029 "third_party/libpg_query/grammar/statements/select.y" { if ((yyvsp[(2) - (2)].list)) @@ -29326,14 +29326,14 @@ YYLTYPE yylloc; ;} break; - case 1277: + case 1276: #line 4041 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeBitStringConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)])); ;} break; - case 1278: + case 1277: #line 4045 "third_party/libpg_query/grammar/statements/select.y" { /* This is a bit constant per SQL99: @@ -29345,7 +29345,7 @@ YYLTYPE yylloc; ;} break; - case 1279: + case 1278: #line 4054 "third_party/libpg_query/grammar/statements/select.y" { /* generic type 'literal' syntax */ @@ -29355,7 +29355,7 @@ YYLTYPE yylloc; ;} break; - case 1280: + case 1279: #line 4061 "third_party/libpg_query/grammar/statements/select.y" { /* generic syntax with a type modifier */ @@ -29396,146 +29396,146 @@ YYLTYPE yylloc; ;} break; - case 1281: + case 1280: #line 4099 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeStringConstCast((yyvsp[(2) - (2)].str), (yylsp[(2) - (2)]), (yyvsp[(1) - (2)].typnam)); ;} break; - case 1282: + case 1281: #line 4103 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeIntervalNode((yyvsp[(3) - (5)].node), (yylsp[(3) - (5)]), (yyvsp[(5) - (5)].list)); ;} break; - case 1283: + case 1282: #line 4107 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeIntervalNode((yyvsp[(2) - (3)].ival), (yylsp[(2) - (3)]), (yyvsp[(3) - (3)].list)); ;} break; - case 1284: + case 1283: #line 4111 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeIntervalNode((yyvsp[(2) - (3)].str), (yylsp[(2) - (3)]), (yyvsp[(3) - (3)].list)); ;} break; - case 1285: + case 1284: #line 4115 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeBoolAConst(true, (yylsp[(1) - (1)])); ;} break; - case 1286: + case 1285: #line 4119 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeBoolAConst(false, (yylsp[(1) - (1)])); ;} break; - case 1287: + case 1286: #line 4123 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeNullAConst((yylsp[(1) - (1)])); ;} break; - case 1288: + case 1287: #line 4128 "third_party/libpg_query/grammar/statements/select.y" { (yyval.ival) = (yyvsp[(1) - (1)].ival); ;} break; - case 1289: + case 1288: #line 4145 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1290: + case 1289: #line 4146 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1291: + case 1290: #line 4147 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1292: + case 1291: #line 4150 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1293: + case 1292: #line 4151 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1294: + case 1293: #line 4152 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1295: + case 1294: #line 4155 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1296: + case 1295: #line 4156 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1297: + case 1296: #line 4157 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1298: + case 1297: #line 4160 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;} break; - case 1299: + case 1298: #line 4161 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lcons(makeString((yyvsp[(1) - (2)].str)), (yyvsp[(2) - (2)].list)); ;} break; - case 1300: + case 1299: #line 4165 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(2) - (2)].str))); ;} break; - case 1301: + case 1300: #line 4167 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), makeString((yyvsp[(3) - (3)].str))); ;} break; - case 1302: + case 1301: #line 4171 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(2) - (3)].list); ;} break; - case 1303: + case 1302: #line 4172 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 1305: + case 1304: #line 4179 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1306: + case 1305: #line 4180 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1307: + case 1306: #line 8 "third_party/libpg_query/grammar/statements/prepare.y" { PGPrepareStmt *n = makeNode(PGPrepareStmt); @@ -29546,17 +29546,17 @@ YYLTYPE yylloc; ;} break; - case 1308: + case 1307: #line 18 "third_party/libpg_query/grammar/statements/prepare.y" { (yyval.list) = (yyvsp[(2) - (3)].list); ;} break; - case 1309: + case 1308: #line 19 "third_party/libpg_query/grammar/statements/prepare.y" { (yyval.list) = NIL; ;} break; - case 1316: + case 1315: #line 8 "third_party/libpg_query/grammar/statements/create_schema.y" { PGCreateSchemaStmt *n = makeNode(PGCreateSchemaStmt); @@ -29578,7 +29578,7 @@ YYLTYPE yylloc; ;} break; - case 1317: + case 1316: #line 27 "third_party/libpg_query/grammar/statements/create_schema.y" { PGCreateSchemaStmt *n = makeNode(PGCreateSchemaStmt); @@ -29605,7 +29605,7 @@ YYLTYPE yylloc; ;} break; - case 1318: + case 1317: #line 51 "third_party/libpg_query/grammar/statements/create_schema.y" { PGCreateSchemaStmt *n = makeNode(PGCreateSchemaStmt); @@ -29627,7 +29627,7 @@ YYLTYPE yylloc; ;} break; - case 1319: + case 1318: #line 74 "third_party/libpg_query/grammar/statements/create_schema.y" { if ((yyloc) < 0) /* see comments for YYLLOC_DEFAULT */ @@ -29636,12 +29636,12 @@ YYLTYPE yylloc; ;} break; - case 1320: + case 1319: #line 80 "third_party/libpg_query/grammar/statements/create_schema.y" { (yyval.list) = NIL; ;} break; - case 1325: + case 1324: #line 11 "third_party/libpg_query/grammar/statements/index.y" { PGIndexStmt *n = makeNode(PGIndexStmt); @@ -29667,7 +29667,7 @@ YYLTYPE yylloc; ;} break; - case 1326: + case 1325: #line 36 "third_party/libpg_query/grammar/statements/index.y" { PGIndexStmt *n = makeNode(PGIndexStmt); @@ -29693,62 +29693,62 @@ YYLTYPE yylloc; ;} break; - case 1327: + case 1326: #line 62 "third_party/libpg_query/grammar/statements/index.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1328: + case 1327: #line 66 "third_party/libpg_query/grammar/statements/index.y" { (yyval.str) = (yyvsp[(2) - (2)].str); ;} break; - case 1329: + case 1328: #line 67 "third_party/libpg_query/grammar/statements/index.y" { (yyval.str) = (char*) DEFAULT_INDEX_TYPE; ;} break; - case 1330: + case 1329: #line 72 "third_party/libpg_query/grammar/statements/index.y" { (yyval.boolean) = true; ;} break; - case 1331: + case 1330: #line 73 "third_party/libpg_query/grammar/statements/index.y" { (yyval.boolean) = false; ;} break; - case 1332: + case 1331: #line 78 "third_party/libpg_query/grammar/statements/index.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1333: + case 1332: #line 79 "third_party/libpg_query/grammar/statements/index.y" { (yyval.str) = NULL; ;} break; - case 1334: + case 1333: #line 83 "third_party/libpg_query/grammar/statements/index.y" { (yyval.list) = (yyvsp[(2) - (2)].list); ;} break; - case 1335: + case 1334: #line 84 "third_party/libpg_query/grammar/statements/index.y" { (yyval.list) = NIL; ;} break; - case 1336: + case 1335: #line 89 "third_party/libpg_query/grammar/statements/index.y" { (yyval.boolean) = true; ;} break; - case 1337: + case 1336: #line 90 "third_party/libpg_query/grammar/statements/index.y" { (yyval.boolean) = false; ;} break; - case 1338: + case 1337: #line 8 "third_party/libpg_query/grammar/statements/alter_schema.y" { PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt); @@ -29760,7 +29760,7 @@ YYLTYPE yylloc; ;} break; - case 1339: + case 1338: #line 17 "third_party/libpg_query/grammar/statements/alter_schema.y" { PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt); @@ -29772,7 +29772,7 @@ YYLTYPE yylloc; ;} break; - case 1340: + case 1339: #line 26 "third_party/libpg_query/grammar/statements/alter_schema.y" { PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt); @@ -29784,7 +29784,7 @@ YYLTYPE yylloc; ;} break; - case 1341: + case 1340: #line 35 "third_party/libpg_query/grammar/statements/alter_schema.y" { PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt); @@ -29796,7 +29796,7 @@ YYLTYPE yylloc; ;} break; - case 1342: + case 1341: #line 44 "third_party/libpg_query/grammar/statements/alter_schema.y" { PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt); @@ -29808,7 +29808,7 @@ YYLTYPE yylloc; ;} break; - case 1343: + case 1342: #line 53 "third_party/libpg_query/grammar/statements/alter_schema.y" { PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt); @@ -29820,7 +29820,7 @@ YYLTYPE yylloc; ;} break; - case 1344: + case 1343: #line 6 "third_party/libpg_query/grammar/statements/checkpoint.y" { PGCheckPointStmt *n = makeNode(PGCheckPointStmt); @@ -29830,7 +29830,7 @@ YYLTYPE yylloc; ;} break; - case 1345: + case 1344: #line 13 "third_party/libpg_query/grammar/statements/checkpoint.y" { PGCheckPointStmt *n = makeNode(PGCheckPointStmt); @@ -29840,17 +29840,17 @@ YYLTYPE yylloc; ;} break; - case 1346: + case 1345: #line 22 "third_party/libpg_query/grammar/statements/checkpoint.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1347: + case 1346: #line 23 "third_party/libpg_query/grammar/statements/checkpoint.y" { (yyval.str) = NULL; ;} break; - case 1348: + case 1347: #line 8 "third_party/libpg_query/grammar/statements/comment_on.y" { PGCommentOnStmt *n = makeNode(PGCommentOnStmt); @@ -29861,7 +29861,7 @@ YYLTYPE yylloc; ;} break; - case 1349: + case 1348: #line 16 "third_party/libpg_query/grammar/statements/comment_on.y" { PGCommentOnStmt *n = makeNode(PGCommentOnStmt); @@ -29872,67 +29872,67 @@ YYLTYPE yylloc; ;} break; - case 1350: + case 1349: #line 26 "third_party/libpg_query/grammar/statements/comment_on.y" { (yyval.node) = makeStringConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)])); ;} break; - case 1351: + case 1350: #line 27 "third_party/libpg_query/grammar/statements/comment_on.y" { (yyval.node) = makeNullAConst((yylsp[(1) - (1)])); ;} break; - case 1352: + case 1351: #line 30 "third_party/libpg_query/grammar/statements/comment_on.y" { (yyval.objtype) = PG_OBJECT_TABLE; ;} break; - case 1353: + case 1352: #line 31 "third_party/libpg_query/grammar/statements/comment_on.y" { (yyval.objtype) = PG_OBJECT_SEQUENCE; ;} break; - case 1354: + case 1353: #line 32 "third_party/libpg_query/grammar/statements/comment_on.y" { (yyval.objtype) = PG_OBJECT_FUNCTION; ;} break; - case 1355: + case 1354: #line 33 "third_party/libpg_query/grammar/statements/comment_on.y" { (yyval.objtype) = PG_OBJECT_FUNCTION; ;} break; - case 1356: + case 1355: #line 34 "third_party/libpg_query/grammar/statements/comment_on.y" { (yyval.objtype) = PG_OBJECT_TABLE_MACRO; ;} break; - case 1357: + case 1356: #line 35 "third_party/libpg_query/grammar/statements/comment_on.y" { (yyval.objtype) = PG_OBJECT_VIEW; ;} break; - case 1358: + case 1357: #line 36 "third_party/libpg_query/grammar/statements/comment_on.y" { (yyval.objtype) = PG_OBJECT_DATABASE; ;} break; - case 1359: + case 1358: #line 37 "third_party/libpg_query/grammar/statements/comment_on.y" { (yyval.objtype) = PG_OBJECT_INDEX; ;} break; - case 1360: + case 1359: #line 38 "third_party/libpg_query/grammar/statements/comment_on.y" { (yyval.objtype) = PG_OBJECT_SCHEMA; ;} break; - case 1361: + case 1360: #line 39 "third_party/libpg_query/grammar/statements/comment_on.y" { (yyval.objtype) = PG_OBJECT_TYPE; ;} break; - case 1362: + case 1361: #line 8 "third_party/libpg_query/grammar/statements/export.y" { PGExportStmt *n = makeNode(PGExportStmt); @@ -29946,7 +29946,7 @@ YYLTYPE yylloc; ;} break; - case 1363: + case 1362: #line 20 "third_party/libpg_query/grammar/statements/export.y" { PGExportStmt *n = makeNode(PGExportStmt); @@ -29960,7 +29960,7 @@ YYLTYPE yylloc; ;} break; - case 1364: + case 1363: #line 34 "third_party/libpg_query/grammar/statements/export.y" { PGImportStmt *n = makeNode(PGImportStmt); @@ -29969,7 +29969,7 @@ YYLTYPE yylloc; ;} break; - case 1365: + case 1364: #line 10 "third_party/libpg_query/grammar/statements/explain.y" { PGExplainStmt *n = makeNode(PGExplainStmt); @@ -29979,7 +29979,7 @@ YYLTYPE yylloc; ;} break; - case 1366: + case 1365: #line 17 "third_party/libpg_query/grammar/statements/explain.y" { PGExplainStmt *n = makeNode(PGExplainStmt); @@ -29992,7 +29992,7 @@ YYLTYPE yylloc; ;} break; - case 1367: + case 1366: #line 27 "third_party/libpg_query/grammar/statements/explain.y" { PGExplainStmt *n = makeNode(PGExplainStmt); @@ -30002,7 +30002,7 @@ YYLTYPE yylloc; ;} break; - case 1368: + case 1367: #line 34 "third_party/libpg_query/grammar/statements/explain.y" { PGExplainStmt *n = makeNode(PGExplainStmt); @@ -30012,118 +30012,118 @@ YYLTYPE yylloc; ;} break; - case 1369: + case 1368: #line 44 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.boolean) = true; ;} break; - case 1370: + case 1369: #line 45 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.boolean) = false; ;} break; - case 1371: + case 1370: #line 50 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.node) = (PGNode *) makeString((yyvsp[(1) - (1)].str)); ;} break; - case 1372: + case 1371: #line 51 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.node) = (PGNode *) (yyvsp[(1) - (1)].value); ;} break; - case 1373: + case 1372: #line 52 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.node) = NULL; ;} break; - case 1405: + case 1404: #line 91 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1406: + case 1405: #line 92 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1407: + case 1406: #line 93 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1408: + case 1407: #line 98 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1409: + case 1408: #line 99 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1410: + case 1409: #line 105 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].defelt)); ;} break; - case 1411: + case 1410: #line 109 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].defelt)); ;} break; - case 1412: + case 1411: #line 116 "third_party/libpg_query/grammar/statements/explain.y" {;} break; - case 1413: + case 1412: #line 117 "third_party/libpg_query/grammar/statements/explain.y" {;} break; - case 1414: + case 1413: #line 122 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (char*) "true"; ;} break; - case 1415: + case 1414: #line 123 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (char*) "false"; ;} break; - case 1416: + case 1415: #line 124 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (char*) "on"; ;} break; - case 1417: + case 1416: #line 130 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1418: + case 1417: #line 136 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.defelt) = makeDefElem((yyvsp[(1) - (2)].str), (yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;} break; - case 1419: + case 1418: #line 143 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1420: + case 1419: #line 144 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (char*) "analyze"; ;} break; - case 1421: + case 1420: #line 11 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = (yyvsp[(2) - (2)].vsetstmt); @@ -30132,7 +30132,7 @@ YYLTYPE yylloc; ;} break; - case 1422: + case 1421: #line 17 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = (yyvsp[(3) - (3)].vsetstmt); @@ -30141,7 +30141,7 @@ YYLTYPE yylloc; ;} break; - case 1423: + case 1422: #line 23 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = (yyvsp[(3) - (3)].vsetstmt); @@ -30150,7 +30150,7 @@ YYLTYPE yylloc; ;} break; - case 1424: + case 1423: #line 29 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = (yyvsp[(3) - (3)].vsetstmt); @@ -30159,7 +30159,7 @@ YYLTYPE yylloc; ;} break; - case 1425: + case 1424: #line 35 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = (yyvsp[(3) - (3)].vsetstmt); @@ -30168,12 +30168,12 @@ YYLTYPE yylloc; ;} break; - case 1426: + case 1425: #line 44 "third_party/libpg_query/grammar/statements/variable_set.y" {(yyval.vsetstmt) = (yyvsp[(1) - (1)].vsetstmt);;} break; - case 1427: + case 1426: #line 46 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -30183,7 +30183,7 @@ YYLTYPE yylloc; ;} break; - case 1428: + case 1427: #line 54 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -30197,7 +30197,7 @@ YYLTYPE yylloc; ;} break; - case 1429: + case 1428: #line 65 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -30208,7 +30208,7 @@ YYLTYPE yylloc; ;} break; - case 1430: + case 1429: #line 77 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -30219,7 +30219,7 @@ YYLTYPE yylloc; ;} break; - case 1431: + case 1430: #line 85 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -30230,26 +30230,26 @@ YYLTYPE yylloc; ;} break; - case 1432: + case 1431: #line 96 "third_party/libpg_query/grammar/statements/variable_set.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 1433: + case 1432: #line 102 "third_party/libpg_query/grammar/statements/variable_set.y" { (yyval.node) = makeStringConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)])); ;} break; - case 1434: + case 1433: #line 106 "third_party/libpg_query/grammar/statements/variable_set.y" { (yyval.node) = makeStringConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)])); ;} break; - case 1435: + case 1434: #line 110 "third_party/libpg_query/grammar/statements/variable_set.y" { PGTypeName *t = (yyvsp[(1) - (3)].typnam); @@ -30267,7 +30267,7 @@ YYLTYPE yylloc; ;} break; - case 1436: + case 1435: #line 125 "third_party/libpg_query/grammar/statements/variable_set.y" { PGTypeName *t = (yyvsp[(1) - (5)].typnam); @@ -30277,32 +30277,32 @@ YYLTYPE yylloc; ;} break; - case 1437: + case 1436: #line 131 "third_party/libpg_query/grammar/statements/variable_set.y" { (yyval.node) = makeAConst((yyvsp[(1) - (1)].value), (yylsp[(1) - (1)])); ;} break; - case 1438: + case 1437: #line 132 "third_party/libpg_query/grammar/statements/variable_set.y" { (yyval.node) = NULL; ;} break; - case 1439: + case 1438: #line 133 "third_party/libpg_query/grammar/statements/variable_set.y" { (yyval.node) = NULL; ;} break; - case 1440: + case 1439: #line 137 "third_party/libpg_query/grammar/statements/variable_set.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 1441: + case 1440: #line 138 "third_party/libpg_query/grammar/statements/variable_set.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;} break; - case 1442: + case 1441: #line 8 "third_party/libpg_query/grammar/statements/load.y" { PGLoadStmt *n = makeNode(PGLoadStmt); @@ -30315,7 +30315,7 @@ YYLTYPE yylloc; ;} break; - case 1443: + case 1442: #line 17 "third_party/libpg_query/grammar/statements/load.y" { PGLoadStmt *n = makeNode(PGLoadStmt); @@ -30328,7 +30328,7 @@ YYLTYPE yylloc; ;} break; - case 1444: + case 1443: #line 26 "third_party/libpg_query/grammar/statements/load.y" { PGLoadStmt *n = makeNode(PGLoadStmt); @@ -30341,7 +30341,7 @@ YYLTYPE yylloc; ;} break; - case 1445: + case 1444: #line 35 "third_party/libpg_query/grammar/statements/load.y" { PGLoadStmt *n = makeNode(PGLoadStmt); @@ -30354,42 +30354,42 @@ YYLTYPE yylloc; ;} break; - case 1446: + case 1445: #line 46 "third_party/libpg_query/grammar/statements/load.y" { (yyval.loadinstalltype) = PG_LOAD_TYPE_INSTALL; ;} break; - case 1447: + case 1446: #line 47 "third_party/libpg_query/grammar/statements/load.y" { (yyval.loadinstalltype) = PG_LOAD_TYPE_FORCE_INSTALL; ;} break; - case 1448: + case 1447: #line 49 "third_party/libpg_query/grammar/statements/load.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1449: + case 1448: #line 50 "third_party/libpg_query/grammar/statements/load.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1450: + case 1449: #line 53 "third_party/libpg_query/grammar/statements/load.y" { (yyval.str) = NULL; ;} break; - case 1451: + case 1450: #line 54 "third_party/libpg_query/grammar/statements/load.y" { (yyval.str) = (yyvsp[(2) - (2)].str); ;} break; - case 1452: + case 1451: #line 55 "third_party/libpg_query/grammar/statements/load.y" { (yyval.str) = (yyvsp[(2) - (2)].str); ;} break; - case 1453: + case 1452: #line 9 "third_party/libpg_query/grammar/statements/vacuum.y" { PGVacuumStmt *n = makeNode(PGVacuumStmt); @@ -30406,7 +30406,7 @@ YYLTYPE yylloc; ;} break; - case 1454: + case 1453: #line 23 "third_party/libpg_query/grammar/statements/vacuum.y" { PGVacuumStmt *n = makeNode(PGVacuumStmt); @@ -30423,7 +30423,7 @@ YYLTYPE yylloc; ;} break; - case 1455: + case 1454: #line 37 "third_party/libpg_query/grammar/statements/vacuum.y" { PGVacuumStmt *n = (PGVacuumStmt *) (yyvsp[(5) - (5)].node); @@ -30438,7 +30438,7 @@ YYLTYPE yylloc; ;} break; - case 1456: + case 1455: #line 49 "third_party/libpg_query/grammar/statements/vacuum.y" { PGVacuumStmt *n = makeNode(PGVacuumStmt); @@ -30449,7 +30449,7 @@ YYLTYPE yylloc; ;} break; - case 1457: + case 1456: #line 57 "third_party/libpg_query/grammar/statements/vacuum.y" { PGVacuumStmt *n = makeNode(PGVacuumStmt); @@ -30462,27 +30462,27 @@ YYLTYPE yylloc; ;} break; - case 1458: + case 1457: #line 70 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.ival) = PG_VACOPT_ANALYZE; ;} break; - case 1459: + case 1458: #line 71 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.ival) = PG_VACOPT_VERBOSE; ;} break; - case 1460: + case 1459: #line 72 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.ival) = PG_VACOPT_FREEZE; ;} break; - case 1461: + case 1460: #line 73 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.ival) = PG_VACOPT_FULL; ;} break; - case 1462: + case 1461: #line 75 "third_party/libpg_query/grammar/statements/vacuum.y" { if (strcmp((yyvsp[(1) - (1)].str), "disable_page_skipping") == 0) @@ -30495,37 +30495,37 @@ YYLTYPE yylloc; ;} break; - case 1463: + case 1462: #line 87 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.boolean) = true; ;} break; - case 1464: + case 1463: #line 88 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.boolean) = false; ;} break; - case 1465: + case 1464: #line 93 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.ival) = (yyvsp[(1) - (1)].ival); ;} break; - case 1466: + case 1465: #line 94 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.ival) = (yyvsp[(1) - (3)].ival) | (yyvsp[(3) - (3)].ival); ;} break; - case 1467: + case 1466: #line 98 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.boolean) = true; ;} break; - case 1468: + case 1467: #line 99 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.boolean) = false; ;} break; - case 1469: + case 1468: #line 9 "third_party/libpg_query/grammar/statements/delete.y" { PGDeleteStmt *n = makeNode(PGDeleteStmt); @@ -30538,7 +30538,7 @@ YYLTYPE yylloc; ;} break; - case 1470: + case 1469: #line 19 "third_party/libpg_query/grammar/statements/delete.y" { PGDeleteStmt *n = makeNode(PGDeleteStmt); @@ -30551,14 +30551,14 @@ YYLTYPE yylloc; ;} break; - case 1471: + case 1470: #line 32 "third_party/libpg_query/grammar/statements/delete.y" { (yyval.range) = (yyvsp[(1) - (1)].range); ;} break; - case 1472: + case 1471: #line 36 "third_party/libpg_query/grammar/statements/delete.y" { PGAlias *alias = makeNode(PGAlias); @@ -30568,7 +30568,7 @@ YYLTYPE yylloc; ;} break; - case 1473: + case 1472: #line 43 "third_party/libpg_query/grammar/statements/delete.y" { PGAlias *alias = makeNode(PGAlias); @@ -30578,27 +30578,27 @@ YYLTYPE yylloc; ;} break; - case 1474: + case 1473: #line 53 "third_party/libpg_query/grammar/statements/delete.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 1475: + case 1474: #line 54 "third_party/libpg_query/grammar/statements/delete.y" { (yyval.node) = NULL; ;} break; - case 1476: + case 1475: #line 60 "third_party/libpg_query/grammar/statements/delete.y" { (yyval.list) = (yyvsp[(2) - (2)].list); ;} break; - case 1477: + case 1476: #line 61 "third_party/libpg_query/grammar/statements/delete.y" { (yyval.list) = NIL; ;} break; - case 1478: + case 1477: #line 10 "third_party/libpg_query/grammar/statements/analyze.y" { PGVacuumStmt *n = makeNode(PGVacuumStmt); @@ -30611,7 +30611,7 @@ YYLTYPE yylloc; ;} break; - case 1479: + case 1478: #line 20 "third_party/libpg_query/grammar/statements/analyze.y" { PGVacuumStmt *n = makeNode(PGVacuumStmt); @@ -30624,7 +30624,7 @@ YYLTYPE yylloc; ;} break; - case 1480: + case 1479: #line 8 "third_party/libpg_query/grammar/statements/attach.y" { PGAttachStmt *n = makeNode(PGAttachStmt); @@ -30636,7 +30636,7 @@ YYLTYPE yylloc; ;} break; - case 1481: + case 1480: #line 17 "third_party/libpg_query/grammar/statements/attach.y" { PGAttachStmt *n = makeNode(PGAttachStmt); @@ -30648,7 +30648,7 @@ YYLTYPE yylloc; ;} break; - case 1482: + case 1481: #line 29 "third_party/libpg_query/grammar/statements/attach.y" { PGDetachStmt *n = makeNode(PGDetachStmt); @@ -30658,7 +30658,7 @@ YYLTYPE yylloc; ;} break; - case 1483: + case 1482: #line 36 "third_party/libpg_query/grammar/statements/attach.y" { PGDetachStmt *n = makeNode(PGDetachStmt); @@ -30668,7 +30668,7 @@ YYLTYPE yylloc; ;} break; - case 1484: + case 1483: #line 43 "third_party/libpg_query/grammar/statements/attach.y" { PGDetachStmt *n = makeNode(PGDetachStmt); @@ -30678,27 +30678,27 @@ YYLTYPE yylloc; ;} break; - case 1485: + case 1484: #line 51 "third_party/libpg_query/grammar/statements/attach.y" {;} break; - case 1486: + case 1485: #line 52 "third_party/libpg_query/grammar/statements/attach.y" {;} break; - case 1487: + case 1486: #line 56 "third_party/libpg_query/grammar/statements/attach.y" { (yyval.str) = (yyvsp[(2) - (2)].str); ;} break; - case 1488: + case 1487: #line 57 "third_party/libpg_query/grammar/statements/attach.y" { (yyval.str) = NULL; ;} break; - case 1489: + case 1488: #line 3 "third_party/libpg_query/grammar/statements/variable_reset.y" { (yyvsp[(2) - (2)].vsetstmt)->scope = VAR_SET_SCOPE_DEFAULT; @@ -30706,7 +30706,7 @@ YYLTYPE yylloc; ;} break; - case 1490: + case 1489: #line 8 "third_party/libpg_query/grammar/statements/variable_reset.y" { (yyvsp[(3) - (3)].vsetstmt)->scope = VAR_SET_SCOPE_LOCAL; @@ -30714,7 +30714,7 @@ YYLTYPE yylloc; ;} break; - case 1491: + case 1490: #line 13 "third_party/libpg_query/grammar/statements/variable_reset.y" { (yyvsp[(3) - (3)].vsetstmt)->scope = VAR_SET_SCOPE_SESSION; @@ -30722,7 +30722,7 @@ YYLTYPE yylloc; ;} break; - case 1492: + case 1491: #line 18 "third_party/libpg_query/grammar/statements/variable_reset.y" { (yyvsp[(3) - (3)].vsetstmt)->scope = VAR_SET_SCOPE_GLOBAL; @@ -30730,7 +30730,7 @@ YYLTYPE yylloc; ;} break; - case 1493: + case 1492: #line 23 "third_party/libpg_query/grammar/statements/variable_reset.y" { (yyvsp[(3) - (3)].vsetstmt)->scope = VAR_SET_SCOPE_VARIABLE; @@ -30738,7 +30738,7 @@ YYLTYPE yylloc; ;} break; - case 1494: + case 1493: #line 32 "third_party/libpg_query/grammar/statements/variable_reset.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -30748,7 +30748,7 @@ YYLTYPE yylloc; ;} break; - case 1495: + case 1494: #line 39 "third_party/libpg_query/grammar/statements/variable_reset.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -30757,12 +30757,12 @@ YYLTYPE yylloc; ;} break; - case 1496: + case 1495: #line 48 "third_party/libpg_query/grammar/statements/variable_reset.y" { (yyval.vsetstmt) = (yyvsp[(1) - (1)].vsetstmt); ;} break; - case 1497: + case 1496: #line 50 "third_party/libpg_query/grammar/statements/variable_reset.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -30772,7 +30772,7 @@ YYLTYPE yylloc; ;} break; - case 1498: + case 1497: #line 57 "third_party/libpg_query/grammar/statements/variable_reset.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -30782,7 +30782,7 @@ YYLTYPE yylloc; ;} break; - case 1499: + case 1498: #line 3 "third_party/libpg_query/grammar/statements/variable_show.y" { PGVariableShowSelectStmt *n = makeNode(PGVariableShowSelectStmt); @@ -30793,7 +30793,7 @@ YYLTYPE yylloc; ;} break; - case 1500: + case 1499: #line 10 "third_party/libpg_query/grammar/statements/variable_show.y" { PGVariableShowSelectStmt *n = makeNode(PGVariableShowSelectStmt); @@ -30804,7 +30804,7 @@ YYLTYPE yylloc; ;} break; - case 1501: + case 1500: #line 18 "third_party/libpg_query/grammar/statements/variable_show.y" { PGVariableShowStmt *n = makeNode(PGVariableShowStmt); @@ -30814,7 +30814,7 @@ YYLTYPE yylloc; ;} break; - case 1502: + case 1501: #line 25 "third_party/libpg_query/grammar/statements/variable_show.y" { PGVariableShowStmt *n = makeNode(PGVariableShowStmt); @@ -30824,7 +30824,7 @@ YYLTYPE yylloc; ;} break; - case 1503: + case 1502: #line 32 "third_party/libpg_query/grammar/statements/variable_show.y" { PGVariableShowStmt *n = makeNode(PGVariableShowStmt); @@ -30834,7 +30834,7 @@ YYLTYPE yylloc; ;} break; - case 1504: + case 1503: #line 39 "third_party/libpg_query/grammar/statements/variable_show.y" { PGVariableShowStmt *n = makeNode(PGVariableShowStmt); @@ -30844,7 +30844,7 @@ YYLTYPE yylloc; ;} break; - case 1505: + case 1504: #line 46 "third_party/libpg_query/grammar/statements/variable_show.y" { PGVariableShowStmt *n = makeNode(PGVariableShowStmt); @@ -30854,7 +30854,7 @@ YYLTYPE yylloc; ;} break; - case 1506: + case 1505: #line 53 "third_party/libpg_query/grammar/statements/variable_show.y" { PGVariableShowStmt *n = makeNode(PGVariableShowStmt); @@ -30864,27 +30864,27 @@ YYLTYPE yylloc; ;} break; - case 1513: + case 1512: #line 67 "third_party/libpg_query/grammar/statements/variable_show.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1514: + case 1513: #line 69 "third_party/libpg_query/grammar/statements/variable_show.y" { (yyval.str) = psprintf("%s.%s", (yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].str)); ;} break; - case 1515: + case 1514: #line 72 "third_party/libpg_query/grammar/statements/variable_show.y" { (yyval.str) = psprintf("\"%s\"", (yyvsp[(1) - (1)].str)); ;} break; - case 1516: + case 1515: #line 74 "third_party/libpg_query/grammar/statements/variable_show.y" { (yyval.str) = psprintf("%s.\"%s\"", (yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].str)); ;} break; - case 1517: + case 1516: #line 7 "third_party/libpg_query/grammar/statements/call.y" { PGCallStmt *n = makeNode(PGCallStmt); @@ -30893,7 +30893,7 @@ YYLTYPE yylloc; ;} break; - case 1518: + case 1517: #line 10 "third_party/libpg_query/grammar/statements/view.y" { PGViewStmt *n = makeNode(PGViewStmt); @@ -30908,7 +30908,7 @@ YYLTYPE yylloc; ;} break; - case 1519: + case 1518: #line 23 "third_party/libpg_query/grammar/statements/view.y" { PGViewStmt *n = makeNode(PGViewStmt); @@ -30923,7 +30923,7 @@ YYLTYPE yylloc; ;} break; - case 1520: + case 1519: #line 36 "third_party/libpg_query/grammar/statements/view.y" { PGViewStmt *n = makeNode(PGViewStmt); @@ -30938,7 +30938,7 @@ YYLTYPE yylloc; ;} break; - case 1521: + case 1520: #line 49 "third_party/libpg_query/grammar/statements/view.y" { PGViewStmt *n = makeNode(PGViewStmt); @@ -30958,7 +30958,7 @@ YYLTYPE yylloc; ;} break; - case 1522: + case 1521: #line 67 "third_party/libpg_query/grammar/statements/view.y" { PGViewStmt *n = makeNode(PGViewStmt); @@ -30978,27 +30978,27 @@ YYLTYPE yylloc; ;} break; - case 1523: + case 1522: #line 87 "third_party/libpg_query/grammar/statements/view.y" { (yyval.viewcheckoption) = CASCADED_CHECK_OPTION; ;} break; - case 1524: + case 1523: #line 88 "third_party/libpg_query/grammar/statements/view.y" { (yyval.viewcheckoption) = CASCADED_CHECK_OPTION; ;} break; - case 1525: + case 1524: #line 89 "third_party/libpg_query/grammar/statements/view.y" { (yyval.viewcheckoption) = PG_LOCAL_CHECK_OPTION; ;} break; - case 1526: + case 1525: #line 90 "third_party/libpg_query/grammar/statements/view.y" { (yyval.viewcheckoption) = PG_NO_CHECK_OPTION; ;} break; - case 1527: + case 1526: #line 12 "third_party/libpg_query/grammar/statements/create_as.y" { PGCreateTableAsStmt *ctas = makeNode(PGCreateTableAsStmt); @@ -31014,7 +31014,7 @@ YYLTYPE yylloc; ;} break; - case 1528: + case 1527: #line 25 "third_party/libpg_query/grammar/statements/create_as.y" { PGCreateTableAsStmt *ctas = makeNode(PGCreateTableAsStmt); @@ -31030,7 +31030,7 @@ YYLTYPE yylloc; ;} break; - case 1529: + case 1528: #line 38 "third_party/libpg_query/grammar/statements/create_as.y" { PGCreateTableAsStmt *ctas = makeNode(PGCreateTableAsStmt); @@ -31046,22 +31046,22 @@ YYLTYPE yylloc; ;} break; - case 1530: + case 1529: #line 54 "third_party/libpg_query/grammar/statements/create_as.y" { (yyval.boolean) = true; ;} break; - case 1531: + case 1530: #line 55 "third_party/libpg_query/grammar/statements/create_as.y" { (yyval.boolean) = false; ;} break; - case 1532: + case 1531: #line 56 "third_party/libpg_query/grammar/statements/create_as.y" { (yyval.boolean) = true; ;} break; - case 1533: + case 1532: #line 62 "third_party/libpg_query/grammar/statements/create_as.y" { (yyval.into) = makeNode(PGIntoClause); diff --git a/src/duckdb/third_party/libpg_query/src_backend_parser_parser.cpp b/src/duckdb/third_party/libpg_query/src_backend_parser_parser.cpp index 072b86b7..d9f9139d 100644 --- a/src/duckdb/third_party/libpg_query/src_backend_parser_parser.cpp +++ b/src/duckdb/third_party/libpg_query/src_backend_parser_parser.cpp @@ -286,4 +286,4 @@ int base_yylex(YYSTYPE *lvalp, YYLTYPE *llocp, core_yyscan_t yyscanner) { return cur_token; } -} \ No newline at end of file +} diff --git a/src/duckdb/third_party/libpg_query/src_backend_parser_scansup.cpp b/src/duckdb/third_party/libpg_query/src_backend_parser_scansup.cpp index 0a33d6f9..0c5ed684 100644 --- a/src/duckdb/third_party/libpg_query/src_backend_parser_scansup.cpp +++ b/src/duckdb/third_party/libpg_query/src_backend_parser_scansup.cpp @@ -130,4 +130,4 @@ bool scanner_isspace(char ch) { return true; return false; } -} \ No newline at end of file +} diff --git a/src/duckdb/third_party/libpg_query/src_common_keywords.cpp b/src/duckdb/third_party/libpg_query/src_common_keywords.cpp index 58378409..1549a5d1 100644 --- a/src/duckdb/third_party/libpg_query/src_common_keywords.cpp +++ b/src/duckdb/third_party/libpg_query/src_common_keywords.cpp @@ -90,4 +90,4 @@ const PGScanKeyword *ScanKeywordLookup(const char *text, const PGScanKeyword *ke return NULL; } -} \ No newline at end of file +} diff --git a/src/duckdb/third_party/lz4/lz4.cpp b/src/duckdb/third_party/lz4/lz4.cpp index b6237ae9..3d11bfca 100644 --- a/src/duckdb/third_party/lz4/lz4.cpp +++ b/src/duckdb/third_party/lz4/lz4.cpp @@ -2602,4 +2602,4 @@ char* LZ4_slideInputBuffer (void* state) } #endif /* LZ4_COMMONDEFS_ONLY */ -} \ No newline at end of file +} diff --git a/src/duckdb/third_party/mbedtls/include/des_alt.h b/src/duckdb/third_party/mbedtls/include/des_alt.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/des_alt.h +++ b/src/duckdb/third_party/mbedtls/include/des_alt.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/mbedtls/aes_alt.h b/src/duckdb/third_party/mbedtls/include/mbedtls/aes_alt.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/mbedtls/aes_alt.h +++ b/src/duckdb/third_party/mbedtls/include/mbedtls/aes_alt.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/mbedtls/aria_alt.h b/src/duckdb/third_party/mbedtls/include/mbedtls/aria_alt.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/mbedtls/aria_alt.h +++ b/src/duckdb/third_party/mbedtls/include/mbedtls/aria_alt.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/mbedtls/asn1write.h b/src/duckdb/third_party/mbedtls/include/mbedtls/asn1write.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/mbedtls/asn1write.h +++ b/src/duckdb/third_party/mbedtls/include/mbedtls/asn1write.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/mbedtls/camellia_alt.h b/src/duckdb/third_party/mbedtls/include/mbedtls/camellia_alt.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/mbedtls/camellia_alt.h +++ b/src/duckdb/third_party/mbedtls/include/mbedtls/camellia_alt.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/mbedtls/ccm_alt.h b/src/duckdb/third_party/mbedtls/include/mbedtls/ccm_alt.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/mbedtls/ccm_alt.h +++ b/src/duckdb/third_party/mbedtls/include/mbedtls/ccm_alt.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/mbedtls/chacha20.h b/src/duckdb/third_party/mbedtls/include/mbedtls/chacha20.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/mbedtls/chacha20.h +++ b/src/duckdb/third_party/mbedtls/include/mbedtls/chacha20.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/mbedtls/chachapoly.h b/src/duckdb/third_party/mbedtls/include/mbedtls/chachapoly.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/mbedtls/chachapoly.h +++ b/src/duckdb/third_party/mbedtls/include/mbedtls/chachapoly.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/mbedtls/cmac.h b/src/duckdb/third_party/mbedtls/include/mbedtls/cmac.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/mbedtls/cmac.h +++ b/src/duckdb/third_party/mbedtls/include/mbedtls/cmac.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/mbedtls/config_psa.h b/src/duckdb/third_party/mbedtls/include/mbedtls/config_psa.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/mbedtls/config_psa.h +++ b/src/duckdb/third_party/mbedtls/include/mbedtls/config_psa.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/mbedtls/ecdsa.h b/src/duckdb/third_party/mbedtls/include/mbedtls/ecdsa.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/mbedtls/ecdsa.h +++ b/src/duckdb/third_party/mbedtls/include/mbedtls/ecdsa.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/mbedtls/ecp.h b/src/duckdb/third_party/mbedtls/include/mbedtls/ecp.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/mbedtls/ecp.h +++ b/src/duckdb/third_party/mbedtls/include/mbedtls/ecp.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/mbedtls/gcm_alt.h b/src/duckdb/third_party/mbedtls/include/mbedtls/gcm_alt.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/mbedtls/gcm_alt.h +++ b/src/duckdb/third_party/mbedtls/include/mbedtls/gcm_alt.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/mbedtls/md5.h b/src/duckdb/third_party/mbedtls/include/mbedtls/md5.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/mbedtls/md5.h +++ b/src/duckdb/third_party/mbedtls/include/mbedtls/md5.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/mbedtls/nist_kw.h b/src/duckdb/third_party/mbedtls/include/mbedtls/nist_kw.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/mbedtls/nist_kw.h +++ b/src/duckdb/third_party/mbedtls/include/mbedtls/nist_kw.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/mbedtls/pkcs12.h b/src/duckdb/third_party/mbedtls/include/mbedtls/pkcs12.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/mbedtls/pkcs12.h +++ b/src/duckdb/third_party/mbedtls/include/mbedtls/pkcs12.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/mbedtls/pkcs5.h b/src/duckdb/third_party/mbedtls/include/mbedtls/pkcs5.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/mbedtls/pkcs5.h +++ b/src/duckdb/third_party/mbedtls/include/mbedtls/pkcs5.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/mbedtls/psa_util.h b/src/duckdb/third_party/mbedtls/include/mbedtls/psa_util.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/mbedtls/psa_util.h +++ b/src/duckdb/third_party/mbedtls/include/mbedtls/psa_util.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/mbedtls/ripemd160.h b/src/duckdb/third_party/mbedtls/include/mbedtls/ripemd160.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/mbedtls/ripemd160.h +++ b/src/duckdb/third_party/mbedtls/include/mbedtls/ripemd160.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/mbedtls/threading.h b/src/duckdb/third_party/mbedtls/include/mbedtls/threading.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/mbedtls/threading.h +++ b/src/duckdb/third_party/mbedtls/include/mbedtls/threading.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/mbedtls/timing.h b/src/duckdb/third_party/mbedtls/include/mbedtls/timing.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/mbedtls/timing.h +++ b/src/duckdb/third_party/mbedtls/include/mbedtls/timing.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/platform_alt.h b/src/duckdb/third_party/mbedtls/include/platform_alt.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/platform_alt.h +++ b/src/duckdb/third_party/mbedtls/include/platform_alt.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/psa/crypto.h b/src/duckdb/third_party/mbedtls/include/psa/crypto.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/psa/crypto.h +++ b/src/duckdb/third_party/mbedtls/include/psa/crypto.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/rsa_alt.h b/src/duckdb/third_party/mbedtls/include/rsa_alt.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/rsa_alt.h +++ b/src/duckdb/third_party/mbedtls/include/rsa_alt.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/sha1_alt.h b/src/duckdb/third_party/mbedtls/include/sha1_alt.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/sha1_alt.h +++ b/src/duckdb/third_party/mbedtls/include/sha1_alt.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/sha256_alt.h b/src/duckdb/third_party/mbedtls/include/sha256_alt.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/sha256_alt.h +++ b/src/duckdb/third_party/mbedtls/include/sha256_alt.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/sha512_alt.h b/src/duckdb/third_party/mbedtls/include/sha512_alt.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/sha512_alt.h +++ b/src/duckdb/third_party/mbedtls/include/sha512_alt.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/include/ssl_misc.h b/src/duckdb/third_party/mbedtls/include/ssl_misc.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/include/ssl_misc.h +++ b/src/duckdb/third_party/mbedtls/include/ssl_misc.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/library/aesni.h b/src/duckdb/third_party/mbedtls/library/aesni.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/library/aesni.h +++ b/src/duckdb/third_party/mbedtls/library/aesni.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/mbedtls/library/padlock.h b/src/duckdb/third_party/mbedtls/library/padlock.h index bfed62c2..6b63dc03 100644 --- a/src/duckdb/third_party/mbedtls/library/padlock.h +++ b/src/duckdb/third_party/mbedtls/library/padlock.h @@ -1 +1 @@ -// dummy file to make amalgamantion happy \ No newline at end of file +// dummy file to make amalgamantion happy diff --git a/src/duckdb/third_party/miniz/miniz.cpp b/src/duckdb/third_party/miniz/miniz.cpp index ac28284c..387573c0 100644 --- a/src/duckdb/third_party/miniz/miniz.cpp +++ b/src/duckdb/third_party/miniz/miniz.cpp @@ -7541,4 +7541,4 @@ mz_bool mz_zip_end(mz_zip_archive *pZip) #endif /*#ifndef MINIZ_NO_ARCHIVE_APIS*/ -} // namespace duckdb_miniz \ No newline at end of file +} // namespace duckdb_miniz diff --git a/src/duckdb/third_party/parquet/parquet_types.cpp b/src/duckdb/third_party/parquet/parquet_types.cpp index e6eeb774..746965f8 100644 --- a/src/duckdb/third_party/parquet/parquet_types.cpp +++ b/src/duckdb/third_party/parquet/parquet_types.cpp @@ -6684,4 +6684,4 @@ void FileCryptoMetaData::printTo(std::ostream& out) const { } -}} // namespace \ No newline at end of file +}} // namespace diff --git a/src/duckdb/third_party/parquet/windows_compatibility.h b/src/duckdb/third_party/parquet/windows_compatibility.h index 6cbe6009..89beede9 100644 --- a/src/duckdb/third_party/parquet/windows_compatibility.h +++ b/src/duckdb/third_party/parquet/windows_compatibility.h @@ -6,4 +6,4 @@ #undef Realloc #undef min #undef max -#endif \ No newline at end of file +#endif diff --git a/src/duckdb/third_party/pcg/pcg_extras.hpp b/src/duckdb/third_party/pcg/pcg_extras.hpp index 66b31d5b..27c3ed5e 100644 --- a/src/duckdb/third_party/pcg/pcg_extras.hpp +++ b/src/duckdb/third_party/pcg/pcg_extras.hpp @@ -661,4 +661,4 @@ std::ostream& operator<<(std::ostream& out, printable_typename) { } // namespace pcg_extras -#endif // PCG_EXTRAS_HPP_INCLUDED \ No newline at end of file +#endif // PCG_EXTRAS_HPP_INCLUDED diff --git a/src/duckdb/third_party/pcg/pcg_uint128.hpp b/src/duckdb/third_party/pcg/pcg_uint128.hpp index a29f77cb..faf10023 100644 --- a/src/duckdb/third_party/pcg/pcg_uint128.hpp +++ b/src/duckdb/third_party/pcg/pcg_uint128.hpp @@ -881,4 +881,4 @@ uint_x4 operator>>(const uint_x4& v, } // namespace pcg_extras -#endif // PCG_UINT128_HPP_INCLUDED \ No newline at end of file +#endif // PCG_UINT128_HPP_INCLUDED diff --git a/src/duckdb/third_party/skiplist/Node.h b/src/duckdb/third_party/skiplist/Node.h index 93d49504..28a0aed8 100644 --- a/src/duckdb/third_party/skiplist/Node.h +++ b/src/duckdb/third_party/skiplist/Node.h @@ -488,8 +488,8 @@ Node *Node::remove(size_t call_level, } /* - * This checks the internal concistency of a Node. It returns 0 - * if succesful, non-zero on error. The tests are: + * This checks the internal consistency of a Node. It returns 0 + * if successful, non-zero on error. The tests are: * * - Height must be >= 1 * - Height must not exceed HeadNode height. @@ -497,8 +497,8 @@ Node *Node::remove(size_t call_level, * - Node pointers must not be self-referential. */ /** - * This checks the internal concistency of a Node. It returns 0 - * if succesful, non-zero on error. The tests are: + * This checks the internal consistency of a Node. It returns 0 + * if successful, non-zero on error. The tests are: * * - Height must be >= 1 * - Height must not exceed HeadNode height. diff --git a/src/duckdb/third_party/snappy/snappy.cc b/src/duckdb/third_party/snappy/snappy.cc index 23b83081..f3ebe066 100644 --- a/src/duckdb/third_party/snappy/snappy.cc +++ b/src/duckdb/third_party/snappy/snappy.cc @@ -4285,4 +4285,4 @@ bool Uncompress(Source* compressed, Sink* uncompressed) { } // namespace duckdb_snappy -#endif // #if SNAPPY_NEW_VERSION # else \ No newline at end of file +#endif // #if SNAPPY_NEW_VERSION # else diff --git a/src/duckdb/third_party/snappy/snappy_version.hpp b/src/duckdb/third_party/snappy/snappy_version.hpp index be97e820..ef8b48b3 100644 --- a/src/duckdb/third_party/snappy/snappy_version.hpp +++ b/src/duckdb/third_party/snappy/snappy_version.hpp @@ -8,4 +8,4 @@ #else #define SNAPPY_NEW_VERSION false #endif -#endif \ No newline at end of file +#endif diff --git a/src/duckdb/third_party/thrift/thrift/thrift-config.h b/src/duckdb/third_party/thrift/thrift/thrift-config.h index e4761f8d..33fdfd39 100644 --- a/src/duckdb/third_party/thrift/thrift/thrift-config.h +++ b/src/duckdb/third_party/thrift/thrift/thrift-config.h @@ -31,4 +31,4 @@ #define ARITHMETIC_RIGHT_SHIFT 1 #endif -#endif \ No newline at end of file +#endif diff --git a/src/duckdb/third_party/zstd/decompress/zstd_decompress_block.cpp b/src/duckdb/third_party/zstd/decompress/zstd_decompress_block.cpp index f7574918..e86f19ce 100644 --- a/src/duckdb/third_party/zstd/decompress/zstd_decompress_block.cpp +++ b/src/duckdb/third_party/zstd/decompress/zstd_decompress_block.cpp @@ -1415,4 +1415,4 @@ size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, return dSize; } -} \ No newline at end of file +} diff --git a/src/duckdb/third_party/zstd/include/zstd_static.h b/src/duckdb/third_party/zstd/include/zstd_static.h index e4f1f3b0..2c31f3d3 100644 --- a/src/duckdb/third_party/zstd/include/zstd_static.h +++ b/src/duckdb/third_party/zstd/include/zstd_static.h @@ -221,7 +221,7 @@ ZSTDLIB_API unsigned long long ZSTD_findDecompressedSize(const void* src, size_t * `srcSize` must be the _exact_ size of this series * (i.e. there should be a frame boundary at `src + srcSize`) * @return : - upper-bound for the decompressed size of all data in all successive frames - * - if an error occured: ZSTD_CONTENTSIZE_ERROR + * - if an error occurred: ZSTD_CONTENTSIZE_ERROR * * note 1 : an error can occur if `src` contains an invalid or incorrectly formatted frame. * note 2 : the upper-bound is exact when the decompressed size field is available in every ZSTD encoded frame of `src`. diff --git a/src/duckdb/ub_src_execution_index_art.cpp b/src/duckdb/ub_src_execution_index_art.cpp index 503c9e38..2f700eb0 100644 --- a/src/duckdb/ub_src_execution_index_art.cpp +++ b/src/duckdb/ub_src_execution_index_art.cpp @@ -20,3 +20,5 @@ #include "src/execution/index/art/art.cpp" +#include "src/execution/index/art/plan_art.cpp" + diff --git a/src/duckdb/ub_src_parser_parsed_data.cpp b/src/duckdb/ub_src_parser_parsed_data.cpp index 47459ee1..bf80fff4 100644 --- a/src/duckdb/ub_src_parser_parsed_data.cpp +++ b/src/duckdb/ub_src_parser_parsed_data.cpp @@ -46,6 +46,8 @@ #include "src/parser/parsed_data/drop_info.cpp" +#include "src/parser/parsed_data/exported_table_data.cpp" + #include "src/parser/parsed_data/extra_drop_info.cpp" #include "src/parser/parsed_data/load_info.cpp" diff --git a/src/duckdb/ub_src_planner_operator.cpp b/src/duckdb/ub_src_planner_operator.cpp index 0ec5e67d..88b3bc63 100644 --- a/src/duckdb/ub_src_planner_operator.cpp +++ b/src/duckdb/ub_src_planner_operator.cpp @@ -32,6 +32,8 @@ #include "src/planner/operator/logical_empty_result.cpp" +#include "src/planner/operator/logical_export.cpp" + #include "src/planner/operator/logical_expression_get.cpp" #include "src/planner/operator/logical_extension_operator.cpp"